Port Android relocation packer to chromium build
[chromium-blink-merge.git] / third_party / speex / libspeex / sb_celp.c
blob6c19ff8bb751a3350516ba6f029ddb8faa285dfc
1 /* Copyright (C) 2002-2006 Jean-Marc Valin
2 File: sb_celp.c
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
15 - Neither the name of the Xiph.org Foundation nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
36 #include <math.h>
37 #include "sb_celp.h"
38 #include "filters.h"
39 #include "lpc.h"
40 #include "lsp.h"
41 #include "stack_alloc.h"
42 #include "cb_search.h"
43 #include "quant_lsp.h"
44 #include "vq.h"
45 #include "ltp.h"
46 #include "arch.h"
47 #include "math_approx.h"
48 #include "os_support.h"
50 #ifndef NULL
51 #define NULL 0
52 #endif
54 /* Default size for the encoder and decoder stack (can be changed at compile time).
55 This does not apply when using variable-size arrays or alloca. */
56 #ifndef SB_ENC_STACK
57 #define SB_ENC_STACK (10000*sizeof(spx_sig_t))
58 #endif
60 #ifndef SB_DEC_STACK
61 #define SB_DEC_STACK (6000*sizeof(spx_sig_t))
62 #endif
65 #ifdef DISABLE_WIDEBAND
66 void *sb_encoder_init(const SpeexMode *m)
68 speex_fatal("Wideband and Ultra-wideband are disabled");
69 return NULL;
71 void sb_encoder_destroy(void *state)
73 speex_fatal("Wideband and Ultra-wideband are disabled");
75 int sb_encode(void *state, void *vin, SpeexBits *bits)
77 speex_fatal("Wideband and Ultra-wideband are disabled");
78 return -2;
80 void *sb_decoder_init(const SpeexMode *m)
82 speex_fatal("Wideband and Ultra-wideband are disabled");
83 return NULL;
85 void sb_decoder_destroy(void *state)
87 speex_fatal("Wideband and Ultra-wideband are disabled");
89 int sb_decode(void *state, SpeexBits *bits, void *vout)
91 speex_fatal("Wideband and Ultra-wideband are disabled");
92 return -2;
94 int sb_encoder_ctl(void *state, int request, void *ptr)
96 speex_fatal("Wideband and Ultra-wideband are disabled");
97 return -2;
99 int sb_decoder_ctl(void *state, int request, void *ptr)
101 speex_fatal("Wideband and Ultra-wideband are disabled");
102 return -2;
104 #else
107 #ifndef M_PI
108 #define M_PI 3.14159265358979323846 /* pi */
109 #endif
111 #define sqr(x) ((x)*(x))
113 #define SUBMODE(x) st->submodes[st->submodeID]->x
115 #ifdef FIXED_POINT
116 static const spx_word16_t gc_quant_bound[16] = {125, 164, 215, 282, 370, 484, 635, 832, 1090, 1428, 1871, 2452, 3213, 4210, 5516, 7228};
117 static const spx_word16_t fold_quant_bound[32] = {
118 39, 44, 50, 57, 64, 73, 83, 94,
119 106, 120, 136, 154, 175, 198, 225, 255,
120 288, 327, 370, 420, 476, 539, 611, 692,
121 784, 889, 1007, 1141, 1293, 1465, 1660, 1881};
122 #define LSP_MARGIN 410
123 #define LSP_DELTA1 6553
124 #define LSP_DELTA2 1638
126 #else
128 static const spx_word16_t gc_quant_bound[16] = {
129 0.97979, 1.28384, 1.68223, 2.20426, 2.88829, 3.78458, 4.95900, 6.49787,
130 8.51428, 11.15642, 14.61846, 19.15484, 25.09895, 32.88761, 43.09325, 56.46588};
131 static const spx_word16_t fold_quant_bound[32] = {
132 0.30498, 0.34559, 0.39161, 0.44375, 0.50283, 0.56979, 0.64565, 0.73162,
133 0.82903, 0.93942, 1.06450, 1.20624, 1.36685, 1.54884, 1.75506, 1.98875,
134 2.25355, 2.55360, 2.89361, 3.27889, 3.71547, 4.21018, 4.77076, 5.40598,
135 6.12577, 6.94141, 7.86565, 8.91295, 10.09969, 11.44445, 12.96826, 14.69497};
137 #define LSP_MARGIN .05
138 #define LSP_DELTA1 .2
139 #define LSP_DELTA2 .05
141 #endif
143 #define QMF_ORDER 64
145 #ifdef FIXED_POINT
146 static const spx_word16_t h0[64] = {2, -7, -7, 18, 15, -39, -25, 75, 35, -130, -41, 212, 38, -327, -17, 483, -32, -689, 124, 956, -283, -1307, 543, 1780, -973, -2467, 1733, 3633, -3339, -6409, 9059, 30153, 30153, 9059, -6409, -3339, 3633, 1733, -2467, -973, 1780, 543, -1307, -283, 956, 124, -689, -32, 483, -17, -327, 38, 212, -41, -130, 35, 75, -25, -39, 15, 18, -7, -7, 2};
148 #else
149 static const float h0[64] = {
150 3.596189e-05f, -0.0001123515f,
151 -0.0001104587f, 0.0002790277f,
152 0.0002298438f, -0.0005953563f,
153 -0.0003823631f, 0.00113826f,
154 0.0005308539f, -0.001986177f,
155 -0.0006243724f, 0.003235877f,
156 0.0005743159f, -0.004989147f,
157 -0.0002584767f, 0.007367171f,
158 -0.0004857935f, -0.01050689f,
159 0.001894714f, 0.01459396f,
160 -0.004313674f, -0.01994365f,
161 0.00828756f, 0.02716055f,
162 -0.01485397f, -0.03764973f,
163 0.026447f, 0.05543245f,
164 -0.05095487f, -0.09779096f,
165 0.1382363f, 0.4600981f,
166 0.4600981f, 0.1382363f,
167 -0.09779096f, -0.05095487f,
168 0.05543245f, 0.026447f,
169 -0.03764973f, -0.01485397f,
170 0.02716055f, 0.00828756f,
171 -0.01994365f, -0.004313674f,
172 0.01459396f, 0.001894714f,
173 -0.01050689f, -0.0004857935f,
174 0.007367171f, -0.0002584767f,
175 -0.004989147f, 0.0005743159f,
176 0.003235877f, -0.0006243724f,
177 -0.001986177f, 0.0005308539f,
178 0.00113826f, -0.0003823631f,
179 -0.0005953563f, 0.0002298438f,
180 0.0002790277f, -0.0001104587f,
181 -0.0001123515f, 3.596189e-05f
184 #endif
186 extern const spx_word16_t lag_window[];
187 extern const spx_word16_t lpc_window[];
190 void *sb_encoder_init(const SpeexMode *m)
192 int i;
193 spx_int32_t tmp;
194 SBEncState *st;
195 const SpeexSBMode *mode;
197 st = (SBEncState*)speex_alloc(sizeof(SBEncState));
198 if (!st)
199 return NULL;
200 st->mode = m;
201 mode = (const SpeexSBMode*)m->mode;
204 st->st_low = speex_encoder_init(mode->nb_mode);
205 #if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
206 st->stack = NULL;
207 #else
208 /*st->stack = (char*)speex_alloc_scratch(SB_ENC_STACK);*/
209 speex_encoder_ctl(st->st_low, SPEEX_GET_STACK, &st->stack);
210 #endif
212 st->full_frame_size = 2*mode->frameSize;
213 st->frame_size = mode->frameSize;
214 st->subframeSize = mode->subframeSize;
215 st->nbSubframes = mode->frameSize/mode->subframeSize;
216 st->windowSize = st->frame_size+st->subframeSize;
217 st->lpcSize=mode->lpcSize;
219 st->encode_submode = 1;
220 st->submodes=mode->submodes;
221 st->submodeSelect = st->submodeID=mode->defaultSubmode;
223 tmp=9;
224 speex_encoder_ctl(st->st_low, SPEEX_SET_QUALITY, &tmp);
225 tmp=1;
226 speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp);
228 st->lpc_floor = mode->lpc_floor;
229 st->gamma1=mode->gamma1;
230 st->gamma2=mode->gamma2;
231 st->first=1;
233 st->high=(spx_word16_t*)speex_alloc((st->windowSize-st->frame_size)*sizeof(spx_word16_t));
235 st->h0_mem=(spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
236 st->h1_mem=(spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
238 st->window= lpc_window;
240 st->lagWindow = lag_window;
242 st->old_lsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t));
243 st->old_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t));
244 st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t));
245 st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));
246 st->exc_rms = (spx_word16_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word16_t));
247 st->innov_rms_save = NULL;
249 st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
250 st->mem_sp2 = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
251 st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
253 for (i=0;i<st->lpcSize;i++)
254 st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
256 #ifndef DISABLE_VBR
257 st->vbr_quality = 8;
258 st->vbr_enabled = 0;
259 st->vbr_max = 0;
260 st->vbr_max_high = 20000; /* We just need a big value here */
261 st->vad_enabled = 0;
262 st->abr_enabled = 0;
263 st->relative_quality=0;
264 #endif /* #ifndef DISABLE_VBR */
266 st->complexity=2;
267 speex_encoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate);
268 st->sampling_rate*=2;
269 #ifdef ENABLE_VALGRIND
270 VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));
271 #endif
272 return st;
275 void sb_encoder_destroy(void *state)
277 SBEncState *st=(SBEncState*)state;
279 speex_encoder_destroy(st->st_low);
280 #if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
281 /*speex_free_scratch(st->stack);*/
282 #endif
284 speex_free(st->high);
286 speex_free(st->h0_mem);
287 speex_free(st->h1_mem);
289 speex_free(st->old_lsp);
290 speex_free(st->old_qlsp);
291 speex_free(st->interp_qlpc);
292 speex_free(st->pi_gain);
293 speex_free(st->exc_rms);
295 speex_free(st->mem_sp);
296 speex_free(st->mem_sp2);
297 speex_free(st->mem_sw);
300 speex_free(st);
304 int sb_encode(void *state, void *vin, SpeexBits *bits)
306 SBEncState *st;
307 int i, roots, sub;
308 char *stack;
309 VARDECL(spx_mem_t *mem);
310 VARDECL(spx_sig_t *innov);
311 VARDECL(spx_word16_t *target);
312 VARDECL(spx_word16_t *syn_resp);
313 VARDECL(spx_word32_t *low_pi_gain);
314 spx_word16_t *low;
315 spx_word16_t *high;
316 VARDECL(spx_word16_t *low_exc_rms);
317 VARDECL(spx_word16_t *low_innov_rms);
318 const SpeexSBMode *mode;
319 spx_int32_t dtx;
320 spx_word16_t *in = (spx_word16_t*)vin;
321 spx_word16_t e_low=0, e_high=0;
322 VARDECL(spx_coef_t *lpc);
323 VARDECL(spx_coef_t *interp_lpc);
324 VARDECL(spx_coef_t *bw_lpc1);
325 VARDECL(spx_coef_t *bw_lpc2);
326 VARDECL(spx_lsp_t *lsp);
327 VARDECL(spx_lsp_t *qlsp);
328 VARDECL(spx_lsp_t *interp_lsp);
329 VARDECL(spx_lsp_t *interp_qlsp);
331 st = (SBEncState*)state;
332 stack=st->stack;
333 mode = (const SpeexSBMode*)(st->mode->mode);
334 low = in;
335 high = in+st->frame_size;
337 /* High-band buffering / sync with low band */
338 /* Compute the two sub-bands by filtering with QMF h0*/
339 qmf_decomp(in, h0, low, high, st->full_frame_size, QMF_ORDER, st->h0_mem, stack);
341 #ifndef DISABLE_VBR
342 if (st->vbr_enabled || st->vad_enabled)
344 /* Need to compute things here before the signal is trashed by the encoder */
345 /*FIXME: Are the two signals (low, high) in sync? */
346 e_low = compute_rms16(low, st->frame_size);
347 e_high = compute_rms16(high, st->frame_size);
349 #endif /* #ifndef DISABLE_VBR */
351 ALLOC(low_innov_rms, st->nbSubframes, spx_word16_t);
352 speex_encoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, low_innov_rms);
353 /* Encode the narrowband part*/
354 speex_encode_native(st->st_low, low, bits);
356 high = high - (st->windowSize-st->frame_size);
357 SPEEX_COPY(high, st->high, st->windowSize-st->frame_size);
358 SPEEX_COPY(st->high, &high[st->frame_size], st->windowSize-st->frame_size);
361 ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t);
362 ALLOC(low_exc_rms, st->nbSubframes, spx_word16_t);
363 speex_encoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain);
364 speex_encoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc_rms);
366 speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, &dtx);
368 if (dtx==0)
369 dtx=1;
370 else
371 dtx=0;
373 ALLOC(lpc, st->lpcSize, spx_coef_t);
374 ALLOC(interp_lpc, st->lpcSize, spx_coef_t);
375 ALLOC(bw_lpc1, st->lpcSize, spx_coef_t);
376 ALLOC(bw_lpc2, st->lpcSize, spx_coef_t);
378 ALLOC(lsp, st->lpcSize, spx_lsp_t);
379 ALLOC(qlsp, st->lpcSize, spx_lsp_t);
380 ALLOC(interp_lsp, st->lpcSize, spx_lsp_t);
381 ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);
384 VARDECL(spx_word16_t *autocorr);
385 VARDECL(spx_word16_t *w_sig);
386 ALLOC(autocorr, st->lpcSize+1, spx_word16_t);
387 ALLOC(w_sig, st->windowSize, spx_word16_t);
388 /* Window for analysis */
389 /* FIXME: This is a kludge */
390 if (st->subframeSize==80)
392 for (i=0;i<st->windowSize;i++)
393 w_sig[i] = EXTRACT16(SHR32(MULT16_16(high[i],st->window[i>>1]),SIG_SHIFT));
394 } else {
395 for (i=0;i<st->windowSize;i++)
396 w_sig[i] = EXTRACT16(SHR32(MULT16_16(high[i],st->window[i]),SIG_SHIFT));
398 /* Compute auto-correlation */
399 _spx_autocorr(w_sig, autocorr, st->lpcSize+1, st->windowSize);
400 autocorr[0] = ADD16(autocorr[0],MULT16_16_Q15(autocorr[0],st->lpc_floor)); /* Noise floor in auto-correlation domain */
402 /* Lag windowing: equivalent to filtering in the power-spectrum domain */
403 for (i=0;i<st->lpcSize+1;i++)
404 autocorr[i] = MULT16_16_Q14(autocorr[i],st->lagWindow[i]);
406 /* Levinson-Durbin */
407 _spx_lpc(lpc, autocorr, st->lpcSize);
410 /* LPC to LSPs (x-domain) transform */
411 roots=lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA1, stack);
412 if (roots!=st->lpcSize)
414 roots = lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA2, stack);
415 if (roots!=st->lpcSize) {
416 /*If we can't find all LSP's, do some damage control and use a flat filter*/
417 for (i=0;i<st->lpcSize;i++)
419 lsp[i]=st->old_lsp[i];
424 #ifndef DISABLE_VBR
425 /* VBR code */
426 if ((st->vbr_enabled || st->vad_enabled) && !dtx)
428 float ratio;
429 if (st->abr_enabled)
431 float qual_change=0;
432 if (st->abr_drift2 * st->abr_drift > 0)
434 /* Only adapt if long-term and short-term drift are the same sign */
435 qual_change = -.00001*st->abr_drift/(1+st->abr_count);
436 if (qual_change>.1)
437 qual_change=.1;
438 if (qual_change<-.1)
439 qual_change=-.1;
441 st->vbr_quality += qual_change;
442 if (st->vbr_quality>10)
443 st->vbr_quality=10;
444 if (st->vbr_quality<0)
445 st->vbr_quality=0;
449 ratio = 2*log((1.f+e_high)/(1.f+e_low));
451 speex_encoder_ctl(st->st_low, SPEEX_GET_RELATIVE_QUALITY, &st->relative_quality);
452 if (ratio<-4)
453 ratio=-4;
454 if (ratio>2)
455 ratio=2;
456 /*if (ratio>-2)*/
457 if (st->vbr_enabled)
459 spx_int32_t modeid;
460 modeid = mode->nb_modes-1;
461 st->relative_quality+=1.0*(ratio+2);
462 if (st->relative_quality<-1)
463 st->relative_quality=-1;
464 while (modeid)
466 int v1;
467 float thresh;
468 v1=(int)floor(st->vbr_quality);
469 if (v1==10)
470 thresh = mode->vbr_thresh[modeid][v1];
471 else
472 thresh = (st->vbr_quality-v1) * mode->vbr_thresh[modeid][v1+1] +
473 (1+v1-st->vbr_quality) * mode->vbr_thresh[modeid][v1];
474 if (st->relative_quality >= thresh && st->sampling_rate*st->submodes[modeid]->bits_per_frame/st->full_frame_size <= st->vbr_max_high)
475 break;
476 modeid--;
478 speex_encoder_ctl(state, SPEEX_SET_HIGH_MODE, &modeid);
479 if (st->abr_enabled)
481 spx_int32_t bitrate;
482 speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate);
483 st->abr_drift+=(bitrate-st->abr_enabled);
484 st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled);
485 st->abr_count += 1.0;
488 } else {
489 /* VAD only */
490 int modeid;
491 if (st->relative_quality<2.0)
492 modeid=1;
493 else
494 modeid=st->submodeSelect;
495 /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/
496 st->submodeID=modeid;
499 /*fprintf (stderr, "%f %f\n", ratio, low_qual);*/
501 #endif /* #ifndef DISABLE_VBR */
503 if (st->encode_submode)
505 speex_bits_pack(bits, 1, 1);
506 if (dtx)
507 speex_bits_pack(bits, 0, SB_SUBMODE_BITS);
508 else
509 speex_bits_pack(bits, st->submodeID, SB_SUBMODE_BITS);
512 /* If null mode (no transmission), just set a couple things to zero*/
513 if (dtx || st->submodes[st->submodeID] == NULL)
515 for (i=0;i<st->frame_size;i++)
516 high[i]=VERY_SMALL;
518 for (i=0;i<st->lpcSize;i++)
519 st->mem_sw[i]=0;
520 st->first=1;
522 /* Final signal synthesis from excitation */
523 iir_mem16(high, st->interp_qlpc, high, st->frame_size, st->lpcSize, st->mem_sp, stack);
525 if (dtx)
526 return 0;
527 else
528 return 1;
532 /* LSP quantization */
533 SUBMODE(lsp_quant)(lsp, qlsp, st->lpcSize, bits);
535 if (st->first)
537 for (i=0;i<st->lpcSize;i++)
538 st->old_lsp[i] = lsp[i];
539 for (i=0;i<st->lpcSize;i++)
540 st->old_qlsp[i] = qlsp[i];
543 ALLOC(mem, st->lpcSize, spx_mem_t);
544 ALLOC(syn_resp, st->subframeSize, spx_word16_t);
545 ALLOC(innov, st->subframeSize, spx_sig_t);
546 ALLOC(target, st->subframeSize, spx_word16_t);
548 for (sub=0;sub<st->nbSubframes;sub++)
550 VARDECL(spx_word16_t *exc);
551 VARDECL(spx_word16_t *res);
552 VARDECL(spx_word16_t *sw);
553 spx_word16_t *sp;
554 spx_word16_t filter_ratio; /*Q7*/
555 int offset;
556 spx_word32_t rl, rh; /*Q13*/
557 spx_word16_t eh=0;
559 offset = st->subframeSize*sub;
560 sp=high+offset;
561 ALLOC(exc, st->subframeSize, spx_word16_t);
562 ALLOC(res, st->subframeSize, spx_word16_t);
563 ALLOC(sw, st->subframeSize, spx_word16_t);
565 /* LSP interpolation (quantized and unquantized) */
566 lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, sub, st->nbSubframes);
567 lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);
569 lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN);
570 lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);
572 lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack);
573 lsp_to_lpc(interp_qlsp, st->interp_qlpc, st->lpcSize, stack);
575 bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize);
576 bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize);
578 /* Compute mid-band (4000 Hz for wideband) response of low-band and high-band
579 filters */
580 st->pi_gain[sub]=LPC_SCALING;
581 rh = LPC_SCALING;
582 for (i=0;i<st->lpcSize;i+=2)
584 rh += st->interp_qlpc[i+1] - st->interp_qlpc[i];
585 st->pi_gain[sub] += st->interp_qlpc[i] + st->interp_qlpc[i+1];
588 rl = low_pi_gain[sub];
589 #ifdef FIXED_POINT
590 filter_ratio=EXTRACT16(SATURATE(PDIV32(SHL32(ADD32(rl,82),7),ADD32(82,rh)),32767));
591 #else
592 filter_ratio=(rl+.01)/(rh+.01);
593 #endif
595 /* Compute "real excitation" */
596 fir_mem16(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2, stack);
597 /* Compute energy of low-band and high-band excitation */
599 eh = compute_rms16(exc, st->subframeSize);
601 if (!SUBMODE(innovation_quant)) {/* 1 for spectral folding excitation, 0 for stochastic */
602 spx_word32_t g; /*Q7*/
603 spx_word16_t el; /*Q0*/
604 el = low_innov_rms[sub];
606 /* Gain to use if we want to use the low-band excitation for high-band */
607 g=PDIV32(MULT16_16(filter_ratio,eh),EXTEND32(ADD16(1,el)));
609 #if 0
611 char *tmp_stack=stack;
612 float *tmp_sig;
613 float g2;
614 ALLOC(tmp_sig, st->subframeSize, spx_sig_t);
615 for (i=0;i<st->lpcSize;i++)
616 mem[i]=st->mem_sp[i];
617 iir_mem2(st->low_innov+offset, st->interp_qlpc, tmp_sig, st->subframeSize, st->lpcSize, mem);
618 g2 = compute_rms(sp, st->subframeSize)/(.01+compute_rms(tmp_sig, st->subframeSize));
619 /*fprintf (stderr, "gains: %f %f\n", g, g2);*/
620 g = g2;
621 stack = tmp_stack;
623 #endif
625 /*print_vec(&g, 1, "gain factor");*/
626 /* Gain quantization */
628 int quant = scal_quant(g, fold_quant_bound, 32);
629 /*speex_warning_int("tata", quant);*/
630 if (quant<0)
631 quant=0;
632 if (quant>31)
633 quant=31;
634 speex_bits_pack(bits, quant, 5);
636 if (st->innov_rms_save)
638 st->innov_rms_save[sub] = eh;
640 st->exc_rms[sub] = eh;
641 } else {
642 spx_word16_t gc; /*Q7*/
643 spx_word32_t scale; /*Q14*/
644 spx_word16_t el; /*Q0*/
645 el = low_exc_rms[sub]; /*Q0*/
647 gc = PDIV32_16(MULT16_16(filter_ratio,1+eh),1+el);
649 /* This is a kludge that cleans up a historical bug */
650 if (st->subframeSize==80)
651 gc = MULT16_16_P15(QCONST16(0.70711f,15),gc);
652 /*printf ("%f %f %f %f\n", el, eh, filter_ratio, gc);*/
654 int qgc = scal_quant(gc, gc_quant_bound, 16);
655 speex_bits_pack(bits, qgc, 4);
656 gc = MULT16_16_Q15(QCONST16(0.87360,15),gc_quant_bound[qgc]);
658 if (st->subframeSize==80)
659 gc = MULT16_16_P14(QCONST16(1.4142f,14), gc);
661 scale = SHL32(MULT16_16(PDIV32_16(SHL32(EXTEND32(gc),SIG_SHIFT-6),filter_ratio),(1+el)),6);
663 compute_impulse_response(st->interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack);
666 /* Reset excitation */
667 for (i=0;i<st->subframeSize;i++)
668 res[i]=VERY_SMALL;
670 /* Compute zero response (ringing) of A(z/g1) / ( A(z/g2) * Aq(z) ) */
671 for (i=0;i<st->lpcSize;i++)
672 mem[i]=st->mem_sp[i];
673 iir_mem16(res, st->interp_qlpc, res, st->subframeSize, st->lpcSize, mem, stack);
675 for (i=0;i<st->lpcSize;i++)
676 mem[i]=st->mem_sw[i];
677 filter_mem16(res, bw_lpc1, bw_lpc2, res, st->subframeSize, st->lpcSize, mem, stack);
679 /* Compute weighted signal */
680 for (i=0;i<st->lpcSize;i++)
681 mem[i]=st->mem_sw[i];
682 filter_mem16(sp, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, mem, stack);
684 /* Compute target signal */
685 for (i=0;i<st->subframeSize;i++)
686 target[i]=SUB16(sw[i],res[i]);
688 signal_div(target, target, scale, st->subframeSize);
690 /* Reset excitation */
691 SPEEX_MEMSET(innov, 0, st->subframeSize);
693 /*print_vec(target, st->subframeSize, "\ntarget");*/
694 SUBMODE(innovation_quant)(target, st->interp_qlpc, bw_lpc1, bw_lpc2,
695 SUBMODE(innovation_params), st->lpcSize, st->subframeSize,
696 innov, syn_resp, bits, stack, st->complexity, SUBMODE(double_codebook));
697 /*print_vec(target, st->subframeSize, "after");*/
699 signal_mul(innov, innov, scale, st->subframeSize);
701 if (SUBMODE(double_codebook)) {
702 char *tmp_stack=stack;
703 VARDECL(spx_sig_t *innov2);
704 ALLOC(innov2, st->subframeSize, spx_sig_t);
705 SPEEX_MEMSET(innov2, 0, st->subframeSize);
706 for (i=0;i<st->subframeSize;i++)
707 target[i]=MULT16_16_P13(QCONST16(2.5f,13), target[i]);
709 SUBMODE(innovation_quant)(target, st->interp_qlpc, bw_lpc1, bw_lpc2,
710 SUBMODE(innovation_params), st->lpcSize, st->subframeSize,
711 innov2, syn_resp, bits, stack, st->complexity, 0);
712 signal_mul(innov2, innov2, MULT16_32_P15(QCONST16(0.4f,15),scale), st->subframeSize);
714 for (i=0;i<st->subframeSize;i++)
715 innov[i] = ADD32(innov[i],innov2[i]);
716 stack = tmp_stack;
718 for (i=0;i<st->subframeSize;i++)
719 exc[i] = PSHR32(innov[i],SIG_SHIFT);
721 if (st->innov_rms_save)
723 st->innov_rms_save[sub] = MULT16_16_Q15(QCONST16(.70711f, 15), compute_rms(innov, st->subframeSize));
725 st->exc_rms[sub] = compute_rms16(exc, st->subframeSize);
731 /*Keep the previous memory*/
732 for (i=0;i<st->lpcSize;i++)
733 mem[i]=st->mem_sp[i];
734 /* Final signal synthesis from excitation */
735 iir_mem16(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp, stack);
737 /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */
738 filter_mem16(sp, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw, stack);
741 for (i=0;i<st->lpcSize;i++)
742 st->old_lsp[i] = lsp[i];
743 for (i=0;i<st->lpcSize;i++)
744 st->old_qlsp[i] = qlsp[i];
746 st->first=0;
748 return 1;
755 void *sb_decoder_init(const SpeexMode *m)
757 spx_int32_t tmp;
758 SBDecState *st;
759 const SpeexSBMode *mode;
760 st = (SBDecState*)speex_alloc(sizeof(SBDecState));
761 if (!st)
762 return NULL;
763 st->mode = m;
764 mode=(const SpeexSBMode*)m->mode;
765 st->encode_submode = 1;
767 st->st_low = speex_decoder_init(mode->nb_mode);
768 #if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
769 st->stack = NULL;
770 #else
771 /*st->stack = (char*)speex_alloc_scratch(SB_DEC_STACK);*/
772 speex_decoder_ctl(st->st_low, SPEEX_GET_STACK, &st->stack);
773 #endif
775 st->full_frame_size = 2*mode->frameSize;
776 st->frame_size = mode->frameSize;
777 st->subframeSize = mode->subframeSize;
778 st->nbSubframes = mode->frameSize/mode->subframeSize;
779 st->lpcSize=mode->lpcSize;
780 speex_decoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate);
781 st->sampling_rate*=2;
782 tmp=1;
783 speex_decoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp);
785 st->submodes=mode->submodes;
786 st->submodeID=mode->defaultSubmode;
788 st->first=1;
790 st->g0_mem = (spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
791 st->g1_mem = (spx_word16_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
793 st->excBuf = (spx_word16_t*)speex_alloc((st->subframeSize)*sizeof(spx_word16_t));
795 st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
796 st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t));
798 st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));
799 st->exc_rms = (spx_word16_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word16_t));
800 st->mem_sp = (spx_mem_t*)speex_alloc((2*st->lpcSize)*sizeof(spx_mem_t));
802 st->innov_save = NULL;
805 st->lpc_enh_enabled=0;
806 st->seed = 1000;
808 #ifdef ENABLE_VALGRIND
809 VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));
810 #endif
811 return st;
814 void sb_decoder_destroy(void *state)
816 SBDecState *st;
817 st = (SBDecState*)state;
818 speex_decoder_destroy(st->st_low);
819 #if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
820 /*speex_free_scratch(st->stack);*/
821 #endif
823 speex_free(st->g0_mem);
824 speex_free(st->g1_mem);
825 speex_free(st->excBuf);
826 speex_free(st->old_qlsp);
827 speex_free(st->interp_qlpc);
828 speex_free(st->pi_gain);
829 speex_free(st->exc_rms);
830 speex_free(st->mem_sp);
832 speex_free(state);
835 static void sb_decode_lost(SBDecState *st, spx_word16_t *out, int dtx, char *stack)
837 int i;
838 int saved_modeid=0;
840 if (dtx)
842 saved_modeid=st->submodeID;
843 st->submodeID=1;
844 } else {
845 bw_lpc(QCONST16(0.99f,15), st->interp_qlpc, st->interp_qlpc, st->lpcSize);
848 st->first=1;
851 /* Final signal synthesis from excitation */
852 if (!dtx)
854 st->last_ener = MULT16_16_Q15(QCONST16(.9f,15),st->last_ener);
856 for (i=0;i<st->frame_size;i++)
857 out[i+st->frame_size] = speex_rand(st->last_ener, &st->seed);
859 iir_mem16(out+st->frame_size, st->interp_qlpc, out+st->frame_size, st->frame_size, st->lpcSize,
860 st->mem_sp, stack);
863 /* Reconstruct the original */
864 qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
865 if (dtx)
867 st->submodeID=saved_modeid;
870 return;
873 int sb_decode(void *state, SpeexBits *bits, void *vout)
875 int i, sub;
876 SBDecState *st;
877 int wideband;
878 int ret;
879 char *stack;
880 VARDECL(spx_word32_t *low_pi_gain);
881 VARDECL(spx_word16_t *low_exc_rms);
882 VARDECL(spx_coef_t *ak);
883 VARDECL(spx_lsp_t *qlsp);
884 VARDECL(spx_lsp_t *interp_qlsp);
885 spx_int32_t dtx;
886 const SpeexSBMode *mode;
887 spx_word16_t *out = (spx_word16_t*)vout;
888 spx_word16_t *low_innov_alias;
889 spx_word32_t exc_ener_sum = 0;
891 st = (SBDecState*)state;
892 stack=st->stack;
893 mode = (const SpeexSBMode*)(st->mode->mode);
895 low_innov_alias = out+st->frame_size;
896 speex_decoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, low_innov_alias);
897 /* Decode the low-band */
898 ret = speex_decode_native(st->st_low, bits, out);
900 speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, &dtx);
902 /* If error decoding the narrowband part, propagate error */
903 if (ret!=0)
905 return ret;
908 if (!bits)
910 sb_decode_lost(st, out, dtx, stack);
911 return 0;
914 if (st->encode_submode)
917 /*Check "wideband bit"*/
918 if (speex_bits_remaining(bits)>0)
919 wideband = speex_bits_peek(bits);
920 else
921 wideband = 0;
922 if (wideband)
924 /*Regular wideband frame, read the submode*/
925 wideband = speex_bits_unpack_unsigned(bits, 1);
926 st->submodeID = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
927 } else
929 /*Was a narrowband frame, set "null submode"*/
930 st->submodeID = 0;
932 if (st->submodeID != 0 && st->submodes[st->submodeID] == NULL)
934 speex_notify("Invalid mode encountered. The stream is corrupted.");
935 return -2;
939 /* If null mode (no transmission), just set a couple things to zero*/
940 if (st->submodes[st->submodeID] == NULL)
942 if (dtx)
944 sb_decode_lost(st, out, 1, stack);
945 return 0;
948 for (i=0;i<st->frame_size;i++)
949 out[st->frame_size+i]=VERY_SMALL;
951 st->first=1;
953 /* Final signal synthesis from excitation */
954 iir_mem16(out+st->frame_size, st->interp_qlpc, out+st->frame_size, st->frame_size, st->lpcSize, st->mem_sp, stack);
956 qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
958 return 0;
962 ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t);
963 ALLOC(low_exc_rms, st->nbSubframes, spx_word16_t);
964 speex_decoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain);
965 speex_decoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc_rms);
967 ALLOC(qlsp, st->lpcSize, spx_lsp_t);
968 ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);
969 SUBMODE(lsp_unquant)(qlsp, st->lpcSize, bits);
971 if (st->first)
973 for (i=0;i<st->lpcSize;i++)
974 st->old_qlsp[i] = qlsp[i];
977 ALLOC(ak, st->lpcSize, spx_coef_t);
979 for (sub=0;sub<st->nbSubframes;sub++)
981 VARDECL(spx_word32_t *exc);
982 spx_word16_t *innov_save=NULL;
983 spx_word16_t *sp;
984 spx_word16_t filter_ratio;
985 spx_word16_t el=0;
986 int offset;
987 spx_word32_t rl=0,rh=0;
989 offset = st->subframeSize*sub;
990 sp=out+st->frame_size+offset;
991 ALLOC(exc, st->subframeSize, spx_word32_t);
992 /* Pointer for saving innovation */
993 if (st->innov_save)
995 innov_save = st->innov_save+2*offset;
996 SPEEX_MEMSET(innov_save, 0, 2*st->subframeSize);
999 /* LSP interpolation */
1000 lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);
1002 lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);
1004 /* LSP to LPC */
1005 lsp_to_lpc(interp_qlsp, ak, st->lpcSize, stack);
1007 /* Calculate reponse ratio between the low and high filter in the middle
1008 of the band (4000 Hz) */
1010 st->pi_gain[sub]=LPC_SCALING;
1011 rh = LPC_SCALING;
1012 for (i=0;i<st->lpcSize;i+=2)
1014 rh += ak[i+1] - ak[i];
1015 st->pi_gain[sub] += ak[i] + ak[i+1];
1018 rl = low_pi_gain[sub];
1019 #ifdef FIXED_POINT
1020 filter_ratio=EXTRACT16(SATURATE(PDIV32(SHL32(ADD32(rl,82),7),ADD32(82,rh)),32767));
1021 #else
1022 filter_ratio=(rl+.01)/(rh+.01);
1023 #endif
1025 SPEEX_MEMSET(exc, 0, st->subframeSize);
1026 if (!SUBMODE(innovation_unquant))
1028 spx_word32_t g;
1029 int quant;
1031 quant = speex_bits_unpack_unsigned(bits, 5);
1032 g= spx_exp(MULT16_16(QCONST16(.125f,11),(quant-10)));
1034 g = PDIV32(g, filter_ratio);
1036 for (i=0;i<st->subframeSize;i+=2)
1038 exc[i]=SHL32(MULT16_32_P15(MULT16_16_Q15(mode->folding_gain,low_innov_alias[offset+i]),SHL32(g,6)),SIG_SHIFT);
1039 exc[i+1]=NEG32(SHL32(MULT16_32_P15(MULT16_16_Q15(mode->folding_gain,low_innov_alias[offset+i+1]),SHL32(g,6)),SIG_SHIFT));
1042 } else {
1043 spx_word16_t gc;
1044 spx_word32_t scale;
1045 int qgc = speex_bits_unpack_unsigned(bits, 4);
1047 el = low_exc_rms[sub];
1048 gc = MULT16_16_Q15(QCONST16(0.87360,15),gc_quant_bound[qgc]);
1050 if (st->subframeSize==80)
1051 gc = MULT16_16_P14(QCONST16(1.4142f,14),gc);
1053 scale = SHL32(PDIV32(SHL32(MULT16_16(gc, el),3), filter_ratio),SIG_SHIFT-3);
1054 SUBMODE(innovation_unquant)(exc, SUBMODE(innovation_params), st->subframeSize,
1055 bits, stack, &st->seed);
1057 signal_mul(exc,exc,scale,st->subframeSize);
1059 if (SUBMODE(double_codebook)) {
1060 char *tmp_stack=stack;
1061 VARDECL(spx_sig_t *innov2);
1062 ALLOC(innov2, st->subframeSize, spx_sig_t);
1063 SPEEX_MEMSET(innov2, 0, st->subframeSize);
1064 SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize,
1065 bits, stack, &st->seed);
1066 signal_mul(innov2, innov2, MULT16_32_P15(QCONST16(0.4f,15),scale), st->subframeSize);
1067 for (i=0;i<st->subframeSize;i++)
1068 exc[i] = ADD32(exc[i],innov2[i]);
1069 stack = tmp_stack;
1074 if (st->innov_save)
1076 for (i=0;i<st->subframeSize;i++)
1077 innov_save[2*i]=EXTRACT16(PSHR32(exc[i],SIG_SHIFT));
1080 iir_mem16(st->excBuf, st->interp_qlpc, sp, st->subframeSize, st->lpcSize,
1081 st->mem_sp, stack);
1082 for (i=0;i<st->subframeSize;i++)
1083 st->excBuf[i]=EXTRACT16(PSHR32(exc[i],SIG_SHIFT));
1084 for (i=0;i<st->lpcSize;i++)
1085 st->interp_qlpc[i] = ak[i];
1086 st->exc_rms[sub] = compute_rms16(st->excBuf, st->subframeSize);
1087 exc_ener_sum = ADD32(exc_ener_sum, DIV32(MULT16_16(st->exc_rms[sub],st->exc_rms[sub]), st->nbSubframes));
1089 st->last_ener = spx_sqrt(exc_ener_sum);
1091 qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
1092 for (i=0;i<st->lpcSize;i++)
1093 st->old_qlsp[i] = qlsp[i];
1095 st->first=0;
1097 return 0;
1101 int sb_encoder_ctl(void *state, int request, void *ptr)
1103 SBEncState *st;
1104 st=(SBEncState*)state;
1105 switch(request)
1107 case SPEEX_GET_FRAME_SIZE:
1108 (*(spx_int32_t*)ptr) = st->full_frame_size;
1109 break;
1110 case SPEEX_SET_HIGH_MODE:
1111 st->submodeSelect = st->submodeID = (*(spx_int32_t*)ptr);
1112 break;
1113 case SPEEX_SET_LOW_MODE:
1114 speex_encoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr);
1115 break;
1116 case SPEEX_SET_DTX:
1117 speex_encoder_ctl(st->st_low, SPEEX_SET_DTX, ptr);
1118 break;
1119 case SPEEX_GET_DTX:
1120 speex_encoder_ctl(st->st_low, SPEEX_GET_DTX, ptr);
1121 break;
1122 case SPEEX_GET_LOW_MODE:
1123 speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr);
1124 break;
1125 case SPEEX_SET_MODE:
1126 speex_encoder_ctl(st, SPEEX_SET_QUALITY, ptr);
1127 break;
1128 #ifndef DISABLE_VBR
1129 case SPEEX_SET_VBR:
1130 st->vbr_enabled = (*(spx_int32_t*)ptr);
1131 speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, ptr);
1132 break;
1133 case SPEEX_GET_VBR:
1134 (*(spx_int32_t*)ptr) = st->vbr_enabled;
1135 break;
1136 case SPEEX_SET_VAD:
1137 st->vad_enabled = (*(spx_int32_t*)ptr);
1138 speex_encoder_ctl(st->st_low, SPEEX_SET_VAD, ptr);
1139 break;
1140 case SPEEX_GET_VAD:
1141 (*(spx_int32_t*)ptr) = st->vad_enabled;
1142 break;
1143 #endif /* #ifndef DISABLE_VBR */
1144 #if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API)
1145 case SPEEX_SET_VBR_QUALITY:
1147 spx_int32_t q;
1148 float qual = (*(float*)ptr)+.6;
1149 st->vbr_quality = (*(float*)ptr);
1150 if (qual>10)
1151 qual=10;
1152 q=(int)floor(.5+*(float*)ptr);
1153 if (q>10)
1154 q=10;
1155 speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_QUALITY, &qual);
1156 speex_encoder_ctl(state, SPEEX_SET_QUALITY, &q);
1157 break;
1159 case SPEEX_GET_VBR_QUALITY:
1160 (*(float*)ptr) = st->vbr_quality;
1161 break;
1162 #endif /* #if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */
1163 #ifndef DISABLE_VBR
1164 case SPEEX_SET_ABR:
1165 st->abr_enabled = (*(spx_int32_t*)ptr);
1166 st->vbr_enabled = st->abr_enabled!=0;
1167 speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, &st->vbr_enabled);
1168 if (st->vbr_enabled)
1170 spx_int32_t i=10, rate, target;
1171 float vbr_qual;
1172 target = (*(spx_int32_t*)ptr);
1173 while (i>=0)
1175 speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
1176 speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
1177 if (rate <= target)
1178 break;
1179 i--;
1181 vbr_qual=i;
1182 if (vbr_qual<0)
1183 vbr_qual=0;
1184 speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual);
1185 st->abr_count=0;
1186 st->abr_drift=0;
1187 st->abr_drift2=0;
1190 break;
1191 case SPEEX_GET_ABR:
1192 (*(spx_int32_t*)ptr) = st->abr_enabled;
1193 break;
1194 #endif /* #ifndef DISABLE_VBR */
1196 case SPEEX_SET_QUALITY:
1198 spx_int32_t nb_qual;
1199 int quality = (*(spx_int32_t*)ptr);
1200 if (quality < 0)
1201 quality = 0;
1202 if (quality > 10)
1203 quality = 10;
1204 st->submodeSelect = st->submodeID = ((const SpeexSBMode*)(st->mode->mode))->quality_map[quality];
1205 nb_qual = ((const SpeexSBMode*)(st->mode->mode))->low_quality_map[quality];
1206 speex_encoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual);
1208 break;
1209 case SPEEX_SET_COMPLEXITY:
1210 speex_encoder_ctl(st->st_low, SPEEX_SET_COMPLEXITY, ptr);
1211 st->complexity = (*(spx_int32_t*)ptr);
1212 if (st->complexity<1)
1213 st->complexity=1;
1214 break;
1215 case SPEEX_GET_COMPLEXITY:
1216 (*(spx_int32_t*)ptr) = st->complexity;
1217 break;
1218 case SPEEX_SET_BITRATE:
1220 spx_int32_t i=10;
1221 spx_int32_t rate, target;
1222 target = (*(spx_int32_t*)ptr);
1223 while (i>=0)
1225 speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
1226 speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
1227 if (rate <= target)
1228 break;
1229 i--;
1232 break;
1233 case SPEEX_GET_BITRATE:
1234 speex_encoder_ctl(st->st_low, request, ptr);
1235 /*fprintf (stderr, "before: %d\n", (*(int*)ptr));*/
1236 if (st->submodes[st->submodeID])
1237 (*(spx_int32_t*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size;
1238 else
1239 (*(spx_int32_t*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size;
1240 /*fprintf (stderr, "after: %d\n", (*(int*)ptr));*/
1241 break;
1242 case SPEEX_SET_SAMPLING_RATE:
1244 spx_int32_t tmp=(*(spx_int32_t*)ptr);
1245 st->sampling_rate = tmp;
1246 tmp>>=1;
1247 speex_encoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp);
1249 break;
1250 case SPEEX_GET_SAMPLING_RATE:
1251 (*(spx_int32_t*)ptr)=st->sampling_rate;
1252 break;
1253 case SPEEX_RESET_STATE:
1255 int i;
1256 st->first = 1;
1257 for (i=0;i<st->lpcSize;i++)
1258 st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
1259 for (i=0;i<st->lpcSize;i++)
1260 st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0;
1261 for (i=0;i<QMF_ORDER;i++)
1262 st->h0_mem[i]=st->h1_mem[i]=0;
1264 break;
1265 case SPEEX_SET_SUBMODE_ENCODING:
1266 st->encode_submode = (*(spx_int32_t*)ptr);
1267 speex_encoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, ptr);
1268 break;
1269 case SPEEX_GET_SUBMODE_ENCODING:
1270 (*(spx_int32_t*)ptr) = st->encode_submode;
1271 break;
1272 case SPEEX_GET_LOOKAHEAD:
1273 speex_encoder_ctl(st->st_low, SPEEX_GET_LOOKAHEAD, ptr);
1274 (*(spx_int32_t*)ptr) = 2*(*(spx_int32_t*)ptr) + QMF_ORDER - 1;
1275 break;
1276 case SPEEX_SET_PLC_TUNING:
1277 speex_encoder_ctl(st->st_low, SPEEX_SET_PLC_TUNING, ptr);
1278 break;
1279 case SPEEX_GET_PLC_TUNING:
1280 speex_encoder_ctl(st->st_low, SPEEX_GET_PLC_TUNING, ptr);
1281 break;
1282 #ifndef DISABLE_VBR
1283 case SPEEX_SET_VBR_MAX_BITRATE:
1285 st->vbr_max = (*(spx_int32_t*)ptr);
1286 if (SPEEX_SET_VBR_MAX_BITRATE<1)
1288 speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_MAX_BITRATE, &st->vbr_max);
1289 st->vbr_max_high = 17600;
1290 } else {
1291 spx_int32_t low_rate;
1292 if (st->vbr_max >= 42200)
1294 st->vbr_max_high = 17600;
1295 } else if (st->vbr_max >= 27800)
1297 st->vbr_max_high = 9600;
1298 } else if (st->vbr_max > 20600)
1300 st->vbr_max_high = 5600;
1301 } else {
1302 st->vbr_max_high = 1800;
1304 if (st->subframeSize==80)
1305 st->vbr_max_high = 1800;
1306 low_rate = st->vbr_max - st->vbr_max_high;
1307 speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_MAX_BITRATE, &low_rate);
1310 break;
1311 case SPEEX_GET_VBR_MAX_BITRATE:
1312 (*(spx_int32_t*)ptr) = st->vbr_max;
1313 break;
1314 #endif /* #ifndef DISABLE_VBR */
1315 case SPEEX_SET_HIGHPASS:
1316 speex_encoder_ctl(st->st_low, SPEEX_SET_HIGHPASS, ptr);
1317 break;
1318 case SPEEX_GET_HIGHPASS:
1319 speex_encoder_ctl(st->st_low, SPEEX_GET_HIGHPASS, ptr);
1320 break;
1323 /* This is all internal stuff past this point */
1324 case SPEEX_GET_PI_GAIN:
1326 int i;
1327 spx_word32_t *g = (spx_word32_t*)ptr;
1328 for (i=0;i<st->nbSubframes;i++)
1329 g[i]=st->pi_gain[i];
1331 break;
1332 case SPEEX_GET_EXC:
1334 int i;
1335 for (i=0;i<st->nbSubframes;i++)
1336 ((spx_word16_t*)ptr)[i] = st->exc_rms[i];
1338 break;
1339 #ifndef DISABLE_VBR
1340 case SPEEX_GET_RELATIVE_QUALITY:
1341 (*(float*)ptr)=st->relative_quality;
1342 break;
1343 #endif /* #ifndef DISABLE_VBR */
1344 case SPEEX_SET_INNOVATION_SAVE:
1345 st->innov_rms_save = (spx_word16_t*)ptr;
1346 break;
1347 case SPEEX_SET_WIDEBAND:
1348 speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr);
1349 break;
1350 case SPEEX_GET_STACK:
1351 *((char**)ptr) = st->stack;
1352 break;
1353 default:
1354 speex_warning_int("Unknown nb_ctl request: ", request);
1355 return -1;
1357 return 0;
1360 int sb_decoder_ctl(void *state, int request, void *ptr)
1362 SBDecState *st;
1363 st=(SBDecState*)state;
1364 switch(request)
1366 case SPEEX_SET_HIGH_MODE:
1367 st->submodeID = (*(spx_int32_t*)ptr);
1368 break;
1369 case SPEEX_SET_LOW_MODE:
1370 speex_decoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr);
1371 break;
1372 case SPEEX_GET_LOW_MODE:
1373 speex_decoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr);
1374 break;
1375 case SPEEX_GET_FRAME_SIZE:
1376 (*(spx_int32_t*)ptr) = st->full_frame_size;
1377 break;
1378 case SPEEX_SET_ENH:
1379 speex_decoder_ctl(st->st_low, request, ptr);
1380 st->lpc_enh_enabled = *((spx_int32_t*)ptr);
1381 break;
1382 case SPEEX_GET_ENH:
1383 *((spx_int32_t*)ptr) = st->lpc_enh_enabled;
1384 break;
1385 case SPEEX_SET_MODE:
1386 case SPEEX_SET_QUALITY:
1388 spx_int32_t nb_qual;
1389 int quality = (*(spx_int32_t*)ptr);
1390 if (quality < 0)
1391 quality = 0;
1392 if (quality > 10)
1393 quality = 10;
1394 st->submodeID = ((const SpeexSBMode*)(st->mode->mode))->quality_map[quality];
1395 nb_qual = ((const SpeexSBMode*)(st->mode->mode))->low_quality_map[quality];
1396 speex_decoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual);
1398 break;
1399 case SPEEX_GET_BITRATE:
1400 speex_decoder_ctl(st->st_low, request, ptr);
1401 if (st->submodes[st->submodeID])
1402 (*(spx_int32_t*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size;
1403 else
1404 (*(spx_int32_t*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size;
1405 break;
1406 case SPEEX_SET_SAMPLING_RATE:
1408 spx_int32_t tmp=(*(spx_int32_t*)ptr);
1409 st->sampling_rate = tmp;
1410 tmp>>=1;
1411 speex_decoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp);
1413 break;
1414 case SPEEX_GET_SAMPLING_RATE:
1415 (*(spx_int32_t*)ptr)=st->sampling_rate;
1416 break;
1417 case SPEEX_SET_HANDLER:
1418 speex_decoder_ctl(st->st_low, SPEEX_SET_HANDLER, ptr);
1419 break;
1420 case SPEEX_SET_USER_HANDLER:
1421 speex_decoder_ctl(st->st_low, SPEEX_SET_USER_HANDLER, ptr);
1422 break;
1423 case SPEEX_RESET_STATE:
1425 int i;
1426 for (i=0;i<2*st->lpcSize;i++)
1427 st->mem_sp[i]=0;
1428 for (i=0;i<QMF_ORDER;i++)
1429 st->g0_mem[i]=st->g1_mem[i]=0;
1430 st->last_ener=0;
1432 break;
1433 case SPEEX_SET_SUBMODE_ENCODING:
1434 st->encode_submode = (*(spx_int32_t*)ptr);
1435 speex_decoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, ptr);
1436 break;
1437 case SPEEX_GET_SUBMODE_ENCODING:
1438 (*(spx_int32_t*)ptr) = st->encode_submode;
1439 break;
1440 case SPEEX_GET_LOOKAHEAD:
1441 speex_decoder_ctl(st->st_low, SPEEX_GET_LOOKAHEAD, ptr);
1442 (*(spx_int32_t*)ptr) = 2*(*(spx_int32_t*)ptr);
1443 break;
1444 case SPEEX_SET_HIGHPASS:
1445 speex_decoder_ctl(st->st_low, SPEEX_SET_HIGHPASS, ptr);
1446 break;
1447 case SPEEX_GET_HIGHPASS:
1448 speex_decoder_ctl(st->st_low, SPEEX_GET_HIGHPASS, ptr);
1449 break;
1450 case SPEEX_GET_ACTIVITY:
1451 speex_decoder_ctl(st->st_low, SPEEX_GET_ACTIVITY, ptr);
1452 break;
1453 case SPEEX_GET_PI_GAIN:
1455 int i;
1456 spx_word32_t *g = (spx_word32_t*)ptr;
1457 for (i=0;i<st->nbSubframes;i++)
1458 g[i]=st->pi_gain[i];
1460 break;
1461 case SPEEX_GET_EXC:
1463 int i;
1464 for (i=0;i<st->nbSubframes;i++)
1465 ((spx_word16_t*)ptr)[i] = st->exc_rms[i];
1467 break;
1468 case SPEEX_GET_DTX_STATUS:
1469 speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, ptr);
1470 break;
1471 case SPEEX_SET_INNOVATION_SAVE:
1472 st->innov_save = (spx_word16_t*)ptr;
1473 break;
1474 case SPEEX_SET_WIDEBAND:
1475 speex_decoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr);
1476 break;
1477 case SPEEX_GET_STACK:
1478 *((char**)ptr) = st->stack;
1479 break;
1480 default:
1481 speex_warning_int("Unknown nb_ctl request: ", request);
1482 return -1;
1484 return 0;
1487 #endif