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 EXPORT 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 EXPORT 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
wb_mode_query(const void * mode,int request,void * ptr)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 EXPORT 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
speex_lib_get_mode(int mode)292 EXPORT 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
301