added guarded #include "config.h" throughout libspeex/ and src/
[speexdsp.git] / libspeex / modes_noglobals.c
1 /* Copyright (C) 2002 Jean-Marc Valin 
2    File: modes_noglobals.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 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
38
39 #include "modes.h"
40 #include "ltp.h"
41 #include "quant_lsp.h"
42 #include "cb_search.h"
43 #include "sb_celp.h"
44 #include "nb_celp.h"
45 #include "vbr.h"
46 #include "misc.h"
47 #include <math.h>
48
49 #ifndef NULL
50 #define NULL 0
51 #endif
52
53 /* Extern declarations for all codebooks we use here */
54 extern const signed char gain_cdbk_nb[];
55 extern const signed char gain_cdbk_lbr[];
56 extern const signed char hexc_table[];
57 extern const signed char exc_5_256_table[];
58 extern const signed char exc_5_64_table[];
59 extern const signed char exc_8_128_table[];
60 extern const signed char exc_10_32_table[];
61 extern const signed char exc_10_16_table[];
62 extern const signed char exc_20_32_table[];
63 extern const signed char hexc_10_32_table[];
64
65 static const ltp_params *
66 speex_ltp_params_new (const signed char * gain_cdbk, int gain_bits,
67                       int pitch_bits)
68 {
69   ltp_params * params;
70
71   params = (ltp_params *) speex_alloc (sizeof (ltp_params));
72   if (params == NULL) return NULL;
73
74   params->gain_cdbk = gain_cdbk;
75   params->gain_bits = gain_bits;
76   params->pitch_bits = pitch_bits;
77
78   return params;
79 }
80
81 static void
82 speex_ltp_params_free (ltp_params * params)
83 {
84   speex_free (params);
85 }
86
87 static const split_cb_params *
88 speex_split_cb_params_new (int subvect_size, int nb_subvect,
89                            const signed char * shape_cb, int shape_bits,
90                            int have_sign)
91 {
92   split_cb_params * params;
93
94   params = (split_cb_params *) speex_alloc (sizeof (split_cb_params));
95   if (params == NULL) return NULL;
96
97   params->subvect_size = subvect_size;
98   params->nb_subvect = nb_subvect;
99   params->shape_cb = shape_cb;
100   params->shape_bits = shape_bits;
101   params->have_sign = have_sign;
102
103   return params;
104 }
105
106 static void
107 speex_split_cb_params_free (split_cb_params * params)
108 {
109   speex_free (params);
110 }
111
112 static SpeexSubmode *
113 speex_submode_new (int lbr_pitch, int forced_pitch_gain,
114                    int have_subframe_gain, int double_codebook,
115
116                    lsp_quant_func lsp_quant, lsp_unquant_func lsp_unquant,
117                    ltp_quant_func ltp_quant, ltp_unquant_func ltp_unquant,
118                    const void * ltp_params,
119
120                    innovation_quant_func innovation_quant,
121                    innovation_unquant_func innovation_unquant,
122                    const void * innovation_params,
123
124                    /*Synthesis filter enhancement*/
125                    spx_word16_t      lpc_enh_k1, /**< Enhancer constant */
126                    spx_word16_t      lpc_enh_k2, /**< Enhancer constant */
127                    spx_word16_t      lpc_enh_k3, /**< Enhancer constant */
128                    spx_word16_t      comb_gain,  /**< Gain of enhancer comb filter */
129                    
130                    int               bits_per_frame /**< Number of bits per frame after encoding*/
131
132                    )
133 {
134   SpeexSubmode * submode;
135
136   submode = (SpeexSubmode *) speex_alloc (sizeof (SpeexSubmode));
137   if (submode == NULL) return NULL;
138
139   submode->lbr_pitch = lbr_pitch;
140   submode->forced_pitch_gain = forced_pitch_gain;
141   submode->have_subframe_gain = have_subframe_gain;
142   submode->double_codebook = double_codebook;
143   submode->lsp_quant = lsp_quant;
144   submode->lsp_unquant = lsp_unquant;
145   submode->ltp_quant = ltp_quant;
146   submode->ltp_unquant = ltp_unquant;
147   submode->ltp_params = ltp_params;
148   submode->innovation_quant = innovation_quant;
149   submode->innovation_unquant = innovation_unquant;
150   submode->innovation_params = innovation_params;
151   submode->lpc_enh_k1 = lpc_enh_k1;
152   submode->lpc_enh_k2 = lpc_enh_k2;
153   submode->lpc_enh_k3 = lpc_enh_k3;
154   submode->comb_gain = comb_gain;
155   submode->bits_per_frame = bits_per_frame;
156
157   return submode;
158 }
159
160 static void
161 speex_submode_free (const SpeexSubmode * submode)
162 {
163   speex_free ((void *)submode);
164 }
165
166 static SpeexNBMode *
167 nb_mode_new (int frameSize, int subframeSize, int lpcSize, int bufSize,
168              int pitchStart, int pitchEnd, spx_word16_t gamma1,
169              spx_word16_t gamma2, float lag_factor, float lpc_floor,
170 #ifdef EPIC_48K
171              int lbr48k,
172 #endif
173              const SpeexSubmode * submodes[], int defaultSubmode,
174              int quality_map[])
175 {
176   SpeexNBMode * nb_mode;
177
178   nb_mode = (SpeexNBMode *) speex_alloc (sizeof (SpeexNBMode));
179   if (nb_mode == NULL) return NULL;
180
181   nb_mode->frameSize = frameSize;
182   nb_mode->subframeSize = subframeSize;
183   nb_mode->lpcSize = lpcSize;
184   nb_mode->bufSize = bufSize;
185   nb_mode->pitchStart = pitchStart;
186   nb_mode->pitchEnd = pitchEnd;
187   nb_mode->gamma1 = gamma1;
188   nb_mode->gamma2 = gamma2;
189   nb_mode->lag_factor = lag_factor;
190   nb_mode->lpc_floor = lpc_floor;
191 #ifdef EPIC_48K
192   nb_mode->lbr48k = lbr48k;
193 #endif
194   memcpy (nb_mode->submodes, submodes, sizeof (nb_mode->submodes));
195   nb_mode->defaultSubmode = defaultSubmode;
196   memcpy (nb_mode->quality_map, quality_map, sizeof (nb_mode->quality_map));
197
198   return nb_mode;
199 }
200
201 static void
202 nb_mode_free (const SpeexNBMode * nb_mode)
203 {
204   speex_free ((void *)nb_mode);
205 }
206
207 static SpeexSBMode *
208 sb_mode_new (
209    const SpeexMode *nb_mode,    /**< Embedded narrowband mode */
210    int     frameSize,     /**< Size of frames used for encoding */
211    int     subframeSize,  /**< Size of sub-frames used for encoding */
212    int     lpcSize,       /**< Order of LPC filter */
213    int     bufSize,       /**< Signal buffer size in encoder */
214    spx_word16_t gamma1,   /**< Perceptual filter parameter #1 */
215    spx_word16_t gamma2,   /**< Perceptual filter parameter #1 */
216    float   lag_factor,    /**< Lag-windowing parameter */
217    float   lpc_floor,     /**< Noise floor for LPC analysis */
218    float   folding_gain,
219
220    const SpeexSubmode *submodes[], /**< Sub-mode data for the mode */
221    int     defaultSubmode, /**< Default sub-mode to use when encoding */
222    int     low_quality_map[], /**< Mode corresponding to each quality setting */
223    int     quality_map[], /**< Mode corresponding to each quality setting */
224    const float (*vbr_thresh)[11],
225    int     nb_modes
226                    )
227 {
228   SpeexSBMode * sb_mode;
229
230   sb_mode = (SpeexSBMode *) speex_alloc (sizeof (SpeexSBMode));
231   if (sb_mode == NULL) return NULL;
232
233   sb_mode->nb_mode = nb_mode;
234   sb_mode->frameSize = frameSize;
235   sb_mode->subframeSize = subframeSize;
236   sb_mode->lpcSize = lpcSize;
237   sb_mode->bufSize = bufSize;
238   sb_mode->gamma1 = gamma1;
239   sb_mode->gamma2 = gamma2;
240   sb_mode->lag_factor = lag_factor;
241   sb_mode->lpc_floor = lpc_floor;
242   sb_mode->folding_gain = folding_gain;
243
244   memcpy (sb_mode->submodes, submodes, sizeof (sb_mode->submodes));
245   sb_mode->defaultSubmode = defaultSubmode;
246   memcpy (sb_mode->low_quality_map, low_quality_map, sizeof (sb_mode->low_quality_map));
247   memcpy (sb_mode->quality_map, quality_map, sizeof (sb_mode->quality_map));
248   sb_mode->vbr_thresh = vbr_thresh;
249   sb_mode->nb_modes = nb_modes;
250
251   return sb_mode;
252 }
253
254 static void
255 sb_mode_free (const SpeexSBMode * sb_mode)
256 {
257   int i;
258
259   for (i = 0; i < SB_SUBMODES; i++)
260     if (sb_mode->submodes[i]) speex_submode_free (sb_mode->submodes[i]);
261
262   speex_free ((void *)sb_mode);
263 }
264
265 static SpeexMode *
266 speex_mode_new (const void * b_mode, mode_query_func query, char * modeName,
267                 int modeID, int bitstream_version, encoder_init_func enc_init,
268                 encoder_destroy_func enc_destroy, encode_func enc,
269                 decoder_init_func dec_init, decoder_destroy_func dec_destroy,
270                 decode_func dec, encoder_ctl_func enc_ctl,
271                 decoder_ctl_func dec_ctl)
272 {
273   SpeexMode * mode;
274
275   mode = (SpeexMode *) speex_alloc (sizeof (SpeexMode));
276   if (mode == NULL) return NULL;
277
278   mode->mode = b_mode;
279   mode->query = query;
280   mode->modeName = modeName;
281   mode->modeID = modeID;
282   mode->bitstream_version = bitstream_version;
283   mode->enc_init = enc_init;
284   mode->enc_destroy = enc_destroy;
285   mode->enc = enc;
286   mode->dec_init = dec_init;
287   mode->dec_destroy = dec_destroy;
288   mode->dec = dec;
289   mode->enc_ctl = enc_ctl;
290   mode->dec_ctl = dec_ctl;
291
292   return mode;
293 }
294
295 /* Freeing each kind of created (SpeexMode *) is done separately below */
296
297 /* Parameters for Long-Term Prediction (LTP)*/
298 static const ltp_params * ltp_params_nb (void)
299 {
300   return speex_ltp_params_new (
301    gain_cdbk_nb,
302    7,
303    7
304    );
305 }
306
307 /* Parameters for Long-Term Prediction (LTP)*/
308 static const ltp_params * ltp_params_vlbr (void)
309 {
310   return speex_ltp_params_new (
311    gain_cdbk_lbr,
312    5,
313    0
314    );
315 }
316
317 /* Parameters for Long-Term Prediction (LTP)*/
318 static const ltp_params * ltp_params_lbr (void)
319 {
320   return speex_ltp_params_new (
321    gain_cdbk_lbr,
322    5,
323    7
324    );
325 }
326
327 /* Parameters for Long-Term Prediction (LTP)*/
328 static const ltp_params * ltp_params_med (void)
329 {
330   return speex_ltp_params_new (
331    gain_cdbk_lbr,
332    5,
333    7
334    );
335 }
336
337 /* Split-VQ innovation parameters for very low bit-rate narrowband */
338 static const split_cb_params * split_cb_nb_vlbr (void)
339 {
340   return speex_split_cb_params_new (
341    10,               /*subvect_size*/
342    4,               /*nb_subvect*/
343    exc_10_16_table, /*shape_cb*/
344    4,               /*shape_bits*/
345    0
346    );
347 }
348
349 /* Split-VQ innovation parameters for very low bit-rate narrowband */
350 static const split_cb_params * split_cb_nb_ulbr (void)
351 {
352   return speex_split_cb_params_new (
353    20,               /*subvect_size*/
354    2,               /*nb_subvect*/
355    exc_20_32_table, /*shape_cb*/
356    5,               /*shape_bits*/
357    0
358    );
359 }
360
361 /* Split-VQ innovation parameters for low bit-rate narrowband */
362 static const split_cb_params * split_cb_nb_lbr (void)
363 {
364   return speex_split_cb_params_new (
365    10,              /*subvect_size*/
366    4,               /*nb_subvect*/
367    exc_10_32_table, /*shape_cb*/
368    5,               /*shape_bits*/
369    0
370    );
371 }
372
373
374 /* Split-VQ innovation parameters narrowband */
375 static const split_cb_params * split_cb_nb (void)
376 {
377   return speex_split_cb_params_new (
378    5,               /*subvect_size*/
379    8,               /*nb_subvect*/
380    exc_5_64_table, /*shape_cb*/
381    6,               /*shape_bits*/
382    0
383    );
384 }
385
386 /* Split-VQ innovation parameters narrowband */
387 static const split_cb_params * split_cb_nb_med (void)
388 {
389   return speex_split_cb_params_new (
390    8,               /*subvect_size*/
391    5,               /*nb_subvect*/
392    exc_8_128_table, /*shape_cb*/
393    7,               /*shape_bits*/
394    0
395    );
396 }
397
398 /* Split-VQ innovation for low-band wideband */
399 static const split_cb_params * split_cb_sb (void)
400 {
401   return speex_split_cb_params_new (
402    5,               /*subvect_size*/
403    8,              /*nb_subvect*/
404    exc_5_256_table,    /*shape_cb*/
405    8,               /*shape_bits*/
406    0
407    );
408 }
409
410 /* Split-VQ innovation for high-band wideband */
411 static const split_cb_params * split_cb_high (void)
412 {
413   return speex_split_cb_params_new (
414    8,               /*subvect_size*/
415    5,               /*nb_subvect*/
416    hexc_table,       /*shape_cb*/
417    7,               /*shape_bits*/
418    1
419    );
420 }
421
422
423 /* Split-VQ innovation for high-band wideband */
424 static const split_cb_params * split_cb_high_lbr (void)
425 {
426   return speex_split_cb_params_new (
427    10,               /*subvect_size*/
428    4,               /*nb_subvect*/
429    hexc_10_32_table,       /*shape_cb*/
430    5,               /*shape_bits*/
431    0
432    );
433 }
434
435 /* 2150 bps "vocoder-like" mode for comfort noise */
436 static const SpeexSubmode * nb_submode1 (void)
437 {
438   return speex_submode_new (
439    0,
440    1,
441    0,
442    0,
443    /* LSP quantization */
444    lsp_quant_lbr,
445    lsp_unquant_lbr,
446    /* No pitch quantization */
447    forced_pitch_quant,
448    forced_pitch_unquant,
449    NULL,
450    /* No innovation quantization (noise only) */
451    noise_codebook_quant,
452    noise_codebook_unquant,
453    NULL,
454 #ifdef FIXED_POINT
455    22938, 22938, 0, -1,
456 #else
457    .7, .7, 0, -1,
458 #endif
459    43
460    );
461 }
462
463 /* 3.95 kbps very low bit-rate mode */
464 static const SpeexSubmode * nb_submode8 (void)
465 {
466   const split_cb_params * params;
467
468   params = split_cb_nb_ulbr();
469   if (params == NULL) return NULL;
470
471   return speex_submode_new (
472    0,
473    1,
474    0,
475    0,
476    /*LSP quantization*/
477    lsp_quant_lbr,
478    lsp_unquant_lbr,
479    /*No pitch quantization*/
480    forced_pitch_quant,
481    forced_pitch_unquant,
482    NULL,
483    /*Innovation quantization*/
484    split_cb_search_shape_sign,
485    split_cb_shape_sign_unquant,
486    params,
487 #ifdef FIXED_POINT
488    22938, 16384, 11796, 21299,
489 #else
490    0.7, 0.5, .36, .65,
491 #endif
492    79
493    );
494 }
495
496 /* 5.95 kbps very low bit-rate mode */
497 static const SpeexSubmode * nb_submode2 (void)
498 {
499   return speex_submode_new (
500    0,
501    0,
502    0,
503    0,
504    /*LSP quantization*/
505    lsp_quant_lbr,
506    lsp_unquant_lbr,
507    /*No pitch quantization*/
508    pitch_search_3tap,
509    pitch_unquant_3tap,
510    &ltp_params_vlbr,
511    /*Innovation quantization*/
512    split_cb_search_shape_sign,
513    split_cb_shape_sign_unquant,
514    split_cb_nb_vlbr(),
515 #ifdef FIXED_POINT
516    22938, 16384, 11796, 18022,
517 #else
518    0.7, 0.5, .36, .55,
519 #endif
520    119
521    );
522 }
523
524 /* 8 kbps low bit-rate mode */
525 static const SpeexSubmode * nb_submode3 (void)
526 {
527   return speex_submode_new (
528    -1,
529    0,
530    1,
531    0,
532    /*LSP quantization*/
533    lsp_quant_lbr,
534    lsp_unquant_lbr,
535    /*Pitch quantization*/
536    pitch_search_3tap,
537    pitch_unquant_3tap,
538    ltp_params_lbr(),
539    /*Innovation quantization*/
540    split_cb_search_shape_sign,
541    split_cb_shape_sign_unquant,
542    split_cb_nb_lbr(),
543 #ifdef FIXED_POINT
544    22938, 18022, 9830, 14746,
545 #else
546    0.7, 0.55, .30, .45,
547 #endif
548    160
549    );
550 }
551
552 /* 11 kbps medium bit-rate mode */
553 static const SpeexSubmode * nb_submode4 (void)
554 {
555   return speex_submode_new (
556    -1,
557    0,
558    1,
559    0,
560    /*LSP quantization*/
561    lsp_quant_lbr,
562    lsp_unquant_lbr,
563    /*Pitch quantization*/
564    pitch_search_3tap,
565    pitch_unquant_3tap,
566    ltp_params_med(),
567    /*Innovation quantization*/
568    split_cb_search_shape_sign,
569    split_cb_shape_sign_unquant,
570    split_cb_nb_med(),
571 #ifdef FIXED_POINT
572    22938, 20644, 5243, 11469,
573 #else
574    0.7, 0.63, .16, .35,
575 #endif
576    220
577    );
578 }
579
580 /* 15 kbps high bit-rate mode */
581 static const SpeexSubmode * nb_submode5 (void)
582 {
583   return speex_submode_new (
584    -1,
585    0,
586    3,
587    0,
588    /*LSP quantization*/
589    lsp_quant_nb,
590    lsp_unquant_nb,
591    /*Pitch quantization*/
592    pitch_search_3tap,
593    pitch_unquant_3tap,
594    ltp_params_nb(),
595    /*Innovation quantization*/
596    split_cb_search_shape_sign,
597    split_cb_shape_sign_unquant,
598    split_cb_nb(),
599 #ifdef FIXED_POINT
600    22938, 21299, 3932, 8192,
601 #else
602    0.7, 0.65, .12, .25,
603 #endif
604    300
605    );
606 }
607
608 /* 18.2 high bit-rate mode */
609 static const SpeexSubmode * nb_submode6 (void)
610 {
611   return speex_submode_new (
612    -1,
613    0,
614    3,
615    0,
616    /*LSP quantization*/
617    lsp_quant_nb,
618    lsp_unquant_nb,
619    /*Pitch quantization*/
620    pitch_search_3tap,
621    pitch_unquant_3tap,
622    ltp_params_nb(),
623    /*Innovation quantization*/
624    split_cb_search_shape_sign,
625    split_cb_shape_sign_unquant,
626    split_cb_sb(),
627 #ifdef FIXED_POINT
628    22282, 21299, 2294, 3277,
629 #else
630    0.68, 0.65, .07, .1,
631 #endif
632    364
633    );
634 }
635
636 /* 24.6 kbps high bit-rate mode */
637 static const SpeexSubmode * nb_submode7 (void)
638 {
639   return speex_submode_new (
640    -1,
641    0,
642    3,
643    1,
644    /*LSP quantization*/
645    lsp_quant_nb,
646    lsp_unquant_nb,
647    /*Pitch quantization*/
648    pitch_search_3tap,
649    pitch_unquant_3tap,
650    ltp_params_nb(),
651    /*Innovation quantization*/
652    split_cb_search_shape_sign,
653    split_cb_shape_sign_unquant,
654    split_cb_nb(),
655 #ifdef FIXED_POINT
656    21299, 21299, 0, -1,
657 #else
658    0.65, 0.65, .0, -1,
659 #endif
660    492
661    );
662 }
663
664
665 /* Default mode for narrowband */
666 static const SpeexNBMode * nb_mode (void)
667 {
668   const SpeexSubmode ** submodes;
669   int quality_map[11] = {1, 8, 2, 3, 3, 4, 4, 5, 5, 6, 7};
670   const SpeexNBMode * ret;
671
672   submodes = (const SpeexSubmode **)
673     speex_alloc (sizeof (SpeexSubmode *) * SB_SUBMODES);
674   if (submodes == NULL) return NULL;
675   memset (submodes, 0, sizeof (submodes));
676
677   if (!(submodes[1] = nb_submode1())) goto nb_1;
678   if (!(submodes[2] = nb_submode2())) goto nb_2;
679   if (!(submodes[3] = nb_submode3())) goto nb_3;
680   if (!(submodes[4] = nb_submode4())) goto nb_4;
681   if (!(submodes[5] = nb_submode5())) goto nb_5;
682   if (!(submodes[6] = nb_submode6())) goto nb_6;
683   if (!(submodes[7] = nb_submode7())) goto nb_7;
684   if (!(submodes[8] = nb_submode8())) goto nb_8;
685
686   ret = nb_mode_new (
687    160,    /*frameSize*/
688    40,     /*subframeSize*/
689    10,     /*lpcSize*/
690    640,    /*bufSize*/
691    17,     /*pitchStart*/
692    144,    /*pitchEnd*/
693 #ifdef FIXED_POINT
694    29491, 19661, /* gamma1, gamma2 */
695 #else
696    0.9, 0.6, /* gamma1, gamma2 */
697 #endif
698    .012,   /*lag_factor*/
699    1.0002, /*lpc_floor*/
700 #ifdef EPIC_48K
701    0,
702 #endif
703    submodes,
704    5,
705    quality_map
706    );
707
708   if (ret == NULL) goto nb_8;
709  
710   /* If nb_mode_new() was successful, the references to submodes have been
711    * copied into ret->submodes[], and it's safe to free submodes.
712    */
713   speex_free (submodes);
714
715   return ret;
716
717   /* Cleanup on memory allocation errors */
718  nb_8: speex_submode_free (submodes[8]);
719  nb_7: speex_submode_free (submodes[7]);
720  nb_6: speex_submode_free (submodes[6]);
721  nb_5: speex_submode_free (submodes[5]);
722  nb_4: speex_submode_free (submodes[4]);
723  nb_3: speex_submode_free (submodes[3]);
724  nb_2: speex_submode_free (submodes[2]);
725  nb_1: speex_submode_free (submodes[1]);
726
727   speex_free (submodes);
728
729   return NULL;
730 }
731
732
733 /* Default mode for narrowband */
734 const SpeexMode * speex_nb_mode_new (void)
735 {
736   const SpeexNBMode * _nb_mode;
737
738   _nb_mode = nb_mode();
739   if (_nb_mode == NULL) return NULL;
740
741   return speex_mode_new (
742    _nb_mode,
743    nb_mode_query,
744    "narrowband",
745    0,
746    4,
747    &nb_encoder_init,
748    &nb_encoder_destroy,
749    &nb_encode,
750    &nb_decoder_init,
751    &nb_decoder_destroy,
752    &nb_decode,
753    &nb_encoder_ctl,
754    &nb_decoder_ctl
755    );
756 }
757
758 void speex_nb_mode_free (const SpeexMode * mode)
759 {
760   nb_mode_free ((SpeexNBMode *)mode->mode);
761   speex_free ((void *)mode);
762 }
763
764 /* Wideband part */
765
766 static const SpeexSubmode * wb_submode1 (void)
767 {
768   return speex_submode_new (
769    0,
770    0,
771    1,
772    0,
773    /*LSP quantization*/
774    lsp_quant_high,
775    lsp_unquant_high,
776    /*Pitch quantization*/
777    NULL,
778    NULL,
779    NULL,
780    /*No innovation quantization*/
781    NULL,
782    NULL,
783    NULL,
784 #ifdef FIXED_POINT
785    24576, 24576, 0, -1,
786 #else
787    .75, .75, .0, -1,
788 #endif
789    36
790    );
791 }
792
793
794 static const SpeexSubmode * wb_submode2 (void)
795 {
796   return speex_submode_new (
797    0,
798    0,
799    1,
800    0,
801    /*LSP quantization*/
802    lsp_quant_high,
803    lsp_unquant_high,
804    /*Pitch quantization*/
805    NULL,
806    NULL,
807    NULL,
808    /*Innovation quantization*/
809    split_cb_search_shape_sign,
810    split_cb_shape_sign_unquant,
811    split_cb_high_lbr(),
812 #ifdef FIXED_POINT
813    27853, 19661, 8192, -1,
814 #else
815    .85, .6, .25, -1,
816 #endif
817    112
818    );
819 }
820
821
822 static const SpeexSubmode * wb_submode3 (void)
823 {
824   return speex_submode_new (
825    0,
826    0,
827    1,
828    0,
829    /*LSP quantization*/
830    lsp_quant_high,
831    lsp_unquant_high,
832    /*Pitch quantization*/
833    NULL,
834    NULL,
835    NULL,
836    /*Innovation quantization*/
837    split_cb_search_shape_sign,
838    split_cb_shape_sign_unquant,
839    split_cb_high(),
840
841 #ifdef FIXED_POINT
842    24576, 22938, 1638, -1,
843 #else
844    .75, .7, .05, -1,
845 #endif
846    192
847    );
848 }
849
850 static const SpeexSubmode * wb_submode4 (void)
851 {
852   return speex_submode_new (
853    0,
854    0,
855    1,
856    1,
857    /*LSP quantization*/
858    lsp_quant_high,
859    lsp_unquant_high,
860    /*Pitch quantization*/
861    NULL,
862    NULL,
863    NULL,
864    /*Innovation quantization*/
865    split_cb_search_shape_sign,
866    split_cb_shape_sign_unquant,
867    split_cb_high(),
868 #ifdef FIXED_POINT
869    24576, 24576, 0, -1,
870 #else
871    .75, .75, .0, -1,
872 #endif
873    352
874    );
875 }
876
877
878 /* Split-band wideband CELP mode*/
879 static const SpeexSBMode * sb_wb_mode (void)
880 {
881   const SpeexMode * nb_mode;
882   const SpeexSubmode ** submodes;
883   int low_quality_map[11] = {1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7};
884   int quality_map[11] = {1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4};
885   SpeexSBMode * ret;
886
887   nb_mode = speex_nb_mode_new ();
888   if (nb_mode == NULL) return NULL;
889
890   submodes = (const SpeexSubmode **)
891     speex_alloc (sizeof (SpeexSubmode *) * SB_SUBMODES);
892   if (submodes == NULL) return NULL;
893   memset (submodes, 0, sizeof (submodes));
894
895   if (!(submodes[1] = wb_submode1())) goto sb_1;
896   if (!(submodes[2] = wb_submode2())) goto sb_2;
897   if (!(submodes[3] = wb_submode3())) goto sb_3;
898   if (!(submodes[4] = wb_submode4())) goto sb_4;
899
900   ret = sb_mode_new (
901    nb_mode,
902    160,    /*frameSize*/
903    40,     /*subframeSize*/
904    8,     /*lpcSize*/
905    640,    /*bufSize*/
906 #ifdef FIXED_POINT
907    29491, 19661, /* gamma1, gamma2 */
908 #else
909    0.9, 0.6, /* gamma1, gamma2 */
910 #endif
911    .001,   /*lag_factor*/
912    1.0001, /*lpc_floor*/
913    0.9,
914    submodes,
915    3,
916    low_quality_map,
917    quality_map,
918    vbr_hb_thresh,
919    5
920    );
921
922   if (ret == NULL) goto sb_4;
923
924   /* If sb_mode_new() was successful, the references to submodes have been
925    * copied into ret->submodes[], and it's safe to free submodes.
926    */
927   speex_free (submodes);
928
929   return ret;
930
931   /* Cleanup on memory allocation errors */
932  sb_4: speex_submode_free (submodes[4]);
933  sb_3: speex_submode_free (submodes[3]);
934  sb_2: speex_submode_free (submodes[2]);
935  sb_1: speex_submode_free (submodes[1]);
936
937   speex_free (submodes);
938
939   return NULL;
940 }
941
942 static void
943 sb_wb_mode_free (const SpeexSBMode * mode)
944 {
945   speex_nb_mode_free (mode->nb_mode);
946 }
947
948 const SpeexMode * speex_wb_mode_new (void)
949 {
950   const SpeexSBMode * sb_mode;
951
952   sb_mode = sb_wb_mode ();
953   if (sb_mode == NULL) return NULL;
954
955   return speex_mode_new (
956    (const SpeexNBMode *)sb_mode,
957    wb_mode_query,
958    "wideband (sub-band CELP)",
959    1,
960    4,
961    &sb_encoder_init,
962    &sb_encoder_destroy,
963    &sb_encode,
964    &sb_decoder_init,
965    &sb_decoder_destroy,
966    &sb_decode,
967    &sb_encoder_ctl,
968    &sb_decoder_ctl
969    );
970 }
971
972 void speex_wb_mode_free (const SpeexMode * mode)
973 {
974   sb_wb_mode_free (mode->mode);
975   speex_free ((void *)mode);
976 }
977
978
979 /* "Ultra-wideband" mode stuff */
980
981
982
983 /* Split-band "ultra-wideband" (32 kbps) CELP mode*/
984 static const SpeexSBMode * sb_uwb_mode (void)
985 {
986   const SpeexSBMode * nb_mode;
987   const SpeexSubmode ** submodes;
988   int low_quality_map[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
989   int quality_map[11] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
990   SpeexSBMode * ret;
991
992   nb_mode = sb_wb_mode ();
993   if (nb_mode == NULL) return NULL;
994
995   submodes = (const SpeexSubmode **)
996     speex_alloc (sizeof (SpeexSubmode *) * SB_SUBMODES);
997   if (submodes == NULL) return NULL;
998   memset (submodes, 0, sizeof (submodes));
999
1000   if (!(submodes[1] = wb_submode1())) goto uwb_1;
1001
1002   ret = sb_mode_new (
1003    (const SpeexMode *)nb_mode,
1004    320,    /*frameSize*/
1005    80,     /*subframeSize*/
1006    8,     /*lpcSize*/
1007    1280,    /*bufSize*/
1008 #ifdef FIXED_POINT
1009    29491, 19661, /* gamma1, gamma2 */
1010 #else
1011    0.9, 0.6, /* gamma1, gamma2 */
1012 #endif
1013    .002,   /*lag_factor*/
1014    1.0001, /*lpc_floor*/
1015    0.7,
1016    submodes,
1017    1,
1018    low_quality_map,
1019    quality_map,
1020    vbr_uhb_thresh,
1021    2
1022    );
1023
1024   if (ret == NULL) goto uwb_1;
1025
1026   /* If sb_mode_new() was successful, the references to submodes have been
1027    * copied into ret->submodes[], and it's safe to free submodes.
1028    */
1029   speex_free (submodes);
1030
1031   return ret;
1032
1033  uwb_1: speex_submode_free (submodes[1]);
1034
1035   speex_free (submodes);
1036
1037   return NULL;
1038 }
1039
1040 void sb_uwb_mode_free (const SpeexSBMode * mode)
1041 {
1042   sb_wb_mode_free ((const SpeexSBMode *)mode->nb_mode);
1043   sb_mode_free (mode);
1044 }
1045
1046 const SpeexMode * speex_uwb_mode_new (void)
1047 {
1048   const SpeexSBMode * sb_mode;
1049
1050   sb_mode = sb_uwb_mode();
1051   if (sb_mode == NULL) return NULL;
1052
1053   return speex_mode_new (
1054    sb_mode,
1055    wb_mode_query,
1056    "ultra-wideband (sub-band CELP)",
1057    2,
1058    4,
1059    &sb_encoder_init,
1060    &sb_encoder_destroy,
1061    &sb_encode,
1062    &sb_decoder_init,
1063    &sb_decoder_destroy,
1064    &sb_decode,
1065    &sb_encoder_ctl,
1066    &sb_decoder_ctl
1067    );
1068 }
1069
1070 void speex_uwb_mode_free (const SpeexMode * mode)
1071 {
1072   sb_uwb_mode_free (mode->mode);
1073   speex_free ((void *)mode);
1074 }
1075
1076 const SpeexMode * speex_mode_new_byID (int id)
1077 {
1078   switch (id) {
1079   case 0: return speex_nb_mode_new(); break;
1080   case 1: return speex_wb_mode_new(); break;
1081   case 2: return speex_uwb_mode_new(); break;
1082   default: return NULL;
1083   }
1084 }
1085
1086 void speex_mode_free_byID (SpeexMode * mode, int id)
1087 {
1088   switch (id) {
1089   case 0: speex_nb_mode_free(mode); break;
1090   case 1: speex_wb_mode_free(mode); break;
1091   case 2:  speex_uwb_mode_free(mode); break;
1092   default: break;
1093   }
1094 }
1095
1096 /** XXX: This is just a dummy global mode, as used by nb_celp.c */
1097 const SpeexMode speex_wb_mode = {
1098    NULL,
1099    NULL,
1100    NULL,
1101    0,
1102    0,
1103    NULL,
1104    NULL,
1105    NULL,
1106    NULL,
1107    NULL,
1108    NULL,
1109    NULL,
1110    NULL
1111 };
1112
1113 int speex_mode_query(const SpeexMode *mode, int request, void *ptr)
1114 {
1115   if (mode == &speex_wb_mode && request == SPEEX_SUBMODE_BITS_PER_FRAME) {
1116     int * p = (int*)ptr;
1117
1118     switch (*p) {
1119     case 0: *p = SB_SUBMODE_BITS+1; break;
1120     case 1: *p = 36; break;
1121     case 2: *p = 112; break;
1122     case 3: *p = 192; break;
1123     case 4: *p = 352; break;
1124     default: *p = -1; break;
1125     }
1126
1127     return 0;
1128   }
1129   
1130   return mode->query(mode->mode, request, ptr);
1131 }