resampler: passing NULL as input should help drain the resampler.
[speexdsp.git] / libspeex / modes_wb.c
1 /* Copyright (C) 2002-2007 Jean-Marc Valin 
2    File: modes.c
3
4    Describes the wideband 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 "arch.h"
47 #include <math.h>
48 #include "os_support.h"
49
50
51 #ifndef NULL
52 #define NULL 0
53 #endif
54
55 const SpeexMode * const speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode};
56
57 extern const signed char hexc_table[];
58 extern const signed char hexc_10_32_table[];
59
60 #ifndef DISABLE_WIDEBAND
61
62 /* Split-VQ innovation for high-band wideband */
63 static const split_cb_params split_cb_high = {
64    8,               /*subvect_size*/
65    5,               /*nb_subvect*/
66    hexc_table,       /*shape_cb*/
67    7,               /*shape_bits*/
68    1,
69 };
70
71
72 /* Split-VQ innovation for high-band wideband */
73 static const split_cb_params split_cb_high_lbr = {
74    10,               /*subvect_size*/
75    4,               /*nb_subvect*/
76    hexc_10_32_table,       /*shape_cb*/
77    5,               /*shape_bits*/
78    0,
79 };
80
81 #endif
82
83
84 static const SpeexSubmode wb_submode1 = {
85    0,
86    0,
87    1,
88    0,
89    /*LSP quantization*/
90    lsp_quant_high,
91    lsp_unquant_high,
92    /*Pitch quantization*/
93    NULL,
94    NULL,
95    NULL,
96    /*No innovation quantization*/
97    NULL,
98    NULL,
99    NULL,
100    -1,
101    36
102 };
103
104
105 static const SpeexSubmode wb_submode2 = {
106    0,
107    0,
108    1,
109    0,
110    /*LSP quantization*/
111    lsp_quant_high,
112    lsp_unquant_high,
113    /*Pitch quantization*/
114    NULL,
115    NULL,
116    NULL,
117    /*Innovation quantization*/
118    split_cb_search_shape_sign,
119    split_cb_shape_sign_unquant,
120 #ifdef DISABLE_WIDEBAND
121    NULL,
122 #else
123    &split_cb_high_lbr,
124 #endif
125    -1,
126    112
127 };
128
129
130 static const SpeexSubmode wb_submode3 = {
131    0,
132    0,
133    1,
134    0,
135    /*LSP quantization*/
136    lsp_quant_high,
137    lsp_unquant_high,
138    /*Pitch quantization*/
139    NULL,
140    NULL,
141    NULL,
142    /*Innovation quantization*/
143    split_cb_search_shape_sign,
144    split_cb_shape_sign_unquant,
145 #ifdef DISABLE_WIDEBAND
146    NULL,
147 #else
148    &split_cb_high,
149 #endif
150    -1,
151    192
152 };
153
154 static const SpeexSubmode wb_submode4 = {
155    0,
156    0,
157    1,
158    1,
159    /*LSP quantization*/
160    lsp_quant_high,
161    lsp_unquant_high,
162    /*Pitch quantization*/
163    NULL,
164    NULL,
165    NULL,
166    /*Innovation quantization*/
167    split_cb_search_shape_sign,
168    split_cb_shape_sign_unquant,
169 #ifdef DISABLE_WIDEBAND
170    NULL,
171 #else
172    &split_cb_high,
173 #endif
174    -1,
175    352
176 };
177
178
179 /* Split-band wideband CELP mode*/
180 static const SpeexSBMode sb_wb_mode = {
181    &speex_nb_mode,
182    160,    /*frameSize*/
183    40,     /*subframeSize*/
184    8,     /*lpcSize*/
185 #ifdef FIXED_POINT
186    29491, 19661, /* gamma1, gamma2 */
187 #else
188    0.9, 0.6, /* gamma1, gamma2 */
189 #endif
190    QCONST16(.0002,15), /*lpc_floor*/
191    QCONST16(0.9f,15),
192    {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL},
193    3,
194    {1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7},
195    {1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4},
196 #ifndef DISABLE_VBR
197    vbr_hb_thresh,
198 #endif
199    5
200 };
201
202
203 const SpeexMode speex_wb_mode = {
204    &sb_wb_mode,
205    wb_mode_query,
206    "wideband (sub-band CELP)",
207    1,
208    4,
209    &sb_encoder_init,
210    &sb_encoder_destroy,
211    &sb_encode,
212    &sb_decoder_init,
213    &sb_decoder_destroy,
214    &sb_decode,
215    &sb_encoder_ctl,
216    &sb_decoder_ctl,
217 };
218
219
220
221 /* "Ultra-wideband" mode stuff */
222
223
224
225 /* Split-band "ultra-wideband" (32 kbps) CELP mode*/
226 static const SpeexSBMode sb_uwb_mode = {
227    &speex_wb_mode,
228    320,    /*frameSize*/
229    80,     /*subframeSize*/
230    8,     /*lpcSize*/
231 #ifdef FIXED_POINT
232    29491, 19661, /* gamma1, gamma2 */
233 #else
234    0.9, 0.6, /* gamma1, gamma2 */
235 #endif
236    QCONST16(.0002,15), /*lpc_floor*/
237    QCONST16(0.7f,15),
238    {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL},
239    1,
240    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
241    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
242 #ifndef DISABLE_VBR
243    vbr_uhb_thresh,
244 #endif
245    2
246 };
247
248 int wb_mode_query(const void *mode, int request, void *ptr)
249 {
250    const SpeexSBMode *m = (const SpeexSBMode*)mode;
251
252    switch (request)
253    {
254       case SPEEX_MODE_FRAME_SIZE:
255          *((int*)ptr)=2*m->frameSize;
256          break;
257       case SPEEX_SUBMODE_BITS_PER_FRAME:
258          if (*((int*)ptr)==0)
259             *((int*)ptr) = SB_SUBMODE_BITS+1;
260          else if (m->submodes[*((int*)ptr)]==NULL)
261             *((int*)ptr) = -1;
262          else
263             *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
264          break;
265       default:
266          speex_warning_int("Unknown wb_mode_query request: ", request);
267          return -1;
268    }
269    return 0;
270 }
271
272
273 const SpeexMode speex_uwb_mode = {
274    &sb_uwb_mode,
275    wb_mode_query,
276    "ultra-wideband (sub-band CELP)",
277    2,
278    4,
279    &sb_encoder_init,
280    &sb_encoder_destroy,
281    &sb_encode,
282    &sb_decoder_init,
283    &sb_decoder_destroy,
284    &sb_decode,
285    &sb_encoder_ctl,
286    &sb_decoder_ctl,
287 };
288
289 /* We have defined speex_lib_get_mode() as a macro in speex.h */
290 #undef speex_lib_get_mode
291
292 const SpeexMode * speex_lib_get_mode (int mode)
293 {
294    if (mode < 0 || mode >= SPEEX_NB_MODES) return NULL;
295
296    return speex_mode_list[mode];
297 }
298
299
300