Made the code valid for a C++ compiler (void* stuff), plus some cleanup
[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    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9    
10    - Redistributions of source code must retain the above copyright
11    notice, this list of conditions and the following disclaimer.
12    
13    - Redistributions in binary form must reproduce the above copyright
14    notice, this list of conditions and the following disclaimer in the
15    documentation and/or other materials provided with the distribution.
16    
17    - Neither the name of the Xiph.org Foundation nor the names of its
18    contributors may be used to endorse or promote products derived from
19    this software without specific prior written permission.
20    
21    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
25    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33 */
34
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include "modes.h"
38 #include "ltp.h"
39 #include "quant_lsp.h"
40 #include "cb_search.h"
41 #include "sb_celp.h"
42 #include "nb_celp.h"
43
44 SpeexMode *speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode};
45
46 /* Extern declarations for all codebooks we use here */
47 extern float gain_cdbk_nb[];
48 extern float gain_cdbk_lbr[];
49 extern float hexc_table[];
50 extern float exc_5_256_table[];
51 extern float exc_5_64_table[];
52 extern float exc_8_128_table[];
53 extern float exc_10_32_table[];
54 extern float exc_10_16_table[];
55 extern float hexc_10_32_table[];
56
57 static void nb_mode_query(void *mode, int request, void *ptr);
58 static void wb_mode_query(void *mode, int request, void *ptr);
59
60 /* Parameters for Long-Term Prediction (LTP)*/
61 static ltp_params ltp_params_nb = {
62    gain_cdbk_nb,
63    7,
64    7
65 };
66
67 /* Parameters for Long-Term Prediction (LTP)*/
68 static ltp_params ltp_params_vlbr = {
69    gain_cdbk_lbr,
70    5,
71    0
72 };
73
74 /* Parameters for Long-Term Prediction (LTP)*/
75 static ltp_params ltp_params_lbr = {
76    gain_cdbk_lbr,
77    5,
78    7
79 };
80
81 /* Parameters for Long-Term Prediction (LTP)*/
82 static ltp_params ltp_params_med = {
83    gain_cdbk_lbr,
84    5,
85    7
86 };
87
88 /* Split-VQ innovation parameters for very low bit-rate narrowband */
89 static split_cb_params split_cb_nb_vlbr = {
90    10,               /*subvect_size*/
91    4,               /*nb_subvect*/
92    exc_10_16_table, /*shape_cb*/
93    4,               /*shape_bits*/
94    0,
95 };
96
97 /* Split-VQ innovation parameters for low bit-rate narrowband */
98 static split_cb_params split_cb_nb_lbr = {
99    10,              /*subvect_size*/
100    4,               /*nb_subvect*/
101    exc_10_32_table, /*shape_cb*/
102    5,               /*shape_bits*/
103    0,
104 };
105
106
107 /* Split-VQ innovation parameters narrowband */
108 static split_cb_params split_cb_nb = {
109    5,               /*subvect_size*/
110    8,               /*nb_subvect*/
111    exc_5_64_table, /*shape_cb*/
112    6,               /*shape_bits*/
113    0,
114 };
115
116 /* Split-VQ innovation parameters narrowband */
117 static split_cb_params split_cb_nb_med = {
118    8,               /*subvect_size*/
119    5,               /*nb_subvect*/
120    exc_8_128_table, /*shape_cb*/
121    7,               /*shape_bits*/
122    0,
123 };
124
125 /* Split-VQ innovation for low-band wideband */
126 static split_cb_params split_cb_sb = {
127    5,               /*subvect_size*/
128    8,              /*nb_subvect*/
129    exc_5_256_table,    /*shape_cb*/
130    8,               /*shape_bits*/
131    0,
132 };
133
134 /* Split-VQ innovation for high-band wideband */
135 static split_cb_params split_cb_high = {
136    8,               /*subvect_size*/
137    5,               /*nb_subvect*/
138    hexc_table,       /*shape_cb*/
139    7,               /*shape_bits*/
140    1,
141 };
142
143
144 /* Split-VQ innovation for high-band wideband */
145 static split_cb_params split_cb_high_lbr = {
146    10,               /*subvect_size*/
147    4,               /*nb_subvect*/
148    hexc_10_32_table,       /*shape_cb*/
149    5,               /*shape_bits*/
150    0,
151 };
152
153 /* 2150 bps "vocoder-like" mode for comfort noise */
154 static SpeexSubmode nb_submode1 = {
155    0,
156    1,
157    1,
158    0,
159    /* LSP quantization */
160    lsp_quant_lbr,
161    lsp_unquant_lbr,
162    /* No pitch quantization */
163    forced_pitch_quant,
164    forced_pitch_unquant,
165    NULL,
166    /* No innovation quantization (noise only) */
167    noise_codebook_quant,
168    noise_codebook_unquant,
169    NULL,
170    0, 0, -1,
171    43
172 };
173
174 /* 5.95 kbps very low bit-rate mode */
175 static SpeexSubmode nb_submode2 = {
176    0,
177    0,
178    0,
179    0,
180    /*LSP quantization*/
181    lsp_quant_lbr,
182    lsp_unquant_lbr,
183    /*No pitch quantization*/
184    pitch_search_3tap,
185    pitch_unquant_3tap,
186    &ltp_params_vlbr,
187    /*Innovation quantization*/
188    split_cb_search_shape_sign,
189    split_cb_shape_sign_unquant,
190    &split_cb_nb_vlbr,
191
192    0.75, 0.6, .6,
193    119
194 };
195
196 /* 8 kbps low bit-rate mode */
197 static SpeexSubmode nb_submode3 = {
198    -1,
199    0,
200    1,
201    0,
202    /*LSP quantization*/
203    lsp_quant_lbr,
204    lsp_unquant_lbr,
205    /*Pitch quantization*/
206    pitch_search_3tap,
207    pitch_unquant_3tap,
208    &ltp_params_lbr,
209    /*Innovation quantization*/
210    split_cb_search_shape_sign,
211    split_cb_shape_sign_unquant,
212    &split_cb_nb_lbr,
213
214    0.75, 0.6, .5,
215    160
216 };
217
218 /* 11 kbps medium bit-rate mode */
219 static SpeexSubmode nb_submode4 = {
220    -1,
221    0,
222    1,
223    0,
224    /*LSP quantization*/
225    lsp_quant_lbr,
226    lsp_unquant_lbr,
227    /*Pitch quantization*/
228    pitch_search_3tap,
229    pitch_unquant_3tap,
230    &ltp_params_med,
231    /*Innovation quantization*/
232    split_cb_search_shape_sign,
233    split_cb_shape_sign_unquant,
234    &split_cb_nb_med,
235
236    0.72, 0.65, .3,
237    220
238 };
239
240 /* 15 kbps high bit-rate mode */
241 static SpeexSubmode nb_submode5 = {
242    -1,
243    0,
244    3,
245    0,
246    /*LSP quantization*/
247    lsp_quant_nb,
248    lsp_unquant_nb,
249    /*Pitch quantization*/
250    pitch_search_3tap,
251    pitch_unquant_3tap,
252    &ltp_params_nb,
253    /*Innovation quantization*/
254    split_cb_search_shape_sign,
255    split_cb_shape_sign_unquant,
256    &split_cb_nb,
257
258    0.7, 0.65, .2,
259    300
260 };
261
262 /* 18.2 high bit-rate mode */
263 static SpeexSubmode nb_submode6 = {
264    -1,
265    0,
266    3,
267    0,
268    /*LSP quantization*/
269    lsp_quant_nb,
270    lsp_unquant_nb,
271    /*Pitch quantization*/
272    pitch_search_3tap,
273    pitch_unquant_3tap,
274    &ltp_params_nb,
275    /*Innovation quantization*/
276    split_cb_search_shape_sign,
277    split_cb_shape_sign_unquant,
278    &split_cb_sb,
279
280    0.68, 0.65, .1,
281    364
282 };
283
284 /* 24.6 kbps high bit-rate mode */
285 static SpeexSubmode nb_submode7 = {
286    -1,
287    0,
288    3,
289    1,
290    /*LSP quantization*/
291    lsp_quant_nb,
292    lsp_unquant_nb,
293    /*Pitch quantization*/
294    pitch_search_3tap,
295    pitch_unquant_3tap,
296    &ltp_params_nb,
297    /*Innovation quantization*/
298    split_cb_search_shape_sign,
299    split_cb_shape_sign_unquant,
300    &split_cb_nb,
301
302    0.65, 0.65, 0,
303    492
304 };
305
306
307 /* Default mode for narrowband */
308 static SpeexNBMode nb_mode = {
309    160,    /*frameSize*/
310    40,     /*subframeSize*/
311    10,     /*lpcSize*/
312    640,    /*bufSize*/
313    17,     /*pitchStart*/
314    144,    /*pitchEnd*/
315    0.9,    /*gamma1*/
316    0.6,    /*gamma2*/
317    .01,   /*lag_factor*/
318    1.0001, /*lpc_floor*/
319    0.0,    /*preemph*/
320    {NULL, &nb_submode1, &nb_submode2, &nb_submode3, &nb_submode4, &nb_submode5, &nb_submode6, &nb_submode7,
321    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
322    5
323 };
324
325
326 SpeexMode speex_nb_mode = {
327    &nb_mode,
328    nb_mode_query,
329    "narrowband",
330    0,
331    4,
332    &nb_encoder_init,
333    &nb_encoder_destroy,
334    &nb_encode,
335    &nb_decoder_init,
336    &nb_decoder_destroy,
337    &nb_decode,
338    &nb_encoder_ctl,
339    &nb_decoder_ctl,
340 };
341
342 static SpeexSubmode wb_submode1 = {
343    0,
344    0,
345    1,
346    0,
347    /*LSP quantization*/
348    lsp_quant_high,
349    lsp_unquant_high,
350    /*Pitch quantization*/
351    NULL,
352    NULL,
353    NULL,
354    /*No innovation quantization*/
355    NULL,
356    NULL,
357    NULL,
358
359    0, 0, -1,
360    36
361 };
362
363
364 static SpeexSubmode wb_submode2 = {
365    0,
366    0,
367    1,
368    0,
369    /*LSP quantization*/
370    lsp_quant_high,
371    lsp_unquant_high,
372    /*Pitch quantization*/
373    NULL,
374    NULL,
375    NULL,
376    /*Innovation quantization*/
377    split_cb_search_shape_sign,
378    split_cb_shape_sign_unquant,
379    &split_cb_high_lbr,
380
381    0, 0, -1,
382    112
383 };
384
385
386 static SpeexSubmode wb_submode3 = {
387    0,
388    0,
389    1,
390    0,
391    /*LSP quantization*/
392    lsp_quant_high,
393    lsp_unquant_high,
394    /*Pitch quantization*/
395    NULL,
396    NULL,
397    NULL,
398    /*Innovation quantization*/
399    split_cb_search_shape_sign,
400    split_cb_shape_sign_unquant,
401    &split_cb_high,
402
403    0, 0, -1,
404    192
405 };
406
407 static SpeexSubmode wb_submode4 = {
408    0,
409    0,
410    1,
411    1,
412    /*LSP quantization*/
413    lsp_quant_high,
414    lsp_unquant_high,
415    /*Pitch quantization*/
416    NULL,
417    NULL,
418    NULL,
419    /*Innovation quantization*/
420    split_cb_search_shape_sign,
421    split_cb_shape_sign_unquant,
422    &split_cb_high,
423
424    0, 0, -1,
425    352
426 };
427
428
429 /* Split-band wideband CELP mode*/
430 static SpeexSBMode sb_wb_mode = {
431    &speex_nb_mode,
432    160,    /*frameSize*/
433    40,     /*subframeSize*/
434    8,     /*lpcSize*/
435    640,    /*bufSize*/
436    .9,    /*gamma1*/
437    0.6,    /*gamma2*/
438    .002,   /*lag_factor*/
439    1.0001, /*lpc_floor*/
440    0.0,    /*preemph*/
441    {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL},
442    3
443 };
444
445
446 SpeexMode speex_wb_mode = {
447    &sb_wb_mode,
448    wb_mode_query,
449    "full-rate wideband (sub-band CELP)",
450    1,
451    4,
452    &sb_encoder_init,
453    &sb_encoder_destroy,
454    &sb_encode,
455    &sb_decoder_init,
456    &sb_decoder_destroy,
457    &sb_decode,
458    &sb_encoder_ctl,
459    &sb_decoder_ctl,
460 };
461
462
463
464 void *speex_encoder_init(SpeexMode *mode)
465 {
466    return mode->enc_init(mode);
467 }
468
469 void *speex_decoder_init(SpeexMode *mode)
470 {
471    return mode->dec_init(mode);
472 }
473
474 void speex_encoder_destroy(void *state)
475 {
476    (*((SpeexMode**)state))->enc_destroy(state);
477 }
478
479 void speex_encode(void *state, float *in, SpeexBits *bits)
480 {
481    (*((SpeexMode**)state))->enc(state, in, bits);
482 }
483
484 void speex_decoder_destroy(void *state)
485 {
486    (*((SpeexMode**)state))->dec_destroy(state);
487 }
488
489 int speex_decode(void *state, SpeexBits *bits, float *out)
490 {
491    return (*((SpeexMode**)state))->dec(state, bits, out);
492 }
493
494
495 void speex_encoder_ctl(void *state, int request, void *ptr)
496 {
497    (*((SpeexMode**)state))->enc_ctl(state, request, ptr);
498 }
499
500 void speex_decoder_ctl(void *state, int request, void *ptr)
501 {
502    (*((SpeexMode**)state))->dec_ctl(state, request, ptr);
503 }
504
505
506
507 static void nb_mode_query(void *mode, int request, void *ptr)
508 {
509    SpeexNBMode *m = (SpeexNBMode*)mode;
510    
511    switch (request)
512    {
513    case SPEEX_MODE_FRAME_SIZE:
514       *((int*)ptr)=m->frameSize;
515       break;
516    case SPEEX_SUBMODE_BITS_PER_FRAME:
517       *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
518       break;
519    default:
520       fprintf(stderr, "Unknown wb_mode_query request: %d\n", request);
521    }
522
523 }
524
525 static void wb_mode_query(void *mode, int request, void *ptr)
526 {
527    SpeexSBMode *m = (SpeexSBMode*)mode;
528
529    switch (request)
530    {
531    case SPEEX_MODE_FRAME_SIZE:
532       *((int*)ptr)=m->frameSize;
533       break;
534    case SPEEX_SUBMODE_BITS_PER_FRAME:
535       *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
536       break;
537    default:
538       fprintf(stderr, "Unknown wb_mode_query request: %d\n", request);
539    }
540 }
541
542
543 void speex_mode_query(SpeexMode *mode, int request, void *ptr)
544 {
545    mode->query(mode->mode, request, ptr);
546 }