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