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