a7a961e1809306297c2ec3685cd5022a9bab16fe
[speexdsp.git] / libspeex / modes.c
1 /* Copyright (C) 2002 Jean-Marc Valin 
2    File: modes.c
3
4    Describes the different modes of the codec
5
6    This library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10    
11    This library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15    
16    You should have received a copy of the GNU Lesser General Public
17    License along with this library; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20 */
21
22 #include <stdlib.h>
23 #include "modes.h"
24 #include "ltp.h"
25 #include "quant_lsp.h"
26 #include "cb_search.h"
27 #include "sb_celp.h"
28 #include "nb_celp.h"
29
30 SpeexMode *speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode};
31
32 /* Extern declarations for all codebooks we use here */
33 extern float gain_cdbk_nb[];
34 extern float gain_cdbk_lbr[];
35 extern float hexc_table[];
36 extern float exc_5_256_table[];
37 extern float exc_5_64_table[];
38 extern float exc_8_128_table[];
39 extern float exc_8_32_table[];
40 extern float exc_10_32_table[];
41 extern float exc_10_16_table[];
42 extern float hexc_10_32_table[];
43
44 /* Parameters for Long-Term Prediction (LTP)*/
45 static ltp_params ltp_params_nb = {
46    gain_cdbk_nb,
47    7,
48    7
49 };
50
51 /* Parameters for Long-Term Prediction (LTP)*/
52 static ltp_params ltp_params_vlbr = {
53    gain_cdbk_lbr,
54    5,
55    0
56 };
57
58 /* Parameters for Long-Term Prediction (LTP)*/
59 static ltp_params ltp_params_lbr = {
60    gain_cdbk_lbr,
61    5,
62    7
63 };
64
65 /* Parameters for Long-Term Prediction (LTP)*/
66 static ltp_params ltp_params_med = {
67    gain_cdbk_lbr,
68    5,
69    7
70 };
71
72 /* Split-VQ innovation parameters for very low bit-rate narrowband */
73 static split_cb_params split_cb_nb_vlbr = {
74    10,               /*subvect_size*/
75    4,               /*nb_subvect*/
76    exc_10_16_table, /*shape_cb*/
77    4,               /*shape_bits*/
78 };
79
80 /* Split-VQ innovation parameters for low bit-rate narrowband */
81 static split_cb_params split_cb_nb_lbr = {
82    10,              /*subvect_size*/
83    4,               /*nb_subvect*/
84    exc_10_32_table, /*shape_cb*/
85    5,               /*shape_bits*/
86 };
87
88
89 /* Split-VQ innovation parameters narrowband */
90 static split_cb_params split_cb_nb = {
91    5,               /*subvect_size*/
92    8,               /*nb_subvect*/
93    exc_5_64_table, /*shape_cb*/
94    6,               /*shape_bits*/
95 };
96
97 /* Split-VQ innovation parameters narrowband */
98 static split_cb_params split_cb_nb_med = {
99    8,               /*subvect_size*/
100    5,               /*nb_subvect*/
101    exc_8_128_table, /*shape_cb*/
102    7,               /*shape_bits*/
103 };
104
105 /* Split-VQ innovation for low-band wideband */
106 static split_cb_params split_cb_sb = {
107    5,               /*subvect_size*/
108    8,              /*nb_subvect*/
109    exc_5_256_table,    /*shape_cb*/
110    8,               /*shape_bits*/
111 };
112
113 /* Split-VQ innovation for high-band wideband */
114 static split_cb_params split_cb_high = {
115    8,               /*subvect_size*/
116    5,               /*nb_subvect*/
117    hexc_table,       /*shape_cb*/
118    7,               /*shape_bits*/
119 };
120
121
122 /* Split-VQ innovation for high-band wideband */
123 static split_cb_params split_cb_high_lbr = {
124    10,               /*subvect_size*/
125    4,               /*nb_subvect*/
126    hexc_10_32_table,       /*shape_cb*/
127    5,               /*shape_bits*/
128 };
129
130
131 static SpeexSubmode nb_submode1 = {
132    0,
133    1,
134    /* LSP quantization */
135    lsp_quant_lbr,
136    lsp_unquant_lbr,
137    /* No pitch quantization */
138    NULL,
139    NULL,
140    NULL,
141    /* No innovation quantization (noise only) */
142    NULL,
143    NULL,
144    NULL,
145
146    0, 0, -1,
147    43
148 };
149
150 static SpeexSubmode nb_submode2 = {
151    0,
152    0,
153    /*LSP quantization*/
154    lsp_quant_lbr,
155    lsp_unquant_lbr,
156    /*No pitch quantization*/
157    pitch_search_3tap,
158    pitch_unquant_3tap,
159    &ltp_params_vlbr,
160    /*Innovation quantization*/
161    split_cb_search_nogain,
162    split_cb_nogain_unquant,
163    &split_cb_nb_vlbr,
164
165    0.75, 0.6, .6,
166    119
167 };
168
169
170 static SpeexSubmode nb_submode3 = {
171    -1,
172    1,
173    /*LSP quantization*/
174    lsp_quant_lbr,
175    lsp_unquant_lbr,
176    /*Pitch quantization*/
177    pitch_search_3tap,
178    pitch_unquant_3tap,
179    &ltp_params_lbr,
180    /*Innovation quantization*/
181    split_cb_search_nogain,
182    split_cb_nogain_unquant,
183    &split_cb_nb_lbr,
184
185    0.75, 0.6, .5,
186    160
187 };
188
189 static SpeexSubmode nb_submode4 = {
190    -1,
191    1,
192    /*LSP quantization*/
193    lsp_quant_lbr,
194    lsp_unquant_lbr,
195    /*Pitch quantization*/
196    pitch_search_3tap,
197    pitch_unquant_3tap,
198    &ltp_params_med,
199    /*Innovation quantization*/
200    split_cb_search_nogain,
201    split_cb_nogain_unquant,
202    &split_cb_nb_med,
203
204    0.72, 0.65, .3,
205    220
206 };
207
208 static SpeexSubmode nb_submode5 = {
209    -1,
210    3,
211    /*LSP quantization*/
212    lsp_quant_nb,
213    lsp_unquant_nb,
214    /*Pitch quantization*/
215    pitch_search_3tap,
216    pitch_unquant_3tap,
217    &ltp_params_nb,
218    /*Innovation quantization*/
219    split_cb_search_nogain,
220    split_cb_nogain_unquant,
221    &split_cb_nb,
222
223    0.7, 0.65, .2,
224    300
225 };
226
227 static SpeexSubmode nb_submode6 = {
228    -1,
229    3,
230    /*LSP quantization*/
231    lsp_quant_nb,
232    lsp_unquant_nb,
233    /*Pitch quantization*/
234    pitch_search_3tap,
235    pitch_unquant_3tap,
236    &ltp_params_nb,
237    /*Innovation quantization*/
238    split_cb_search_nogain,
239    split_cb_nogain_unquant,
240    &split_cb_sb,
241
242    0.68, 0.65, .1,
243    364
244 };
245
246
247 /* Default mode for narrowband */
248 static SpeexNBMode nb_mode = {
249    160,    /*frameSize*/
250    40,     /*subframeSize*/
251    10,     /*lpcSize*/
252    640,    /*bufSize*/
253    17,     /*pitchStart*/
254    144,    /*pitchEnd*/
255    0.9,    /*gamma1*/
256    0.6,    /*gamma2*/
257    .005,   /*lag_factor*/
258    1.0001, /*lpc_floor*/
259    0.0,    /*preemph*/
260    {NULL, &nb_submode1, &nb_submode2, &nb_submode3, &nb_submode4, &nb_submode5, &nb_submode6, NULL,
261    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
262    5
263 };
264
265
266 SpeexMode speex_nb_mode = {
267    &nb_mode,
268    "narrowband",
269    0,
270    4,
271    &nb_encoder_init,
272    &nb_encoder_destroy,
273    &nb_encode,
274    &nb_decoder_init,
275    &nb_decoder_destroy,
276    &nb_decode,
277    &nb_encoder_ctl,
278    &nb_decoder_ctl,
279    160,
280    -1,
281    0
282 };
283
284 static SpeexSubmode wb_submode1 = {
285    0,
286    1,
287    /*LSP quantization*/
288    lsp_quant_high,
289    lsp_unquant_high,
290    /*Pitch quantization*/
291    NULL,
292    NULL,
293    NULL,
294    /*No innovation quantization*/
295    NULL,
296    NULL,
297    NULL,
298
299    0, 0, -1,
300    36
301 };
302
303
304 static SpeexSubmode wb_submode2 = {
305    0,
306    1,
307    /*LSP quantization*/
308    lsp_quant_high,
309    lsp_unquant_high,
310    /*Pitch quantization*/
311    NULL,
312    NULL,
313    NULL,
314    /*Innovation quantization*/
315    split_cb_search_nogain,
316    split_cb_nogain_unquant,
317    &split_cb_high_lbr,
318
319    0, 0, -1,
320    112
321 };
322
323
324 static SpeexSubmode wb_submode3 = {
325    0,
326    1,
327    /*LSP quantization*/
328    lsp_quant_high,
329    lsp_unquant_high,
330    /*Pitch quantization*/
331    NULL,
332    NULL,
333    NULL,
334    /*Innovation quantization*/
335    split_cb_search_shape_sign,
336    split_cb_shape_sign_unquant,
337    &split_cb_high,
338
339    0, 0, -1,
340    192
341 };
342
343
344 /* Split-band wideband CELP mode*/
345 SpeexSBMode sb_wb_mode = {
346    &speex_nb_mode,
347    160,    /*frameSize*/
348    40,     /*subframeSize*/
349    8,     /*lpcSize*/
350    640,    /*bufSize*/
351    .9,    /*gamma1*/
352    0.6,    /*gamma2*/
353    .002,   /*lag_factor*/
354    1.0001, /*lpc_floor*/
355    0.0,    /*preemph*/
356    {NULL, &wb_submode1, &wb_submode2, &wb_submode3, NULL, NULL, NULL, NULL},
357    3
358 };
359
360
361 SpeexMode speex_wb_mode = {
362    &sb_wb_mode,
363    "full-rate wideband (sub-band CELP)",
364    1,
365    4,
366    &sb_encoder_init,
367    &sb_encoder_destroy,
368    &sb_encode,
369    &sb_decoder_init,
370    &sb_decoder_destroy,
371    &sb_decode,
372    &sb_encoder_ctl,
373    &sb_decoder_ctl,
374    320,
375    -1,
376    0
377 };
378
379
380
381 void *speex_encoder_init(SpeexMode *mode)
382 {
383    return mode->enc_init(mode);
384 }
385
386 void *speex_decoder_init(SpeexMode *mode)
387 {
388    return mode->dec_init(mode);
389 }
390
391 void speex_encoder_destroy(void *state)
392 {
393    (*((SpeexMode**)state))->enc_destroy(state);
394 }
395
396 void speex_encode(void *state, float *in, SpeexBits *bits)
397 {
398    (*((SpeexMode**)state))->enc(state, in, bits);
399 }
400
401 void speex_decoder_destroy(void *state)
402 {
403    (*((SpeexMode**)state))->dec_destroy(state);
404 }
405
406 void speex_decode(void *state, SpeexBits *bits, float *out, int lost)
407 {
408    (*((SpeexMode**)state))->dec(state, bits, out, lost);
409 }
410
411
412 void speex_encoder_ctl(void *state, int request, void *ptr)
413 {
414    (*((SpeexMode**)state))->enc_ctl(state, request, ptr);
415 }
416
417 void speex_decoder_ctl(void *state, int request, void *ptr)
418 {
419    (*((SpeexMode**)state))->dec_ctl(state, request, ptr);
420 }