summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libspeex/nb_celp.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libspeex/nb_celp.c')
-rw-r--r--lib/rbcodec/codecs/libspeex/nb_celp.c1917
1 files changed, 1917 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libspeex/nb_celp.c b/lib/rbcodec/codecs/libspeex/nb_celp.c
new file mode 100644
index 0000000000..364f987472
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/nb_celp.c
@@ -0,0 +1,1917 @@
1/* Copyright (C) 2002-2006 Jean-Marc Valin
2 File: nb_celp.c
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
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.
14
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.
18
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.
30*/
31
32#ifdef HAVE_CONFIG_H
33#include "config-speex.h"
34#endif
35
36#include <math.h>
37#include "nb_celp.h"
38#include "lpc.h"
39#include "lsp.h"
40#include "ltp.h"
41#include "quant_lsp.h"
42#include "cb_search.h"
43#include "filters.h"
44#include "stack_alloc.h"
45#include "vq.h"
46#include "speex/speex_bits.h"
47#include "vbr.h"
48#include "arch.h"
49#include "math_approx.h"
50#include "os_support.h"
51#include "speex/speex_callbacks.h"
52
53#ifdef VORBIS_PSYCHO
54#include "vorbis_psy.h"
55#endif
56
57#ifndef M_PI
58#define M_PI 3.14159265358979323846 /* pi */
59#endif
60
61#ifndef NULL
62#define NULL 0
63#endif
64
65#define SUBMODE(x) st->submodes[st->submodeID]->x
66
67/* Default size for the encoder and decoder stack (can be changed at compile time).
68 This does not apply when using variable-size arrays or alloca. */
69#ifndef NB_ENC_STACK
70#define NB_ENC_STACK (8000*sizeof(spx_sig_t))
71#endif
72
73#ifndef NB_DEC_STACK
74#define NB_DEC_STACK (4000*sizeof(spx_sig_t))
75#endif
76
77
78#ifdef FIXED_POINT
79const spx_word32_t ol_gain_table[32] ICONST_ATTR = {18900, 25150, 33468, 44536, 59265, 78865, 104946, 139653, 185838, 247297, 329081, 437913, 582736, 775454, 1031906, 1373169, 1827293, 2431601, 3235761, 4305867, 5729870, 7624808, 10146425, 13501971, 17967238, 23909222, 31816294, 42338330, 56340132, 74972501, 99766822, 132760927};
80const spx_word16_t exc_gain_quant_scal3_bound[7] ICONST_ATTR = {1841, 3883, 6051, 8062, 10444, 13580, 18560};
81const spx_word16_t exc_gain_quant_scal3[8] ICONST_ATTR = {1002, 2680, 5086, 7016, 9108, 11781, 15380, 21740};
82const spx_word16_t exc_gain_quant_scal1_bound[1] ICONST_ATTR = {14385};
83const spx_word16_t exc_gain_quant_scal1[2] ICONST_ATTR = {11546, 17224};
84
85#define LSP_MARGIN 16
86#define LSP_DELTA1 6553
87#define LSP_DELTA2 1638
88
89#else
90
91const float exc_gain_quant_scal3_bound[7]={0.112338f, 0.236980f, 0.369316f, 0.492054f, 0.637471f, 0.828874f, 1.132784f};
92const float exc_gain_quant_scal3[8]={0.061130f, 0.163546f, 0.310413f, 0.428220f, 0.555887f, 0.719055f, 0.938694f, 1.326874f};
93const float exc_gain_quant_scal1_bound[1]={0.87798f};
94const float exc_gain_quant_scal1[2]={0.70469f, 1.05127f};
95
96#define LSP_MARGIN .002f
97#define LSP_DELTA1 .2f
98#define LSP_DELTA2 .05f
99
100#endif
101
102#ifdef VORBIS_PSYCHO
103#define EXTRA_BUFFER 100
104#else
105#define EXTRA_BUFFER 0
106#endif
107
108
109#define sqr(x) ((x)*(x))
110
111extern const spx_word16_t lag_window[];
112extern const spx_word16_t lpc_window[];
113
114#ifndef SPEEX_DISABLE_ENCODER
115void *nb_encoder_init(const SpeexMode *m)
116{
117 EncState *st;
118 const SpeexNBMode *mode;
119 int i;
120
121 mode=(const SpeexNBMode *)m->mode;
122 st = (EncState*)speex_alloc(sizeof(EncState));
123 if (!st)
124 return NULL;
125#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
126 st->stack = NULL;
127#else
128 st->stack = (char*)speex_alloc_scratch(NB_ENC_STACK);
129#endif
130
131 st->mode=m;
132
133 st->frameSize = mode->frameSize;
134 st->nbSubframes=mode->frameSize/mode->subframeSize;
135 st->subframeSize=mode->subframeSize;
136 st->windowSize = st->frameSize+st->subframeSize;
137 st->lpcSize = mode->lpcSize;
138 st->gamma1=mode->gamma1;
139 st->gamma2=mode->gamma2;
140 st->min_pitch=mode->pitchStart;
141 st->max_pitch=mode->pitchEnd;
142 st->lpc_floor = mode->lpc_floor;
143
144 st->submodes=mode->submodes;
145 st->submodeID=st->submodeSelect=mode->defaultSubmode;
146 st->bounded_pitch = 1;
147
148 st->encode_submode = 1;
149
150#ifdef VORBIS_PSYCHO
151 st->psy = vorbis_psy_init(8000, 256);
152 st->curve = (float*)speex_alloc(128*sizeof(float));
153 st->old_curve = (float*)speex_alloc(128*sizeof(float));
154 st->psy_window = (float*)speex_alloc(256*sizeof(float));
155#endif
156
157 st->cumul_gain = 1024;
158
159 /* Allocating input buffer */
160 st->winBuf = (spx_word16_t*)speex_alloc((st->windowSize-st->frameSize)*sizeof(spx_word16_t));
161 /* Allocating excitation buffer */
162 st->excBuf = (spx_word16_t*)speex_alloc((mode->frameSize+mode->pitchEnd+2)*sizeof(spx_word16_t));
163 st->exc = st->excBuf + mode->pitchEnd + 2;
164 st->swBuf = (spx_word16_t*)speex_alloc((mode->frameSize+mode->pitchEnd+2)*sizeof(spx_word16_t));
165 st->sw = st->swBuf + mode->pitchEnd + 2;
166
167 st->window= lpc_window;
168
169 /* Create the window for autocorrelation (lag-windowing) */
170 st->lagWindow = lag_window;
171
172 st->old_lsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
173 st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
174 st->first = 1;
175 for (i=0;i<st->lpcSize;i++)
176 st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
177
178 st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
179 st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
180 st->mem_sw_whole = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
181 st->mem_exc = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
182 st->mem_exc2 = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
183
184 st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));
185 st->innov_rms_save = NULL;
186
187 st->pitch = (int*)speex_alloc((st->nbSubframes)*sizeof(int));
188
189#ifndef DISABLE_VBR
190 st->vbr = (VBRState*)speex_alloc(sizeof(VBRState));
191 vbr_init(st->vbr);
192 st->vbr_quality = 8;
193 st->vbr_enabled = 0;
194 st->vbr_max = 0;
195 st->vad_enabled = 0;
196 st->dtx_enabled = 0;
197 st->dtx_count=0;
198 st->abr_enabled = 0;
199 st->abr_drift = 0;
200 st->abr_drift2 = 0;
201#endif /* #ifndef DISABLE_VBR */
202
203 st->plc_tuning = 2;
204 st->complexity=2;
205 st->sampling_rate=8000;
206 st->isWideband = 0;
207 st->highpass_enabled = 1;
208
209#ifdef ENABLE_VALGRIND
210 VALGRIND_MAKE_READABLE(st, NB_ENC_STACK);
211#endif
212 return st;
213}
214
215void nb_encoder_destroy(void *state)
216{
217 EncState *st=(EncState *)state;
218 /* Free all allocated memory */
219#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
220 speex_free_scratch(st->stack);
221#endif
222
223 speex_free (st->winBuf);
224 speex_free (st->excBuf);
225 speex_free (st->old_qlsp);
226 speex_free (st->swBuf);
227
228 speex_free (st->old_lsp);
229 speex_free (st->mem_sp);
230 speex_free (st->mem_sw);
231 speex_free (st->mem_sw_whole);
232 speex_free (st->mem_exc);
233 speex_free (st->mem_exc2);
234 speex_free (st->pi_gain);
235 speex_free (st->pitch);
236
237#ifndef DISABLE_VBR
238 vbr_destroy(st->vbr);
239 speex_free (st->vbr);
240#endif /* #ifndef DISABLE_VBR */
241
242#ifdef VORBIS_PSYCHO
243 vorbis_psy_destroy(st->psy);
244 speex_free (st->curve);
245 speex_free (st->old_curve);
246 speex_free (st->psy_window);
247#endif
248
249 /*Free state memory... should be last*/
250 speex_free(st);
251}
252
253int nb_encode(void *state, void *vin, SpeexBits *bits)
254{
255 EncState *st;
256 int i, sub, roots;
257 int ol_pitch;
258 spx_word16_t ol_pitch_coef;
259 spx_word32_t ol_gain;
260 VARDECL(spx_word16_t *ringing);
261 VARDECL(spx_word16_t *target);
262 VARDECL(spx_sig_t *innov);
263 VARDECL(spx_word32_t *exc32);
264 VARDECL(spx_mem_t *mem);
265 VARDECL(spx_coef_t *bw_lpc1);
266 VARDECL(spx_coef_t *bw_lpc2);
267 VARDECL(spx_coef_t *lpc);
268 VARDECL(spx_lsp_t *lsp);
269 VARDECL(spx_lsp_t *qlsp);
270 VARDECL(spx_lsp_t *interp_lsp);
271 VARDECL(spx_lsp_t *interp_qlsp);
272 VARDECL(spx_coef_t *interp_lpc);
273 VARDECL(spx_coef_t *interp_qlpc);
274 char *stack;
275 VARDECL(spx_word16_t *syn_resp);
276 VARDECL(spx_word16_t *real_exc);
277
278 spx_word32_t ener=0;
279 spx_word16_t fine_gain;
280 spx_word16_t *in = (spx_word16_t*)vin;
281
282 st=(EncState *)state;
283 stack=st->stack;
284
285 ALLOC(lpc, st->lpcSize, spx_coef_t);
286 ALLOC(bw_lpc1, st->lpcSize, spx_coef_t);
287 ALLOC(bw_lpc2, st->lpcSize, spx_coef_t);
288 ALLOC(lsp, st->lpcSize, spx_lsp_t);
289 ALLOC(qlsp, st->lpcSize, spx_lsp_t);
290 ALLOC(interp_lsp, st->lpcSize, spx_lsp_t);
291 ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);
292 ALLOC(interp_lpc, st->lpcSize, spx_coef_t);
293 ALLOC(interp_qlpc, st->lpcSize, spx_coef_t);
294
295 /* Move signals 1 frame towards the past */
296 SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, st->max_pitch+2);
297 SPEEX_MOVE(st->swBuf, st->swBuf+st->frameSize, st->max_pitch+2);
298
299 if (st->highpass_enabled)
300 highpass(in, in, st->frameSize, (st->isWideband?HIGHPASS_WIDEBAND:HIGHPASS_NARROWBAND)|HIGHPASS_INPUT, st->mem_hp);
301
302 {
303 VARDECL(spx_word16_t *w_sig);
304 VARDECL(spx_word16_t *autocorr);
305 ALLOC(w_sig, st->windowSize, spx_word16_t);
306 ALLOC(autocorr, st->lpcSize+1, spx_word16_t);
307 /* Window for analysis */
308 for (i=0;i<st->windowSize-st->frameSize;i++)
309 w_sig[i] = EXTRACT16(SHR32(MULT16_16(st->winBuf[i],st->window[i]),SIG_SHIFT));
310 for (;i<st->windowSize;i++)
311 w_sig[i] = EXTRACT16(SHR32(MULT16_16(in[i-st->windowSize+st->frameSize],st->window[i]),SIG_SHIFT));
312 /* Compute auto-correlation */
313 _spx_autocorr(w_sig, autocorr, st->lpcSize+1, st->windowSize);
314 autocorr[0] = ADD16(autocorr[0],MULT16_16_Q15(autocorr[0],st->lpc_floor)); /* Noise floor in auto-correlation domain */
315
316 /* Lag windowing: equivalent to filtering in the power-spectrum domain */
317 for (i=0;i<st->lpcSize+1;i++)
318 autocorr[i] = MULT16_16_Q14(autocorr[i],st->lagWindow[i]);
319
320 /* Levinson-Durbin */
321 _spx_lpc(lpc, autocorr, st->lpcSize);
322 /* LPC to LSPs (x-domain) transform */
323 roots=lpc_to_lsp (lpc, st->lpcSize, lsp, 10, LSP_DELTA1, stack);
324 /* Check if we found all the roots */
325 if (roots!=st->lpcSize)
326 {
327 /*If we can't find all LSP's, do some damage control and use previous filter*/
328 for (i=0;i<st->lpcSize;i++)
329 {
330 lsp[i]=st->old_lsp[i];
331 }
332 }
333 }
334
335
336
337
338 /* Whole frame analysis (open-loop estimation of pitch and excitation gain) */
339 {
340 int diff = st->windowSize-st->frameSize;
341 if (st->first)
342 for (i=0;i<st->lpcSize;i++)
343 interp_lsp[i] = lsp[i];
344 else
345 lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, st->nbSubframes, st->nbSubframes<<1);
346
347 lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN);
348
349 /* Compute interpolated LPCs (unquantized) for whole frame*/
350 lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack);
351
352
353 /*Open-loop pitch*/
354 if (!st->submodes[st->submodeID] || (st->complexity>2 && SUBMODE(have_subframe_gain)<3) || SUBMODE(forced_pitch_gain) || SUBMODE(lbr_pitch) != -1
355#ifndef DISABLE_VBR
356 || st->vbr_enabled || st->vad_enabled
357#endif
358 )
359 {
360 int nol_pitch[6];
361 spx_word16_t nol_pitch_coef[6];
362
363 bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize);
364 bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize);
365
366 SPEEX_COPY(st->sw, st->winBuf, diff);
367 SPEEX_COPY(st->sw+diff, in, st->frameSize-diff);
368 filter_mem16(st->sw, bw_lpc1, bw_lpc2, st->sw, st->frameSize, st->lpcSize, st->mem_sw_whole, stack);
369
370 open_loop_nbest_pitch(st->sw, st->min_pitch, st->max_pitch, st->frameSize,
371 nol_pitch, nol_pitch_coef, 6, stack);
372 ol_pitch=nol_pitch[0];
373 ol_pitch_coef = nol_pitch_coef[0];
374 /*Try to remove pitch multiples*/
375 for (i=1;i<6;i++)
376 {
377#ifdef FIXED_POINT
378 if ((nol_pitch_coef[i]>MULT16_16_Q15(nol_pitch_coef[0],27853)) &&
379#else
380 if ((nol_pitch_coef[i]>.85*nol_pitch_coef[0]) &&
381#endif
382 (ABS(2*nol_pitch[i]-ol_pitch)<=2 || ABS(3*nol_pitch[i]-ol_pitch)<=3 ||
383 ABS(4*nol_pitch[i]-ol_pitch)<=4 || ABS(5*nol_pitch[i]-ol_pitch)<=5))
384 {
385 /*ol_pitch_coef=nol_pitch_coef[i];*/
386 ol_pitch = nol_pitch[i];
387 }
388 }
389 /*if (ol_pitch>50)
390 ol_pitch/=2;*/
391 /*ol_pitch_coef = sqrt(ol_pitch_coef);*/
392
393 } else {
394 ol_pitch=0;
395 ol_pitch_coef=0;
396 }
397
398 /*Compute "real" excitation*/
399 SPEEX_COPY(st->exc, st->winBuf, diff);
400 SPEEX_COPY(st->exc+diff, in, st->frameSize-diff);
401 fir_mem16(st->exc, interp_lpc, st->exc, st->frameSize, st->lpcSize, st->mem_exc, stack);
402
403 /* Compute open-loop excitation gain */
404 {
405 spx_word16_t g = compute_rms16(st->exc, st->frameSize);
406 if (st->submodeID!=1 && ol_pitch>0)
407 ol_gain = MULT16_16(g, MULT16_16_Q14(QCONST16(1.1,14),
408 spx_sqrt(QCONST32(1.,28)-MULT16_32_Q15(QCONST16(.8,15),SHL32(MULT16_16(ol_pitch_coef,ol_pitch_coef),16)))));
409 else
410 ol_gain = SHL32(EXTEND32(g),SIG_SHIFT);
411 }
412 }
413
414#ifdef VORBIS_PSYCHO
415 SPEEX_MOVE(st->psy_window, st->psy_window+st->frameSize, 256-st->frameSize);
416 SPEEX_COPY(&st->psy_window[256-st->frameSize], in, st->frameSize);
417 compute_curve(st->psy, st->psy_window, st->curve);
418 /*print_vec(st->curve, 128, "curve");*/
419 if (st->first)
420 SPEEX_COPY(st->old_curve, st->curve, 128);
421#endif
422
423 /*VBR stuff*/
424#ifndef DISABLE_VBR
425 if (st->vbr && (st->vbr_enabled||st->vad_enabled))
426 {
427 float lsp_dist=0;
428 for (i=0;i<st->lpcSize;i++)
429 lsp_dist += (st->old_lsp[i] - lsp[i])*(st->old_lsp[i] - lsp[i]);
430 lsp_dist /= LSP_SCALING*LSP_SCALING;
431
432 if (st->abr_enabled)
433 {
434 float qual_change=0;
435 if (st->abr_drift2 * st->abr_drift > 0)
436 {
437 /* Only adapt if long-term and short-term drift are the same sign */
438 qual_change = -.00001*st->abr_drift/(1+st->abr_count);
439 if (qual_change>.05)
440 qual_change=.05;
441 if (qual_change<-.05)
442 qual_change=-.05;
443 }
444 st->vbr_quality += qual_change;
445 if (st->vbr_quality>10)
446 st->vbr_quality=10;
447 if (st->vbr_quality<0)
448 st->vbr_quality=0;
449 }
450
451 st->relative_quality = vbr_analysis(st->vbr, in, st->frameSize, ol_pitch, GAIN_SCALING_1*ol_pitch_coef);
452 /*if (delta_qual<0)*/
453 /* delta_qual*=.1*(3+st->vbr_quality);*/
454 if (st->vbr_enabled)
455 {
456 spx_int32_t mode;
457 int choice=0;
458 float min_diff=100;
459 mode = 8;
460 while (mode)
461 {
462 int v1;
463 float thresh;
464 v1=(int)floor(st->vbr_quality);
465 if (v1==10)
466 thresh = vbr_nb_thresh[mode][v1];
467 else
468 thresh = (st->vbr_quality-v1)*vbr_nb_thresh[mode][v1+1] + (1+v1-st->vbr_quality)*vbr_nb_thresh[mode][v1];
469 if (st->relative_quality > thresh &&
470 st->relative_quality-thresh<min_diff)
471 {
472 choice = mode;
473 min_diff = st->relative_quality-thresh;
474 }
475 mode--;
476 }
477 mode=choice;
478 if (mode==0)
479 {
480 if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20)
481 {
482 mode=1;
483 st->dtx_count=1;
484 } else {
485 mode=0;
486 st->dtx_count++;
487 }
488 } else {
489 st->dtx_count=0;
490 }
491
492 speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);
493 if (st->vbr_max>0)
494 {
495 spx_int32_t rate;
496 speex_encoder_ctl(state, SPEEX_GET_BITRATE, &rate);
497 if (rate > st->vbr_max)
498 {
499 rate = st->vbr_max;
500 speex_encoder_ctl(state, SPEEX_SET_BITRATE, &rate);
501 }
502 }
503
504 if (st->abr_enabled)
505 {
506 spx_int32_t bitrate;
507 speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate);
508 st->abr_drift+=(bitrate-st->abr_enabled);
509 st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled);
510 st->abr_count += 1.0;
511 }
512
513 } else {
514 /*VAD only case*/
515 int mode;
516 if (st->relative_quality<2)
517 {
518 if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20)
519 {
520 st->dtx_count=1;
521 mode=1;
522 } else {
523 mode=0;
524 st->dtx_count++;
525 }
526 } else {
527 st->dtx_count = 0;
528 mode=st->submodeSelect;
529 }
530 /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/
531 st->submodeID=mode;
532 }
533 } else {
534 st->relative_quality = -1;
535 }
536#endif /* #ifndef DISABLE_VBR */
537
538 if (st->encode_submode)
539 {
540 /* First, transmit a zero for narrowband */
541 speex_bits_pack(bits, 0, 1);
542
543 /* Transmit the sub-mode we use for this frame */
544 speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS);
545
546 }
547
548 /* If null mode (no transmission), just set a couple things to zero*/
549 if (st->submodes[st->submodeID] == NULL)
550 {
551 for (i=0;i<st->frameSize;i++)
552 st->exc[i]=st->sw[i]=VERY_SMALL;
553
554 for (i=0;i<st->lpcSize;i++)
555 st->mem_sw[i]=0;
556 st->first=1;
557 st->bounded_pitch = 1;
558
559 SPEEX_COPY(st->winBuf, in+2*st->frameSize-st->windowSize, st->windowSize-st->frameSize);
560
561 /* Clear memory (no need to really compute it) */
562 for (i=0;i<st->lpcSize;i++)
563 st->mem_sp[i] = 0;
564 return 0;
565
566 }
567
568 /* LSP Quantization */
569 if (st->first)
570 {
571 for (i=0;i<st->lpcSize;i++)
572 st->old_lsp[i] = lsp[i];
573 }
574
575
576 /*Quantize LSPs*/
577#if 1 /*0 for unquantized*/
578 SUBMODE(lsp_quant)(lsp, qlsp, st->lpcSize, bits);
579#else
580 for (i=0;i<st->lpcSize;i++)
581 qlsp[i]=lsp[i];
582#endif
583
584 /*If we use low bit-rate pitch mode, transmit open-loop pitch*/
585 if (SUBMODE(lbr_pitch)!=-1)
586 {
587 speex_bits_pack(bits, ol_pitch-st->min_pitch, 7);
588 }
589
590 if (SUBMODE(forced_pitch_gain))
591 {
592 int quant;
593 /* This just damps the pitch a bit, because it tends to be too aggressive when forced */
594 ol_pitch_coef = MULT16_16_Q15(QCONST16(.9,15), ol_pitch_coef);
595#ifdef FIXED_POINT
596 quant = PSHR16(MULT16_16_16(15, ol_pitch_coef),GAIN_SHIFT);
597#else
598 quant = (int)floor(.5+15*ol_pitch_coef*GAIN_SCALING_1);
599#endif
600 if (quant>15)
601 quant=15;
602 if (quant<0)
603 quant=0;
604 speex_bits_pack(bits, quant, 4);
605 ol_pitch_coef=MULT16_16_P15(QCONST16(0.066667,15),SHL16(quant,GAIN_SHIFT));
606 }
607
608
609 /*Quantize and transmit open-loop excitation gain*/
610#ifdef FIXED_POINT
611 {
612 int qe = scal_quant32(ol_gain, ol_gain_table, 32);
613 /*ol_gain = exp(qe/3.5)*SIG_SCALING;*/
614 ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]);
615 speex_bits_pack(bits, qe, 5);
616 }
617#else
618 {
619 int qe = (int)(floor(.5+3.5*log(ol_gain*1.0/SIG_SCALING)));
620 if (qe<0)
621 qe=0;
622 if (qe>31)
623 qe=31;
624 ol_gain = exp(qe/3.5)*SIG_SCALING;
625 speex_bits_pack(bits, qe, 5);
626 }
627#endif
628
629
630
631 /* Special case for first frame */
632 if (st->first)
633 {
634 for (i=0;i<st->lpcSize;i++)
635 st->old_qlsp[i] = qlsp[i];
636 }
637
638 /* Target signal */
639 ALLOC(target, st->subframeSize, spx_word16_t);
640 ALLOC(innov, st->subframeSize, spx_sig_t);
641 ALLOC(exc32, st->subframeSize, spx_word32_t);
642 ALLOC(ringing, st->subframeSize, spx_word16_t);
643 ALLOC(syn_resp, st->subframeSize, spx_word16_t);
644 ALLOC(real_exc, st->subframeSize, spx_word16_t);
645 ALLOC(mem, st->lpcSize, spx_mem_t);
646
647 /* Loop on sub-frames */
648 for (sub=0;sub<st->nbSubframes;sub++)
649 {
650 int offset;
651 spx_word16_t *sw;
652 spx_word16_t *exc;
653 int pitch;
654 int response_bound = st->subframeSize;
655
656 /* Offset relative to start of frame */
657 offset = st->subframeSize*sub;
658 /* Excitation */
659 exc=st->exc+offset;
660 /* Weighted signal */
661 sw=st->sw+offset;
662
663 /* LSP interpolation (quantized and unquantized) */
664 lsp_interpolate(st->old_lsp, lsp, interp_lsp, st->lpcSize, sub, st->nbSubframes);
665 lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);
666
667 /* Make sure the filters are stable */
668 lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN);
669 lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);
670
671 /* Compute interpolated LPCs (quantized and unquantized) */
672 lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack);
673
674 lsp_to_lpc(interp_qlsp, interp_qlpc, st->lpcSize, stack);
675
676 /* Compute analysis filter gain at w=pi (for use in SB-CELP) */
677 {
678 spx_word32_t pi_g=LPC_SCALING;
679 for (i=0;i<st->lpcSize;i+=2)
680 {
681 /*pi_g += -st->interp_qlpc[i] + st->interp_qlpc[i+1];*/
682 pi_g = ADD32(pi_g, SUB32(EXTEND32(interp_qlpc[i+1]),EXTEND32(interp_qlpc[i])));
683 }
684 st->pi_gain[sub] = pi_g;
685 }
686
687#ifdef VORBIS_PSYCHO
688 {
689 float curr_curve[128];
690 float fact = ((float)sub+1.0f)/st->nbSubframes;
691 for (i=0;i<128;i++)
692 curr_curve[i] = (1.0f-fact)*st->old_curve[i] + fact*st->curve[i];
693 curve_to_lpc(st->psy, curr_curve, bw_lpc1, bw_lpc2, 10);
694 }
695#else
696 /* Compute bandwidth-expanded (unquantized) LPCs for perceptual weighting */
697 bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize);
698 if (st->gamma2>=0)
699 bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize);
700 else
701 {
702 for (i=0;i<st->lpcSize;i++)
703 bw_lpc2[i]=0;
704 }
705 /*print_vec(st->bw_lpc1, 10, "bw_lpc");*/
706#endif
707
708 /*FIXME: This will break if we change the window size */
709 speex_assert(st->windowSize-st->frameSize == st->subframeSize);
710 if (sub==0)
711 {
712 for (i=0;i<st->subframeSize;i++)
713 real_exc[i] = sw[i] = st->winBuf[i];
714 } else {
715 for (i=0;i<st->subframeSize;i++)
716 real_exc[i] = sw[i] = in[i+((sub-1)*st->subframeSize)];
717 }
718 fir_mem16(real_exc, interp_qlpc, real_exc, st->subframeSize, st->lpcSize, st->mem_exc2, stack);
719
720 if (st->complexity==0)
721 response_bound >>= 1;
722 compute_impulse_response(interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, response_bound, st->lpcSize, stack);
723 for (i=response_bound;i<st->subframeSize;i++)
724 syn_resp[i]=VERY_SMALL;
725
726 /* Compute zero response of A(z/g1) / ( A(z/g2) * A(z) ) */
727 for (i=0;i<st->lpcSize;i++)
728 mem[i]=SHL32(st->mem_sp[i],1);
729 for (i=0;i<st->subframeSize;i++)
730 ringing[i] = VERY_SMALL;
731#ifdef SHORTCUTS2
732 iir_mem16(ringing, interp_qlpc, ringing, response_bound, st->lpcSize, mem, stack);
733 for (i=0;i<st->lpcSize;i++)
734 mem[i]=SHL32(st->mem_sw[i],1);
735 filter_mem16(ringing, st->bw_lpc1, st->bw_lpc2, ringing, response_bound, st->lpcSize, mem, stack);
736 SPEEX_MEMSET(&ringing[response_bound], 0, st->subframeSize-response_bound);
737#else
738 iir_mem16(ringing, interp_qlpc, ringing, st->subframeSize, st->lpcSize, mem, stack);
739 for (i=0;i<st->lpcSize;i++)
740 mem[i]=SHL32(st->mem_sw[i],1);
741 filter_mem16(ringing, bw_lpc1, bw_lpc2, ringing, st->subframeSize, st->lpcSize, mem, stack);
742#endif
743
744 /* Compute weighted signal */
745 for (i=0;i<st->lpcSize;i++)
746 mem[i]=st->mem_sw[i];
747 filter_mem16(sw, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, mem, stack);
748
749 if (st->complexity==0)
750 for (i=0;i<st->lpcSize;i++)
751 st->mem_sw[i]=mem[i];
752
753 /* Compute target signal (saturation prevents overflows on clipped input speech) */
754 for (i=0;i<st->subframeSize;i++)
755 target[i]=EXTRACT16(SATURATE(SUB32(sw[i],PSHR32(ringing[i],1)),32767));
756
757 /* Reset excitation */
758 SPEEX_MEMSET(exc, 0, st->subframeSize);
759
760 /* If we have a long-term predictor (otherwise, something's wrong) */
761 speex_assert (SUBMODE(ltp_quant));
762 {
763 int pit_min, pit_max;
764 /* Long-term prediction */
765 if (SUBMODE(lbr_pitch) != -1)
766 {
767 /* Low bit-rate pitch handling */
768 int margin;
769 margin = SUBMODE(lbr_pitch);
770 if (margin)
771 {
772 if (ol_pitch < st->min_pitch+margin-1)
773 ol_pitch=st->min_pitch+margin-1;
774 if (ol_pitch > st->max_pitch-margin)
775 ol_pitch=st->max_pitch-margin;
776 pit_min = ol_pitch-margin+1;
777 pit_max = ol_pitch+margin;
778 } else {
779 pit_min=pit_max=ol_pitch;
780 }
781 } else {
782 pit_min = st->min_pitch;
783 pit_max = st->max_pitch;
784 }
785
786 /* Force pitch to use only the current frame if needed */
787 if (st->bounded_pitch && pit_max>offset)
788 pit_max=offset;
789
790 /* Perform pitch search */
791 pitch = SUBMODE(ltp_quant)(target, sw, interp_qlpc, bw_lpc1, bw_lpc2,
792 exc32, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef,
793 st->lpcSize, st->subframeSize, bits, stack,
794 exc, syn_resp, st->complexity, 0, st->plc_tuning, &st->cumul_gain);
795
796 st->pitch[sub]=pitch;
797 }
798 /* Quantization of innovation */
799 SPEEX_MEMSET(innov, 0, st->subframeSize);
800
801 /* FIXME: Make sure this is save from overflows (so far so good) */
802 for (i=0;i<st->subframeSize;i++)
803 real_exc[i] = EXTRACT16(SUB32(EXTEND32(real_exc[i]), PSHR32(exc32[i],SIG_SHIFT-1)));
804
805 ener = SHL32(EXTEND32(compute_rms16(real_exc, st->subframeSize)),SIG_SHIFT);
806
807 /*FIXME: Should use DIV32_16 and make sure result fits in 16 bits */
808#ifdef FIXED_POINT
809 {
810 spx_word32_t f = PDIV32(ener,PSHR32(ol_gain,SIG_SHIFT));
811 if (f<=32767)
812 fine_gain = f;
813 else
814 fine_gain = 32767;
815 }
816#else
817 fine_gain = PDIV32_16(ener,PSHR32(ol_gain,SIG_SHIFT));
818#endif
819 /* Calculate gain correction for the sub-frame (if any) */
820 if (SUBMODE(have_subframe_gain))
821 {
822 int qe;
823 if (SUBMODE(have_subframe_gain)==3)
824 {
825 qe = scal_quant(fine_gain, exc_gain_quant_scal3_bound, 8);
826 speex_bits_pack(bits, qe, 3);
827 ener=MULT16_32_Q14(exc_gain_quant_scal3[qe],ol_gain);
828 } else {
829 qe = scal_quant(fine_gain, exc_gain_quant_scal1_bound, 2);
830 speex_bits_pack(bits, qe, 1);
831 ener=MULT16_32_Q14(exc_gain_quant_scal1[qe],ol_gain);
832 }
833 } else {
834 ener=ol_gain;
835 }
836
837 /*printf ("%f %f\n", ener, ol_gain);*/
838
839 /* Normalize innovation */
840 signal_div(target, target, ener, st->subframeSize);
841
842 /* Quantize innovation */
843 speex_assert (SUBMODE(innovation_quant));
844 {
845 /* Codebook search */
846 SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2,
847 SUBMODE(innovation_params), st->lpcSize, st->subframeSize,
848 innov, syn_resp, bits, stack, st->complexity, SUBMODE(double_codebook));
849
850 /* De-normalize innovation and update excitation */
851 signal_mul(innov, innov, ener, st->subframeSize);
852
853 for (i=0;i<st->subframeSize;i++)
854 exc[i] = EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767));
855
856 /* In some (rare) modes, we do a second search (more bits) to reduce noise even more */
857 if (SUBMODE(double_codebook)) {
858 char *tmp_stack=stack;
859 VARDECL(spx_sig_t *innov2);
860 ALLOC(innov2, st->subframeSize, spx_sig_t);
861 SPEEX_MEMSET(innov2, 0, st->subframeSize);
862 for (i=0;i<st->subframeSize;i++)
863 target[i]=MULT16_16_P13(QCONST16(2.2f,13), target[i]);
864 SUBMODE(innovation_quant)(target, interp_qlpc, bw_lpc1, bw_lpc2,
865 SUBMODE(innovation_params), st->lpcSize, st->subframeSize,
866 innov2, syn_resp, bits, stack, st->complexity, 0);
867 signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545f,15),ener), st->subframeSize);
868 for (i=0;i<st->subframeSize;i++)
869 innov[i] = ADD32(innov[i],innov2[i]);
870 stack = tmp_stack;
871 }
872 for (i=0;i<st->subframeSize;i++)
873 exc[i] = EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767));
874 if (st->innov_rms_save)
875 {
876 st->innov_rms_save[sub] = compute_rms(innov, st->subframeSize);
877 }
878 }
879
880 /* Final signal synthesis from excitation */
881 iir_mem16(exc, interp_qlpc, sw, st->subframeSize, st->lpcSize, st->mem_sp, stack);
882
883 /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */
884 if (st->complexity!=0)
885 filter_mem16(sw, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw, stack);
886
887 }
888
889 /* Store the LSPs for interpolation in the next frame */
890 if (st->submodeID>=1)
891 {
892 for (i=0;i<st->lpcSize;i++)
893 st->old_lsp[i] = lsp[i];
894 for (i=0;i<st->lpcSize;i++)
895 st->old_qlsp[i] = qlsp[i];
896 }
897
898#ifdef VORBIS_PSYCHO
899 if (st->submodeID>=1)
900 SPEEX_COPY(st->old_curve, st->curve, 128);
901#endif
902
903 if (st->submodeID==1)
904 {
905#ifndef DISABLE_VBR
906 if (st->dtx_count)
907 speex_bits_pack(bits, 15, 4);
908 else
909#endif
910 speex_bits_pack(bits, 0, 4);
911 }
912
913 /* The next frame will not be the first (Duh!) */
914 st->first = 0;
915 SPEEX_COPY(st->winBuf, in+2*st->frameSize-st->windowSize, st->windowSize-st->frameSize);
916
917 if (SUBMODE(innovation_quant) == noise_codebook_quant || st->submodeID==0)
918 st->bounded_pitch = 1;
919 else
920 st->bounded_pitch = 0;
921
922 return 1;
923}
924#endif /* SPEEX_DISABLE_ENCODER */
925
926static DecState global_decstate IBSS_ATTR;
927
928void *nb_decoder_init(const SpeexMode *m)
929{
930 DecState *st = &global_decstate;
931 const SpeexNBMode *mode;
932 int i;
933
934 mode=(const SpeexNBMode*)m->mode;
935/*
936 st = (DecState *)speex_alloc(sizeof(DecState));
937 if (!st)
938 return NULL;
939*/
940 memset(st, 0, sizeof(*st));
941#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
942 st->stack = NULL;
943#else
944 st->stack = (char*)speex_alloc_scratch(NB_DEC_STACK);
945#endif
946
947 st->mode=m;
948
949
950 st->encode_submode = 1;
951
952 st->first=1;
953 /* Codec parameters, should eventually have several "modes"*/
954 st->frameSize = mode->frameSize;
955 st->nbSubframes=mode->frameSize/mode->subframeSize;
956 st->subframeSize=mode->subframeSize;
957 st->lpcSize = mode->lpcSize;
958 st->min_pitch=mode->pitchStart;
959 st->max_pitch=mode->pitchEnd;
960
961 st->submodes=mode->submodes;
962 st->submodeID=mode->defaultSubmode;
963
964 st->lpc_enh_enabled=1;
965
966 /* st->excBuf = (spx_word16_t*)speex_alloc((st->frameSize + 2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_word16_t)); */
967 st->exc = st->excBuf + 2*st->max_pitch + st->subframeSize + 6;
968 SPEEX_MEMSET(st->excBuf, 0, st->frameSize + st->max_pitch);
969
970 /* st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t)); */
971 /* st->old_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); */
972 /* st->mem_sp = (spx_mem_t*)speex_alloc(st->lpcSize*sizeof(spx_mem_t)); */
973 /* st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t)); */
974 st->last_pitch = 40;
975 st->count_lost=0;
976 st->pitch_gain_buf[0] = st->pitch_gain_buf[1] = st->pitch_gain_buf[2] = 0;
977 st->pitch_gain_buf_idx = 0;
978 st->seed = 1000;
979
980 st->sampling_rate=8000;
981 st->last_ol_gain = 0;
982
983 st->user_callback.func = &speex_default_user_handler;
984 st->user_callback.data = NULL;
985 for (i=0;i<16;i++)
986 st->speex_callbacks[i].func = NULL;
987
988 st->voc_m1=st->voc_m2=st->voc_mean=0;
989 st->voc_offset=0;
990 st->dtx_enabled=0;
991 st->isWideband = 0;
992 st->highpass_enabled = 1;
993
994#ifdef CPU_COLDFIRE
995 coldfire_set_macsr(0); // Integer mode
996#endif
997#ifdef ENABLE_VALGRIND
998 VALGRIND_MAKE_READABLE(st, NB_DEC_STACK);
999#endif
1000 return st;
1001}
1002
1003void nb_decoder_destroy(void *state)
1004{
1005#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
1006 DecState *st;
1007 st=(DecState*)state;
1008 speex_free_scratch(st->stack);
1009#else
1010 (void)state;
1011#endif
1012/*
1013 speex_free (st->excBuf);
1014 speex_free (st->interp_qlpc);
1015 speex_free (st->old_qlsp);
1016 speex_free (st->mem_sp);
1017 speex_free (st->pi_gain);
1018
1019 speex_free(state);
1020*/
1021}
1022
1023#define median3(a, b, c) ((a) < (b) ? ((b) < (c) ? (b) : ((a) < (c) ? (c) : (a))) : ((c) < (b) ? (b) : ((c) < (a) ? (c) : (a))))
1024
1025#ifdef FIXED_POINT
1026const spx_word16_t attenuation[10] = {32767, 31483, 27923, 22861, 17278, 12055, 7764, 4616, 2533, 1283};
1027#else
1028const spx_word16_t attenuation[10] = {1., 0.961, 0.852, 0.698, 0.527, 0.368, 0.237, 0.141, 0.077, 0.039};
1029
1030#endif
1031
1032#ifndef ROCKBOX_VOICE_CODEC
1033static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack)
1034{
1035 int i;
1036 int pitch_val;
1037 spx_word16_t pitch_gain;
1038 spx_word16_t fact;
1039 spx_word16_t gain_med;
1040 spx_word16_t innov_gain;
1041 spx_word16_t noise_gain;
1042
1043 if (st->count_lost<10)
1044 fact = attenuation[st->count_lost];
1045 else
1046 fact = 0;
1047
1048 gain_med = median3(st->pitch_gain_buf[0], st->pitch_gain_buf[1], st->pitch_gain_buf[2]);
1049 if (gain_med < st->last_pitch_gain)
1050 st->last_pitch_gain = gain_med;
1051
1052#ifdef FIXED_POINT
1053 pitch_gain = st->last_pitch_gain;
1054 if (pitch_gain>54)
1055 pitch_gain = 54;
1056 pitch_gain = SHL16(pitch_gain, 9);
1057#else
1058 pitch_gain = GAIN_SCALING_1*st->last_pitch_gain;
1059 if (pitch_gain>.85)
1060 pitch_gain=.85;
1061#endif
1062 pitch_gain = MULT16_16_Q15(fact,pitch_gain) + VERY_SMALL;
1063 /* FIXME: This was rms of innovation (not exc) */
1064 innov_gain = compute_rms16(st->exc, st->frameSize);
1065 noise_gain = MULT16_16_Q15(innov_gain, MULT16_16_Q15(fact, SUB16(Q15ONE,MULT16_16_Q15(pitch_gain,pitch_gain))));
1066 /* Shift all buffers by one frame */
1067 SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, 2*st->max_pitch + st->subframeSize + 12);
1068
1069
1070 pitch_val = st->last_pitch + SHR32((spx_int32_t)speex_rand(1+st->count_lost, &st->seed),SIG_SHIFT);
1071 if (pitch_val > st->max_pitch)
1072 pitch_val = st->max_pitch;
1073 if (pitch_val < st->min_pitch)
1074 pitch_val = st->min_pitch;
1075 for (i=0;i<st->frameSize;i++)
1076 {
1077 st->exc[i]= MULT16_16_Q15(pitch_gain, (st->exc[i-pitch_val]+VERY_SMALL)) +
1078 speex_rand(noise_gain, &st->seed);
1079 }
1080
1081 bw_lpc(QCONST16(.98,15), st->interp_qlpc, st->interp_qlpc, st->lpcSize);
1082 iir_mem16(&st->exc[-st->subframeSize], st->interp_qlpc, out, st->frameSize,
1083 st->lpcSize, st->mem_sp, stack);
1084 highpass(out, out, st->frameSize, HIGHPASS_NARROWBAND|HIGHPASS_OUTPUT, st->mem_hp);
1085
1086 st->first = 0;
1087 st->count_lost++;
1088 st->pitch_gain_buf[st->pitch_gain_buf_idx++] = PSHR16(pitch_gain,9);
1089 if (st->pitch_gain_buf_idx > 2) /* rollover */
1090 st->pitch_gain_buf_idx = 0;
1091}
1092#endif
1093
1094/* Just so we don't need to carry the complete wideband mode information */
1095static const unsigned short wb_skip_table[8] = {0, 36, 112, 192, 352, 0, 0, 0};
1096
1097int nb_decode(void *state, SpeexBits *bits, void *vout)
1098{
1099 DecState *st;
1100 int i, sub;
1101 int pitch;
1102 spx_word16_t pitch_gain[3];
1103 spx_word32_t ol_gain=0;
1104 int ol_pitch=0;
1105 spx_word16_t ol_pitch_coef=0;
1106 int best_pitch=40;
1107 spx_word16_t best_pitch_gain=0;
1108 int wideband;
1109 int m;
1110 char *stack;
1111 VARDECL(spx_sig_t *innov);
1112 VARDECL(spx_word32_t *exc32);
1113 VARDECL(spx_coef_t *ak);
1114 VARDECL(spx_lsp_t *qlsp);
1115 spx_word16_t pitch_average=0;
1116
1117 spx_word16_t *out = (spx_word16_t*)vout;
1118 VARDECL(spx_lsp_t *interp_qlsp);
1119
1120 st=(DecState*)state;
1121 stack=st->stack;
1122
1123 /* Check if we're in DTX mode*/
1124 if (!bits && st->dtx_enabled)
1125 {
1126 st->submodeID=0;
1127 } else
1128 {
1129 /* If bits is NULL, consider the packet to be lost (what could we do anyway) */
1130#ifndef ROCKBOX_VOICE_CODEC
1131 if (!bits)
1132 {
1133 nb_decode_lost(st, out, stack);
1134 return 0;
1135 }
1136#endif
1137
1138 if (st->encode_submode)
1139 {
1140
1141 /* Search for next narrowband block (handle requests, skip wideband blocks) */
1142 do {
1143 if (speex_bits_remaining(bits)<5)
1144 return -1;
1145 wideband = speex_bits_unpack_unsigned(bits, 1);
1146 if (wideband) /* Skip wideband block (for compatibility) */
1147 {
1148 int submode;
1149 int advance;
1150 advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
1151 /*speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);*/
1152 advance = wb_skip_table[submode];
1153 if (advance < 0)
1154 {
1155 speex_notify("Invalid mode encountered. The stream is corrupted.");
1156 return -2;
1157 }
1158 advance -= (SB_SUBMODE_BITS+1);
1159 speex_bits_advance(bits, advance);
1160
1161 if (speex_bits_remaining(bits)<5)
1162 return -1;
1163 wideband = speex_bits_unpack_unsigned(bits, 1);
1164 if (wideband)
1165 {
1166 advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
1167 /*speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);*/
1168 advance = wb_skip_table[submode];
1169 if (advance < 0)
1170 {
1171 speex_notify("Invalid mode encountered. The stream is corrupted.");
1172 return -2;
1173 }
1174 advance -= (SB_SUBMODE_BITS+1);
1175 speex_bits_advance(bits, advance);
1176 wideband = speex_bits_unpack_unsigned(bits, 1);
1177 if (wideband)
1178 {
1179 speex_notify("More than two wideband layers found. The stream is corrupted.");
1180 return -2;
1181 }
1182
1183 }
1184 }
1185 if (speex_bits_remaining(bits)<4)
1186 return -1;
1187 /* FIXME: Check for overflow */
1188 m = speex_bits_unpack_unsigned(bits, 4);
1189 if (m==15) /* We found a terminator */
1190 {
1191 return -1;
1192 } else if (m==14) /* Speex in-band request */
1193 {
1194 int ret = speex_inband_handler(bits, st->speex_callbacks, state);
1195 if (ret)
1196 return ret;
1197 } else if (m==13) /* User in-band request */
1198 {
1199 int ret = st->user_callback.func(bits, state, st->user_callback.data);
1200 if (ret)
1201 return ret;
1202 } else if (m>8) /* Invalid mode */
1203 {
1204 speex_notify("Invalid mode encountered. The stream is corrupted.");
1205 return -2;
1206 }
1207
1208 } while (m>8);
1209
1210 /* Get the sub-mode that was used */
1211 st->submodeID = m;
1212 }
1213
1214 }
1215
1216 /* Shift all buffers by one frame */
1217 SPEEX_MOVE(st->excBuf, st->excBuf+st->frameSize, 2*st->max_pitch + st->subframeSize + 12);
1218
1219 /* If null mode (no transmission), just set a couple things to zero*/
1220 if (st->submodes[st->submodeID] == NULL)
1221 {
1222 VARDECL(spx_coef_t *lpc);
1223 ALLOC(lpc, st->lpcSize, spx_coef_t);
1224 bw_lpc(QCONST16(0.93f,15), st->interp_qlpc, lpc, st->lpcSize);
1225 {
1226 spx_word16_t innov_gain=0;
1227 /* FIXME: This was innov, not exc */
1228 innov_gain = compute_rms16(st->exc, st->frameSize);
1229 for (i=0;i<st->frameSize;i++)
1230 st->exc[i]=speex_rand(innov_gain, &st->seed);
1231 }
1232
1233
1234 st->first=1;
1235
1236 /* Final signal synthesis from excitation */
1237 iir_mem16(st->exc, lpc, out, st->frameSize, st->lpcSize, st->mem_sp, stack);
1238
1239 st->count_lost=0;
1240 return 0;
1241 }
1242
1243 ALLOC(qlsp, st->lpcSize, spx_lsp_t);
1244
1245 /* Unquantize LSPs */
1246 SUBMODE(lsp_unquant)(qlsp, st->lpcSize, bits);
1247
1248 /*Damp memory if a frame was lost and the LSP changed too much*/
1249 if (st->count_lost)
1250 {
1251 spx_word16_t fact;
1252 spx_word32_t lsp_dist=0;
1253 for (i=0;i<st->lpcSize;i++)
1254 lsp_dist = ADD32(lsp_dist, EXTEND32(ABS(st->old_qlsp[i] - qlsp[i])));
1255#ifdef FIXED_POINT
1256 fact = SHR16(19661,SHR32(lsp_dist,LSP_SHIFT+2));
1257#else
1258 fact = .6*exp(-.2*lsp_dist);
1259#endif
1260 for (i=0;i<st->lpcSize;i++)
1261 st->mem_sp[i] = MULT16_32_Q15(fact,st->mem_sp[i]);
1262 }
1263
1264
1265 /* Handle first frame and lost-packet case */
1266 if (st->first || st->count_lost)
1267 {
1268 for (i=0;i<st->lpcSize;i++)
1269 st->old_qlsp[i] = qlsp[i];
1270 }
1271
1272 /* Get open-loop pitch estimation for low bit-rate pitch coding */
1273 if (SUBMODE(lbr_pitch)!=-1)
1274 {
1275 ol_pitch = st->min_pitch+speex_bits_unpack_unsigned(bits, 7);
1276 }
1277
1278 if (SUBMODE(forced_pitch_gain))
1279 {
1280 int quant;
1281 quant = speex_bits_unpack_unsigned(bits, 4);
1282 ol_pitch_coef=MULT16_16_P15(QCONST16(0.066667,15),SHL16(quant,GAIN_SHIFT));
1283 }
1284
1285 /* Get global excitation gain */
1286 {
1287 int qe;
1288 qe = speex_bits_unpack_unsigned(bits, 5);
1289#ifdef FIXED_POINT
1290 /* FIXME: Perhaps we could slightly lower the gain here when the output is going to saturate? */
1291 ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]);
1292#else
1293 ol_gain = SIG_SCALING*exp(qe/3.5);
1294#endif
1295 }
1296
1297 ALLOC(ak, st->lpcSize, spx_coef_t);
1298 ALLOC(innov, st->subframeSize, spx_sig_t);
1299 ALLOC(exc32, st->subframeSize, spx_word32_t);
1300
1301 if (st->submodeID==1)
1302 {
1303 int extra;
1304 extra = speex_bits_unpack_unsigned(bits, 4);
1305
1306 if (extra==15)
1307 st->dtx_enabled=1;
1308 else
1309 st->dtx_enabled=0;
1310 }
1311 if (st->submodeID>1)
1312 st->dtx_enabled=0;
1313
1314 /*Loop on subframes */
1315 for (sub=0;sub<st->nbSubframes;sub++)
1316 {
1317 int offset;
1318 spx_word16_t *exc;
1319 spx_word16_t *innov_save = NULL;
1320 spx_word16_t tmp;
1321
1322 /* Offset relative to start of frame */
1323 offset = st->subframeSize*sub;
1324 /* Excitation */
1325 exc=st->exc+offset;
1326
1327 if (st->innov_save)
1328 innov_save = st->innov_save+offset;
1329
1330
1331 /* Reset excitation */
1332 SPEEX_MEMSET(exc, 0, st->subframeSize);
1333
1334 /*Adaptive codebook contribution*/
1335 speex_assert (SUBMODE(ltp_unquant));
1336 {
1337 int pit_min, pit_max;
1338 /* Handle pitch constraints if any */
1339 if (SUBMODE(lbr_pitch) != -1)
1340 {
1341 int margin;
1342 margin = SUBMODE(lbr_pitch);
1343 if (margin)
1344 {
1345/* GT - need optimization?
1346 if (ol_pitch < st->min_pitch+margin-1)
1347 ol_pitch=st->min_pitch+margin-1;
1348 if (ol_pitch > st->max_pitch-margin)
1349 ol_pitch=st->max_pitch-margin;
1350 pit_min = ol_pitch-margin+1;
1351 pit_max = ol_pitch+margin;
1352*/
1353 pit_min = ol_pitch-margin+1;
1354 if (pit_min < st->min_pitch)
1355 pit_min = st->min_pitch;
1356 pit_max = ol_pitch+margin;
1357 if (pit_max > st->max_pitch)
1358 pit_max = st->max_pitch;
1359 } else {
1360 pit_min = pit_max = ol_pitch;
1361 }
1362 } else {
1363 pit_min = st->min_pitch;
1364 pit_max = st->max_pitch;
1365 }
1366
1367
1368
1369 SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params),
1370 st->subframeSize, &pitch, &pitch_gain[0], bits, stack,
1371 st->count_lost, offset, st->last_pitch_gain, 0);
1372
1373 /* Ensuring that things aren't blowing up as would happen if e.g. an encoder is
1374 crafting packets to make us produce NaNs and slow down the decoder (vague DoS threat).
1375 We can probably be even more aggressive and limit to 15000 or so. */
1376 sanitize_values32(exc32, NEG32(QCONST32(32000,SIG_SHIFT-1)), QCONST32(32000,SIG_SHIFT-1), st->subframeSize);
1377
1378 tmp = gain_3tap_to_1tap(pitch_gain);
1379
1380 pitch_average += tmp;
1381 if ((tmp>best_pitch_gain&&ABS(2*best_pitch-pitch)>=3&&ABS(3*best_pitch-pitch)>=4&&ABS(4*best_pitch-pitch)>=5)
1382 || (tmp>MULT16_16_Q15(QCONST16(.6,15),best_pitch_gain)&&(ABS(best_pitch-2*pitch)<3||ABS(best_pitch-3*pitch)<4||ABS(best_pitch-4*pitch)<5))
1383 || (MULT16_16_Q15(QCONST16(.67,15),tmp)>best_pitch_gain&&(ABS(2*best_pitch-pitch)<3||ABS(3*best_pitch-pitch)<4||ABS(4*best_pitch-pitch)<5)) )
1384 {
1385 best_pitch = pitch;
1386 if (tmp > best_pitch_gain)
1387 best_pitch_gain = tmp;
1388 }
1389 }
1390
1391 /* Unquantize the innovation */
1392 {
1393 int q_energy;
1394 spx_word32_t ener;
1395
1396 SPEEX_MEMSET(innov, 0, st->subframeSize);
1397
1398 /* Decode sub-frame gain correction */
1399 if (SUBMODE(have_subframe_gain)==3)
1400 {
1401 q_energy = speex_bits_unpack_unsigned(bits, 3);
1402 ener = MULT16_32_Q14(exc_gain_quant_scal3[q_energy],ol_gain);
1403 } else if (SUBMODE(have_subframe_gain)==1)
1404 {
1405 q_energy = speex_bits_unpack_unsigned(bits, 1);
1406 ener = MULT16_32_Q14(exc_gain_quant_scal1[q_energy],ol_gain);
1407 } else {
1408 ener = ol_gain;
1409 }
1410
1411 speex_assert (SUBMODE(innovation_unquant));
1412 {
1413 /*Fixed codebook contribution*/
1414 SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed);
1415 /* De-normalize innovation and update excitation */
1416
1417 signal_mul(innov, innov, ener, st->subframeSize);
1418
1419 /* Decode second codebook (only for some modes) */
1420 if (SUBMODE(double_codebook))
1421 {
1422 char *tmp_stack=stack;
1423 VARDECL(spx_sig_t *innov2);
1424 ALLOC(innov2, st->subframeSize, spx_sig_t);
1425 SPEEX_MEMSET(innov2, 0, st->subframeSize);
1426 SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed);
1427 signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545f,15),ener), st->subframeSize);
1428 for (i=0;i<st->subframeSize;i++)
1429 innov[i] = ADD32(innov[i], innov2[i]);
1430 stack = tmp_stack;
1431 }
1432 for (i=0;i<st->subframeSize;i++)
1433 exc[i]=EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767));
1434 /*print_vec(exc, 40, "innov");*/
1435 if (innov_save)
1436 {
1437 for (i=0;i<st->subframeSize;i++)
1438 innov_save[i] = EXTRACT16(PSHR32(innov[i], SIG_SHIFT));
1439 }
1440 }
1441
1442 /*Vocoder mode*/
1443 if (st->submodeID==1)
1444 {
1445 spx_word16_t g=ol_pitch_coef;
1446 g=MULT16_16_P14(QCONST16(1.5f,14),(g-QCONST16(.2f,6)));
1447 if (g<0)
1448 g=0;
1449 if (g>GAIN_SCALING)
1450 g=GAIN_SCALING;
1451
1452 SPEEX_MEMSET(exc, 0, st->subframeSize);
1453 while (st->voc_offset<st->subframeSize)
1454 {
1455 /* exc[st->voc_offset]= g*sqrt(2*ol_pitch)*ol_gain;
1456 Not quite sure why we need the factor of two in the sqrt */
1457 if (st->voc_offset>=0)
1458 exc[st->voc_offset]=MULT16_16(spx_sqrt(MULT16_16_16(2,ol_pitch)),EXTRACT16(PSHR32(MULT16_16(g,PSHR32(ol_gain,SIG_SHIFT)),6)));
1459 st->voc_offset+=ol_pitch;
1460 }
1461 st->voc_offset -= st->subframeSize;
1462
1463 for (i=0;i<st->subframeSize;i++)
1464 {
1465 spx_word16_t exci=exc[i];
1466 exc[i]= ADD16(ADD16(MULT16_16_Q15(QCONST16(.7f,15),exc[i]) , MULT16_16_Q15(QCONST16(.3f,15),st->voc_m1)),
1467 SUB16(MULT16_16_Q15(Q15_ONE-MULT16_16_16(QCONST16(.85f,9),g),EXTRACT16(PSHR32(innov[i],SIG_SHIFT))),
1468 MULT16_16_Q15(MULT16_16_16(QCONST16(.15f,9),g),EXTRACT16(PSHR32(st->voc_m2,SIG_SHIFT)))
1469 ));
1470 st->voc_m1 = exci;
1471 st->voc_m2=innov[i];
1472 st->voc_mean = EXTRACT16(PSHR32(ADD32(MULT16_16(QCONST16(.8f,15),st->voc_mean), MULT16_16(QCONST16(.2f,15),exc[i])), 15));
1473 exc[i]-=st->voc_mean;
1474 }
1475 }
1476
1477 }
1478 }
1479
1480 ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);
1481
1482 if (st->lpc_enh_enabled && SUBMODE(comb_gain)>0 && !st->count_lost)
1483 {
1484 multicomb(st->exc-st->subframeSize, out, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, 40, SUBMODE(comb_gain), stack);
1485 multicomb(st->exc+st->subframeSize, out+2*st->subframeSize, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, best_pitch, 40, SUBMODE(comb_gain), stack);
1486 } else {
1487 SPEEX_COPY(out, &st->exc[-st->subframeSize], st->frameSize);
1488 }
1489
1490 /* If the last packet was lost, re-scale the excitation to obtain the same energy as encoded in ol_gain */
1491 if (st->count_lost)
1492 {
1493 spx_word16_t exc_ener;
1494 spx_word32_t gain32;
1495 spx_word16_t gain;
1496 exc_ener = compute_rms16 (st->exc, st->frameSize);
1497 gain32 = PDIV32(ol_gain, ADD16(exc_ener,1));
1498#ifdef FIXED_POINT
1499 if (gain32 > 32767)
1500 gain32 = 32767;
1501 gain = EXTRACT16(gain32);
1502#else
1503 if (gain32 > 2)
1504 gain32=2;
1505 gain = gain32;
1506#endif
1507 for (i=0;i<st->frameSize;i++)
1508 {
1509 st->exc[i] = MULT16_16_Q14(gain, st->exc[i]);
1510 out[i]=st->exc[i-st->subframeSize];
1511 }
1512 }
1513
1514 /*Loop on subframes */
1515 for (sub=0;sub<st->nbSubframes;sub++)
1516 {
1517 int offset;
1518 spx_word16_t *sp;
1519
1520 /* Offset relative to start of frame */
1521 offset = st->subframeSize*sub;
1522 /* Original signal */
1523 sp=out+offset;
1524
1525 /* LSP interpolation (quantized and unquantized) */
1526 lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);
1527
1528 /* Make sure the LSP's are stable */
1529 lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);
1530
1531 /* Compute interpolated LPCs (unquantized) */
1532 lsp_to_lpc(interp_qlsp, ak, st->lpcSize, stack);
1533
1534 /* Compute analysis filter at w=pi */
1535 {
1536 spx_word32_t pi_g=LPC_SCALING;
1537 for (i=0;i<st->lpcSize;i+=2)
1538 {
1539 /*pi_g += -st->interp_qlpc[i] + st->interp_qlpc[i+1];*/
1540 pi_g = ADD32(pi_g, SUB32(EXTEND32(ak[i+1]),EXTEND32(ak[i])));
1541 }
1542 st->pi_gain[sub] = pi_g;
1543 }
1544
1545 iir_mem16(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize,
1546 st->mem_sp, stack);
1547
1548 for (i=0;i<st->lpcSize;i++)
1549 st->interp_qlpc[i] = ak[i];
1550
1551 }
1552
1553 if (st->highpass_enabled)
1554 highpass(out, out, st->frameSize, (st->isWideband?HIGHPASS_WIDEBAND:HIGHPASS_NARROWBAND)|HIGHPASS_OUTPUT, st->mem_hp);
1555 /*for (i=0;i<st->frameSize;i++)
1556 printf ("%d\n", (int)st->frame[i]);*/
1557
1558 /* Tracking output level */
1559 st->level = 1+PSHR32(ol_gain,SIG_SHIFT);
1560 st->max_level = MAX16(MULT16_16_Q15(QCONST16(.99f,15), st->max_level), st->level);
1561 st->min_level = MIN16(ADD16(1,MULT16_16_Q14(QCONST16(1.01f,14), st->min_level)), st->level);
1562 if (st->max_level < st->min_level+1)
1563 st->max_level = st->min_level+1;
1564 /*printf ("%f %f %f %d\n", og, st->min_level, st->max_level, update);*/
1565
1566 /* Store the LSPs for interpolation in the next frame */
1567 for (i=0;i<st->lpcSize;i++)
1568 st->old_qlsp[i] = qlsp[i];
1569
1570 /* The next frame will not be the first (Duh!) */
1571 st->first = 0;
1572 st->count_lost=0;
1573 st->last_pitch = best_pitch;
1574#ifdef FIXED_POINT
1575 st->last_pitch_gain = PSHR16(pitch_average,2);
1576#else
1577 st->last_pitch_gain = .25*pitch_average;
1578#endif
1579 st->pitch_gain_buf[st->pitch_gain_buf_idx++] = st->last_pitch_gain;
1580 if (st->pitch_gain_buf_idx > 2) /* rollover */
1581 st->pitch_gain_buf_idx = 0;
1582
1583 st->last_ol_gain = ol_gain;
1584
1585 return 0;
1586}
1587
1588#ifndef SPEEX_DISABLE_ENCODER
1589int nb_encoder_ctl(void *state, int request, void *ptr)
1590{
1591 EncState *st;
1592 st=(EncState*)state;
1593 switch(request)
1594 {
1595 case SPEEX_GET_FRAME_SIZE:
1596 (*(spx_int32_t*)ptr) = st->frameSize;
1597 break;
1598 case SPEEX_SET_LOW_MODE:
1599 case SPEEX_SET_MODE:
1600 st->submodeSelect = st->submodeID = (*(spx_int32_t*)ptr);
1601 break;
1602 case SPEEX_GET_LOW_MODE:
1603 case SPEEX_GET_MODE:
1604 (*(spx_int32_t*)ptr) = st->submodeID;
1605 break;
1606#ifndef DISABLE_VBR
1607 case SPEEX_SET_VBR:
1608 st->vbr_enabled = (*(spx_int32_t*)ptr);
1609 break;
1610 case SPEEX_GET_VBR:
1611 (*(spx_int32_t*)ptr) = st->vbr_enabled;
1612 break;
1613 case SPEEX_SET_VAD:
1614 st->vad_enabled = (*(spx_int32_t*)ptr);
1615 break;
1616 case SPEEX_GET_VAD:
1617 (*(spx_int32_t*)ptr) = st->vad_enabled;
1618 break;
1619 case SPEEX_SET_DTX:
1620 st->dtx_enabled = (*(spx_int32_t*)ptr);
1621 break;
1622 case SPEEX_GET_DTX:
1623 (*(spx_int32_t*)ptr) = st->dtx_enabled;
1624 break;
1625 case SPEEX_SET_ABR:
1626 st->abr_enabled = (*(spx_int32_t*)ptr);
1627 st->vbr_enabled = st->abr_enabled!=0;
1628 if (st->vbr_enabled)
1629 {
1630 spx_int32_t i=10;
1631 spx_int32_t rate, target;
1632 float vbr_qual;
1633 target = (*(spx_int32_t*)ptr);
1634 while (i>=0)
1635 {
1636 speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
1637 speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
1638 if (rate <= target)
1639 break;
1640 i--;
1641 }
1642 vbr_qual=i;
1643 if (vbr_qual<0)
1644 vbr_qual=0;
1645 speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual);
1646 st->abr_count=0;
1647 st->abr_drift=0;
1648 st->abr_drift2=0;
1649 }
1650
1651 break;
1652 case SPEEX_GET_ABR:
1653 (*(spx_int32_t*)ptr) = st->abr_enabled;
1654 break;
1655#endif /* #ifndef DISABLE_VBR */
1656#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API)
1657 case SPEEX_SET_VBR_QUALITY:
1658 st->vbr_quality = (*(float*)ptr);
1659 break;
1660 case SPEEX_GET_VBR_QUALITY:
1661 (*(float*)ptr) = st->vbr_quality;
1662 break;
1663#endif /* !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */
1664 case SPEEX_SET_QUALITY:
1665 {
1666 int quality = (*(spx_int32_t*)ptr);
1667 if (quality < 0)
1668 quality = 0;
1669 if (quality > 10)
1670 quality = 10;
1671 st->submodeSelect = st->submodeID = ((const SpeexNBMode*)(st->mode->mode))->quality_map[quality];
1672 }
1673 break;
1674 case SPEEX_SET_COMPLEXITY:
1675 st->complexity = (*(spx_int32_t*)ptr);
1676 if (st->complexity<0)
1677 st->complexity=0;
1678 break;
1679 case SPEEX_GET_COMPLEXITY:
1680 (*(spx_int32_t*)ptr) = st->complexity;
1681 break;
1682 case SPEEX_SET_BITRATE:
1683 {
1684 spx_int32_t i=10;
1685 spx_int32_t rate, target;
1686 target = (*(spx_int32_t*)ptr);
1687 while (i>=0)
1688 {
1689 speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
1690 speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
1691 if (rate <= target)
1692 break;
1693 i--;
1694 }
1695 }
1696 break;
1697 case SPEEX_GET_BITRATE:
1698 if (st->submodes[st->submodeID])
1699 (*(spx_int32_t*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize;
1700 else
1701 (*(spx_int32_t*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize;
1702 break;
1703 case SPEEX_SET_SAMPLING_RATE:
1704 st->sampling_rate = (*(spx_int32_t*)ptr);
1705 break;
1706 case SPEEX_GET_SAMPLING_RATE:
1707 (*(spx_int32_t*)ptr)=st->sampling_rate;
1708 break;
1709 case SPEEX_RESET_STATE:
1710 {
1711 int i;
1712 st->bounded_pitch = 1;
1713 st->first = 1;
1714 for (i=0;i<st->lpcSize;i++)
1715 st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
1716 for (i=0;i<st->lpcSize;i++)
1717 st->mem_sw[i]=st->mem_sw_whole[i]=st->mem_sp[i]=st->mem_exc[i]=0;
1718 for (i=0;i<st->frameSize+st->max_pitch+1;i++)
1719 st->excBuf[i]=st->swBuf[i]=0;
1720 for (i=0;i<st->windowSize-st->frameSize;i++)
1721 st->winBuf[i]=0;
1722 }
1723 break;
1724 case SPEEX_SET_SUBMODE_ENCODING:
1725 st->encode_submode = (*(spx_int32_t*)ptr);
1726 break;
1727 case SPEEX_GET_SUBMODE_ENCODING:
1728 (*(spx_int32_t*)ptr) = st->encode_submode;
1729 break;
1730 case SPEEX_GET_LOOKAHEAD:
1731 (*(spx_int32_t*)ptr)=(st->windowSize-st->frameSize);
1732 break;
1733 case SPEEX_SET_PLC_TUNING:
1734 st->plc_tuning = (*(spx_int32_t*)ptr);
1735 if (st->plc_tuning>100)
1736 st->plc_tuning=100;
1737 break;
1738 case SPEEX_GET_PLC_TUNING:
1739 (*(spx_int32_t*)ptr)=(st->plc_tuning);
1740 break;
1741#ifndef DISABLE_VBR
1742 case SPEEX_SET_VBR_MAX_BITRATE:
1743 st->vbr_max = (*(spx_int32_t*)ptr);
1744 break;
1745 case SPEEX_GET_VBR_MAX_BITRATE:
1746 (*(spx_int32_t*)ptr) = st->vbr_max;
1747 break;
1748#endif /* #ifndef DISABLE_VBR */
1749 case SPEEX_SET_HIGHPASS:
1750 st->highpass_enabled = (*(spx_int32_t*)ptr);
1751 break;
1752 case SPEEX_GET_HIGHPASS:
1753 (*(spx_int32_t*)ptr) = st->highpass_enabled;
1754 break;
1755
1756 /* This is all internal stuff past this point */
1757 case SPEEX_GET_PI_GAIN:
1758 {
1759 int i;
1760 spx_word32_t *g = (spx_word32_t*)ptr;
1761 for (i=0;i<st->nbSubframes;i++)
1762 g[i]=st->pi_gain[i];
1763 }
1764 break;
1765 case SPEEX_GET_EXC:
1766 {
1767 int i;
1768 for (i=0;i<st->nbSubframes;i++)
1769 ((spx_word16_t*)ptr)[i] = compute_rms16(st->exc+i*st->subframeSize, st->subframeSize);
1770 }
1771 break;
1772#ifndef DISABLE_VBR
1773 case SPEEX_GET_RELATIVE_QUALITY:
1774 (*(float*)ptr)=st->relative_quality;
1775 break;
1776#endif /* #ifndef DISABLE_VBR */
1777 case SPEEX_SET_INNOVATION_SAVE:
1778 st->innov_rms_save = (spx_word16_t*)ptr;
1779 break;
1780 case SPEEX_SET_WIDEBAND:
1781 st->isWideband = *((spx_int32_t*)ptr);
1782 break;
1783 case SPEEX_GET_STACK:
1784 *((char**)ptr) = st->stack;
1785 break;
1786 default:
1787 speex_warning_int("Unknown nb_ctl request: ", request);
1788 return -1;
1789 }
1790 return 0;
1791}
1792#endif /* SPEEX_DISABLE_ENCODER */
1793
1794int nb_decoder_ctl(void *state, int request, void *ptr)
1795{
1796 DecState *st;
1797 st=(DecState*)state;
1798 switch(request)
1799 {
1800 case SPEEX_SET_LOW_MODE:
1801 case SPEEX_SET_MODE:
1802 st->submodeID = (*(spx_int32_t*)ptr);
1803 break;
1804 case SPEEX_GET_LOW_MODE:
1805 case SPEEX_GET_MODE:
1806 (*(spx_int32_t*)ptr) = st->submodeID;
1807 break;
1808 case SPEEX_SET_ENH:
1809 st->lpc_enh_enabled = *((spx_int32_t*)ptr);
1810 break;
1811 case SPEEX_GET_ENH:
1812 *((spx_int32_t*)ptr) = st->lpc_enh_enabled;
1813 break;
1814 case SPEEX_GET_FRAME_SIZE:
1815 (*(spx_int32_t*)ptr) = st->frameSize;
1816 break;
1817 case SPEEX_GET_BITRATE:
1818 if (st->submodes[st->submodeID])
1819 (*(spx_int32_t*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize;
1820 else
1821 (*(spx_int32_t*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize;
1822 break;
1823 case SPEEX_SET_SAMPLING_RATE:
1824 st->sampling_rate = (*(spx_int32_t*)ptr);
1825 break;
1826 case SPEEX_GET_SAMPLING_RATE:
1827 (*(spx_int32_t*)ptr)=st->sampling_rate;
1828 break;
1829 case SPEEX_SET_HANDLER:
1830 {
1831 SpeexCallback *c = (SpeexCallback*)ptr;
1832 st->speex_callbacks[c->callback_id].func=c->func;
1833 st->speex_callbacks[c->callback_id].data=c->data;
1834 st->speex_callbacks[c->callback_id].callback_id=c->callback_id;
1835 }
1836 break;
1837 case SPEEX_SET_USER_HANDLER:
1838 {
1839 SpeexCallback *c = (SpeexCallback*)ptr;
1840 st->user_callback.func=c->func;
1841 st->user_callback.data=c->data;
1842 st->user_callback.callback_id=c->callback_id;
1843 }
1844 break;
1845 case SPEEX_RESET_STATE:
1846 {
1847 int i;
1848 for (i=0;i<st->lpcSize;i++)
1849 st->mem_sp[i]=0;
1850 for (i=0;i<st->frameSize + st->max_pitch + 1;i++)
1851 st->excBuf[i]=0;
1852 }
1853 break;
1854 case SPEEX_SET_SUBMODE_ENCODING:
1855 st->encode_submode = (*(spx_int32_t*)ptr);
1856 break;
1857 case SPEEX_GET_SUBMODE_ENCODING:
1858 (*(spx_int32_t*)ptr) = st->encode_submode;
1859 break;
1860 case SPEEX_GET_LOOKAHEAD:
1861 (*(spx_int32_t*)ptr)=st->subframeSize;
1862 break;
1863 case SPEEX_SET_HIGHPASS:
1864 st->highpass_enabled = (*(spx_int32_t*)ptr);
1865 break;
1866 case SPEEX_GET_HIGHPASS:
1867 (*(spx_int32_t*)ptr) = st->highpass_enabled;
1868 break;
1869 /* FIXME: Convert to fixed-point and re-enable even when float API is disabled */
1870#ifndef DISABLE_FLOAT_API
1871 case SPEEX_GET_ACTIVITY:
1872 {
1873 float ret;
1874 ret = log(st->level/st->min_level)/log(st->max_level/st->min_level);
1875 if (ret>1)
1876 ret = 1;
1877 /* Done in a strange way to catch NaNs as well */
1878 if (!(ret > 0))
1879 ret = 0;
1880 /*printf ("%f %f %f %f\n", st->level, st->min_level, st->max_level, ret);*/
1881 (*(spx_int32_t*)ptr) = (int)(100*ret);
1882 }
1883 break;
1884#endif
1885 case SPEEX_GET_PI_GAIN:
1886 {
1887 int i;
1888 spx_word32_t *g = (spx_word32_t*)ptr;
1889 for (i=0;i<st->nbSubframes;i++)
1890 g[i]=st->pi_gain[i];
1891 }
1892 break;
1893 case SPEEX_GET_EXC:
1894 {
1895 int i;
1896 for (i=0;i<st->nbSubframes;i++)
1897 ((spx_word16_t*)ptr)[i] = compute_rms16(st->exc+i*st->subframeSize, st->subframeSize);
1898 }
1899 break;
1900 case SPEEX_GET_DTX_STATUS:
1901 *((spx_int32_t*)ptr) = st->dtx_enabled;
1902 break;
1903 case SPEEX_SET_INNOVATION_SAVE:
1904 st->innov_save = (spx_word16_t*)ptr;
1905 break;
1906 case SPEEX_SET_WIDEBAND:
1907 st->isWideband = *((spx_int32_t*)ptr);
1908 break;
1909 case SPEEX_GET_STACK:
1910 *((char**)ptr) = st->stack;
1911 break;
1912 default:
1913 speex_warning_int("Unknown nb_ctl request: ", request);
1914 return -1;
1915 }
1916 return 0;
1917}