summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libspeex/sb_celp.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libspeex/sb_celp.c')
-rw-r--r--lib/rbcodec/codecs/libspeex/sb_celp.c1510
1 files changed, 1510 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libspeex/sb_celp.c b/lib/rbcodec/codecs/libspeex/sb_celp.c
new file mode 100644
index 0000000000..b28744812f
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/sb_celp.c
@@ -0,0 +1,1510 @@
1/* Copyright (C) 2002-2006 Jean-Marc Valin
2 File: sb_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 "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"
49
50#ifndef NULL
51#define NULL 0
52#endif
53
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
59
60#ifndef SB_DEC_STACK
61#define SB_DEC_STACK (6000*sizeof(spx_sig_t))
62#endif
63
64
65#ifdef DISABLE_WIDEBAND
66void *sb_encoder_init(const SpeexMode *m)
67{
68 speex_fatal("Wideband and Ultra-wideband are disabled");
69 return NULL;
70}
71void sb_encoder_destroy(void *state)
72{
73 speex_fatal("Wideband and Ultra-wideband are disabled");
74}
75int sb_encode(void *state, void *vin, SpeexBits *bits)
76{
77 speex_fatal("Wideband and Ultra-wideband are disabled");
78 return -2;
79}
80void *sb_decoder_init(const SpeexMode *m)
81{
82 speex_fatal("Wideband and Ultra-wideband are disabled");
83 return NULL;
84}
85void sb_decoder_destroy(void *state)
86{
87 speex_fatal("Wideband and Ultra-wideband are disabled");
88}
89int sb_decode(void *state, SpeexBits *bits, void *vout)
90{
91 speex_fatal("Wideband and Ultra-wideband are disabled");
92 return -2;
93}
94int sb_encoder_ctl(void *state, int request, void *ptr)
95{
96 speex_fatal("Wideband and Ultra-wideband are disabled");
97 return -2;
98}
99int sb_decoder_ctl(void *state, int request, void *ptr)
100{
101 speex_fatal("Wideband and Ultra-wideband are disabled");
102 return -2;
103}
104#else
105
106
107#ifndef M_PI
108#define M_PI 3.14159265358979323846 /* pi */
109#endif
110
111#define sqr(x) ((x)*(x))
112
113#define SUBMODE(x) st->submodes[st->submodeID]->x
114
115#ifdef FIXED_POINT
116static const spx_word16_t gc_quant_bound[16] ICONST_ATTR = {125, 164, 215, 282, 370, 484, 635, 832, 1090, 1428, 1871, 2452, 3213, 4210, 5516, 7228};
117static const spx_word16_t fold_quant_bound[32] ICONST_ATTR = {
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
125
126#else
127
128static 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};
131static 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};
136
137#define LSP_MARGIN .05
138#define LSP_DELTA1 .2
139#define LSP_DELTA2 .05
140
141#endif
142
143#define QMF_ORDER 64
144
145#ifdef FIXED_POINT
146static const spx_word16_t h0[64] ICONST_ATTR = {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};
147
148#else
149static 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
182};
183
184#endif
185
186extern const spx_word16_t lag_window[];
187extern const spx_word16_t lpc_window[];
188
189#ifndef SPEEX_DISABLE_ENCODER
190void *sb_encoder_init(const SpeexMode *m)
191{
192 int i;
193 spx_int32_t tmp;
194 SBEncState *st;
195 const SpeexSBMode *mode;
196
197 st = (SBEncState*)speex_alloc(sizeof(SBEncState));
198 if (!st)
199 return NULL;
200 st->mode = m;
201 mode = (const SpeexSBMode*)m->mode;
202
203
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
211
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;
218
219 st->encode_submode = 1;
220 st->submodes=mode->submodes;
221 st->submodeSelect = st->submodeID=mode->defaultSubmode;
222
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);
227
228 st->lpc_floor = mode->lpc_floor;
229 st->gamma1=mode->gamma1;
230 st->gamma2=mode->gamma2;
231 st->first=1;
232
233 st->high=(spx_word16_t*)speex_alloc((st->windowSize-st->frame_size)*sizeof(spx_word16_t));
234
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));
237
238 st->window= lpc_window;
239
240 st->lagWindow = lag_window;
241
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;
248
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));
252
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);
255
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 */
265
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;
273}
274
275void sb_encoder_destroy(void *state)
276{
277 SBEncState *st=(SBEncState*)state;
278
279 speex_encoder_destroy(st->st_low);
280#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
281 /*speex_free_scratch(st->stack);*/
282#endif
283
284 speex_free(st->high);
285
286 speex_free(st->h0_mem);
287 speex_free(st->h1_mem);
288
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);
294
295 speex_free(st->mem_sp);
296 speex_free(st->mem_sp2);
297 speex_free(st->mem_sw);
298
299
300 speex_free(st);
301}
302
303
304int sb_encode(void *state, void *vin, SpeexBits *bits)
305{
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);
330
331 st = (SBEncState*)state;
332 stack=st->stack;
333 mode = (const SpeexSBMode*)(st->mode->mode);
334 low = in;
335 high = in+st->frame_size;
336
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);
340
341#ifndef DISABLE_VBR
342 if (st->vbr_enabled || st->vad_enabled)
343 {
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);
348 }
349#endif /* #ifndef DISABLE_VBR */
350
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);
355
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);
359
360
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);
365
366 speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, &dtx);
367
368 if (dtx==0)
369 dtx=1;
370 else
371 dtx=0;
372
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);
377
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);
382
383 {
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)
391 {
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));
397 }
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 */
401
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]);
405
406 /* Levinson-Durbin */
407 _spx_lpc(lpc, autocorr, st->lpcSize);
408 }
409
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)
413 {
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++)
418 {
419 lsp[i]=st->old_lsp[i];
420 }
421 }
422 }
423
424#ifndef DISABLE_VBR
425 /* VBR code */
426 if ((st->vbr_enabled || st->vad_enabled) && !dtx)
427 {
428 float ratio;
429 if (st->abr_enabled)
430 {
431 float qual_change=0;
432 if (st->abr_drift2 * st->abr_drift > 0)
433 {
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;
440 }
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;
446 }
447
448
449 ratio = 2*log((1.f+e_high)/(1.f+e_low));
450
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)
458 {
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)
465 {
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--;
477 }
478 speex_encoder_ctl(state, SPEEX_SET_HIGH_MODE, &modeid);
479 if (st->abr_enabled)
480 {
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;
486 }
487
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;
497
498 }
499 /*fprintf (stderr, "%f %f\n", ratio, low_qual);*/
500 }
501#endif /* #ifndef DISABLE_VBR */
502
503 if (st->encode_submode)
504 {
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);
510 }
511
512 /* If null mode (no transmission), just set a couple things to zero*/
513 if (dtx || st->submodes[st->submodeID] == NULL)
514 {
515 for (i=0;i<st->frame_size;i++)
516 high[i]=VERY_SMALL;
517
518 for (i=0;i<st->lpcSize;i++)
519 st->mem_sw[i]=0;
520 st->first=1;
521
522 /* Final signal synthesis from excitation */
523 iir_mem16(high, st->interp_qlpc, high, st->frame_size, st->lpcSize, st->mem_sp, stack);
524
525 if (dtx)
526 return 0;
527 else
528 return 1;
529 }
530
531
532 /* LSP quantization */
533 SUBMODE(lsp_quant)(lsp, qlsp, st->lpcSize, bits);
534
535 if (st->first)
536 {
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];
541 }
542
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);
547
548 for (sub=0;sub<st->nbSubframes;sub++)
549 {
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;
558
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);
564
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);
568
569 lsp_enforce_margin(interp_lsp, st->lpcSize, LSP_MARGIN);
570 lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);
571
572 lsp_to_lpc(interp_lsp, interp_lpc, st->lpcSize,stack);
573 lsp_to_lpc(interp_qlsp, st->interp_qlpc, st->lpcSize, stack);
574
575 bw_lpc(st->gamma1, interp_lpc, bw_lpc1, st->lpcSize);
576 bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize);
577
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)
583 {
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];
586 }
587
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
594
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 */
598
599 eh = compute_rms16(exc, st->subframeSize);
600
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];
605
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)));
608
609#if 0
610 {
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;
622 }
623#endif
624
625 /*print_vec(&g, 1, "gain factor");*/
626 /* Gain quantization */
627 {
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);
635 }
636 if (st->innov_rms_save)
637 {
638 st->innov_rms_save[sub] = eh;
639 }
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*/
646
647 gc = PDIV32_16(MULT16_16(filter_ratio,1+eh),1+el);
648
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);*/
653 {
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]);
657 }
658 if (st->subframeSize==80)
659 gc = MULT16_16_P14(QCONST16(1.4142f,14), gc);
660
661 scale = SHL32(MULT16_16(PDIV32_16(SHL32(EXTEND32(gc),SIG_SHIFT-6),filter_ratio),(1+el)),6);
662
663 compute_impulse_response(st->interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack);
664
665
666 /* Reset excitation */
667 for (i=0;i<st->subframeSize;i++)
668 res[i]=VERY_SMALL;
669
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);
674
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);
678
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);
683
684 /* Compute target signal */
685 for (i=0;i<st->subframeSize;i++)
686 target[i]=SUB16(sw[i],res[i]);
687
688 signal_div(target, target, scale, st->subframeSize);
689
690 /* Reset excitation */
691 SPEEX_MEMSET(innov, 0, st->subframeSize);
692
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");*/
698
699 signal_mul(innov, innov, scale, st->subframeSize);
700
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]);
708
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);
713
714 for (i=0;i<st->subframeSize;i++)
715 innov[i] = ADD32(innov[i],innov2[i]);
716 stack = tmp_stack;
717 }
718 for (i=0;i<st->subframeSize;i++)
719 exc[i] = PSHR32(innov[i],SIG_SHIFT);
720
721 if (st->innov_rms_save)
722 {
723 st->innov_rms_save[sub] = MULT16_16_Q15(QCONST16(.70711f, 15), compute_rms(innov, st->subframeSize));
724 }
725 st->exc_rms[sub] = compute_rms16(exc, st->subframeSize);
726
727
728 }
729
730
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);
736
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);
739 }
740
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];
745
746 st->first=0;
747
748 return 1;
749}
750#endif /* SPEEX_DISABLE_ENCODER */
751
752
753
754static SBDecState global_decstate_wb IBSS_ATTR;
755/* Do not include this for voice codec, files will never be UWB */
756#ifndef ROCKBOX_VOICE_CODEC
757static SBDecState global_decstate_uwb IBSS_ATTR;
758#endif
759
760void *sb_decoder_init(const SpeexMode *m)
761{
762 spx_int32_t tmp;
763 SBDecState *st;
764 const SpeexSBMode *mode;
765/*
766 st = (SBDecState*)speex_alloc(sizeof(SBDecState));
767 if (!st)
768 return NULL;
769*/
770#ifndef ROCKBOX_VOICE_CODEC
771 if (m->modeID == SPEEX_MODEID_UWB)
772 st = &global_decstate_uwb;
773 else
774#endif
775 st = &global_decstate_wb;
776 memset(st, 0, sizeof(*st));
777 st->mode = m;
778 mode=(const SpeexSBMode*)m->mode;
779 st->encode_submode = 1;
780
781 st->st_low = speex_decoder_init(mode->nb_mode);
782#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
783 st->stack = NULL;
784#else
785 /*st->stack = (char*)speex_alloc_scratch(SB_DEC_STACK);*/
786 speex_decoder_ctl(st->st_low, SPEEX_GET_STACK, &st->stack);
787#endif
788
789 st->full_frame_size = 2*mode->frameSize;
790 st->frame_size = mode->frameSize;
791 st->subframeSize = mode->subframeSize;
792 st->nbSubframes = mode->frameSize/mode->subframeSize;
793 st->lpcSize=mode->lpcSize;
794 speex_decoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate);
795 st->sampling_rate*=2;
796 tmp=1;
797 speex_decoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp);
798
799 st->submodes=mode->submodes;
800 st->submodeID=mode->defaultSubmode;
801
802 st->first=1;
803
804 /* st->g0_mem = (spx_word32_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word32_t)); */
805 /* st->g1_mem = (spx_word32_t*)speex_alloc((QMF_ORDER)*sizeof(spx_word32_t)); */
806
807 /* st->excBuf = (spx_word16_t*)speex_alloc((st->subframeSize)*sizeof(spx_word16_t)); */
808
809 /* st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t)); */
810 /* st->interp_qlpc = (spx_coef_t*)speex_alloc(st->lpcSize*sizeof(spx_coef_t)); */
811
812 /* st->pi_gain = (spx_word32_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word32_t)); */
813 /*st->exc_rms = (spx_word16_t*)speex_alloc((st->nbSubframes)*sizeof(spx_word16_t)); */
814 /* st->mem_sp = (spx_mem_t*)speex_alloc((2*st->lpcSize)*sizeof(spx_mem_t)); */
815
816 st->innov_save = NULL;
817
818
819 st->lpc_enh_enabled=0;
820 st->seed = 1000;
821
822#ifdef ENABLE_VALGRIND
823 VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));
824#endif
825 return st;
826}
827
828void sb_decoder_destroy(void *state)
829{
830 SBDecState *st;
831 st = (SBDecState*)state;
832 speex_decoder_destroy(st->st_low);
833#if !(defined(VAR_ARRAYS) || defined (USE_ALLOCA))
834 /*speex_free_scratch(st->stack);*/
835#endif
836/*
837 speex_free(st->g0_mem);
838 speex_free(st->g1_mem);
839 speex_free(st->excBuf);
840 speex_free(st->old_qlsp);
841 speex_free(st->interp_qlpc);
842 speex_free(st->pi_gain);
843 speex_free(st->exc_rms);
844 speex_free(st->mem_sp);
845
846 speex_free(state);
847*/
848}
849
850#ifndef ROCKBOX_VOICE_CODEC
851static void sb_decode_lost(SBDecState *st, spx_word16_t *out, int dtx, char *stack)
852{
853 int i;
854 int saved_modeid=0;
855
856 if (dtx)
857 {
858 saved_modeid=st->submodeID;
859 st->submodeID=1;
860 } else {
861 bw_lpc(QCONST16(0.99f,15), st->interp_qlpc, st->interp_qlpc, st->lpcSize);
862 }
863
864 st->first=1;
865
866
867 /* Final signal synthesis from excitation */
868 if (!dtx)
869 {
870 st->last_ener = MULT16_16_Q15(QCONST16(.9f,15),st->last_ener);
871 }
872 for (i=0;i<st->frame_size;i++)
873 out[i+st->frame_size] = speex_rand(st->last_ener, &st->seed);
874
875 iir_mem16(out+st->frame_size, st->interp_qlpc, out+st->frame_size, st->frame_size, st->lpcSize,
876 st->mem_sp, stack);
877
878
879 /* Reconstruct the original */
880 qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
881 if (dtx)
882 {
883 st->submodeID=saved_modeid;
884 }
885
886 return;
887}
888#endif
889
890int sb_decode(void *state, SpeexBits *bits, void *vout)
891{
892 int i, sub;
893 SBDecState *st;
894 int wideband;
895 int ret;
896 char *stack;
897 VARDECL(spx_word32_t *low_pi_gain);
898 VARDECL(spx_word16_t *low_exc_rms);
899 VARDECL(spx_coef_t *ak);
900 VARDECL(spx_lsp_t *qlsp);
901 VARDECL(spx_lsp_t *interp_qlsp);
902 spx_int32_t dtx;
903 const SpeexSBMode *mode;
904 spx_word16_t *out = (spx_word16_t*)vout;
905 spx_word16_t *low_innov_alias;
906 spx_word32_t exc_ener_sum = 0;
907
908 st = (SBDecState*)state;
909 stack=st->stack;
910 mode = (const SpeexSBMode*)(st->mode->mode);
911
912 low_innov_alias = out+st->frame_size;
913 speex_decoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, low_innov_alias);
914 /* Decode the low-band */
915 ret = speex_decode_native(st->st_low, bits, out);
916
917 speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, &dtx);
918
919 /* If error decoding the narrowband part, propagate error */
920 if (ret!=0)
921 {
922 return ret;
923 }
924
925#ifndef ROCKBOX_VOICE_CODEC
926 if (!bits)
927 {
928 sb_decode_lost(st, out, dtx, stack);
929 return 0;
930 }
931#endif
932
933 if (st->encode_submode)
934 {
935
936 /*Check "wideband bit"*/
937 if (speex_bits_remaining(bits)>0)
938 wideband = speex_bits_peek(bits);
939 else
940 wideband = 0;
941 if (wideband)
942 {
943 /*Regular wideband frame, read the submode*/
944 wideband = speex_bits_unpack_unsigned(bits, 1);
945 st->submodeID = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
946 } else
947 {
948 /*Was a narrowband frame, set "null submode"*/
949 st->submodeID = 0;
950 }
951 if (st->submodeID != 0 && st->submodes[st->submodeID] == NULL)
952 {
953 speex_notify("Invalid mode encountered. The stream is corrupted.");
954 return -2;
955 }
956 }
957
958 /* If null mode (no transmission), just set a couple things to zero*/
959 if (st->submodes[st->submodeID] == NULL)
960 {
961#ifndef ROCKBOX_VOICE_CODEC
962 if (dtx)
963 {
964 sb_decode_lost(st, out, 1, stack);
965 return 0;
966 }
967#endif
968
969 for (i=0;i<st->frame_size;i++)
970 out[st->frame_size+i]=VERY_SMALL;
971
972 st->first=1;
973
974 /* Final signal synthesis from excitation */
975 iir_mem16(out+st->frame_size, st->interp_qlpc, out+st->frame_size, st->frame_size, st->lpcSize, st->mem_sp, stack);
976
977 qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
978
979 return 0;
980
981 }
982
983 ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t);
984 ALLOC(low_exc_rms, st->nbSubframes, spx_word16_t);
985 speex_decoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain);
986 speex_decoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc_rms);
987
988 ALLOC(qlsp, st->lpcSize, spx_lsp_t);
989 ALLOC(interp_qlsp, st->lpcSize, spx_lsp_t);
990 SUBMODE(lsp_unquant)(qlsp, st->lpcSize, bits);
991
992 if (st->first)
993 {
994 for (i=0;i<st->lpcSize;i++)
995 st->old_qlsp[i] = qlsp[i];
996 }
997
998 ALLOC(ak, st->lpcSize, spx_coef_t);
999
1000 for (sub=0;sub<st->nbSubframes;sub++)
1001 {
1002 VARDECL(spx_word32_t *exc);
1003 spx_word16_t *innov_save=NULL;
1004 spx_word16_t *sp;
1005 spx_word16_t filter_ratio;
1006 spx_word16_t el=0;
1007 int offset;
1008 spx_word32_t rl=0,rh=0;
1009
1010 offset = st->subframeSize*sub;
1011 sp=out+st->frame_size+offset;
1012 ALLOC(exc, st->subframeSize, spx_word32_t);
1013 /* Pointer for saving innovation */
1014 if (st->innov_save)
1015 {
1016 innov_save = st->innov_save+2*offset;
1017 SPEEX_MEMSET(innov_save, 0, 2*st->subframeSize);
1018 }
1019
1020 /* LSP interpolation */
1021 lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);
1022
1023 lsp_enforce_margin(interp_qlsp, st->lpcSize, LSP_MARGIN);
1024
1025 /* LSP to LPC */
1026 lsp_to_lpc(interp_qlsp, ak, st->lpcSize, stack);
1027
1028 /* Calculate reponse ratio between the low and high filter in the middle
1029 of the band (4000 Hz) */
1030
1031 st->pi_gain[sub]=LPC_SCALING;
1032 rh = LPC_SCALING;
1033 for (i=0;i<st->lpcSize;i+=2)
1034 {
1035 rh += ak[i+1] - ak[i];
1036 st->pi_gain[sub] += ak[i] + ak[i+1];
1037 }
1038
1039 rl = low_pi_gain[sub];
1040#ifdef FIXED_POINT
1041 filter_ratio=EXTRACT16(SATURATE(PDIV32(SHL32(ADD32(rl,82),7),ADD32(82,rh)),32767));
1042#else
1043 filter_ratio=(rl+.01)/(rh+.01);
1044#endif
1045
1046 SPEEX_MEMSET(exc, 0, st->subframeSize);
1047 if (!SUBMODE(innovation_unquant))
1048 {
1049 spx_word32_t g;
1050 int quant;
1051
1052 quant = speex_bits_unpack_unsigned(bits, 5);
1053 g= spx_exp(MULT16_16(QCONST16(.125f,11),(quant-10)));
1054
1055 g = PDIV32(g, filter_ratio);
1056
1057 for (i=0;i<st->subframeSize;i+=2)
1058 {
1059 exc[i]=SHL32(MULT16_32_P15(MULT16_16_Q15(mode->folding_gain,low_innov_alias[offset+i]),SHL32(g,6)),SIG_SHIFT);
1060 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));
1061 }
1062
1063 } else {
1064 spx_word16_t gc;
1065 spx_word32_t scale;
1066 int qgc = speex_bits_unpack_unsigned(bits, 4);
1067
1068 el = low_exc_rms[sub];
1069 gc = MULT16_16_Q15(QCONST16(0.87360,15),gc_quant_bound[qgc]);
1070
1071 if (st->subframeSize==80)
1072 gc = MULT16_16_P14(QCONST16(1.4142f,14),gc);
1073
1074 scale = SHL32(PDIV32(SHL32(MULT16_16(gc, el),3), filter_ratio),SIG_SHIFT-3);
1075 SUBMODE(innovation_unquant)(exc, SUBMODE(innovation_params), st->subframeSize,
1076 bits, stack, &st->seed);
1077
1078 signal_mul(exc,exc,scale,st->subframeSize);
1079
1080 if (SUBMODE(double_codebook)) {
1081 char *tmp_stack=stack;
1082 VARDECL(spx_sig_t *innov2);
1083 ALLOC(innov2, st->subframeSize, spx_sig_t);
1084 SPEEX_MEMSET(innov2, 0, st->subframeSize);
1085 SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize,
1086 bits, stack, &st->seed);
1087 signal_mul(innov2, innov2, MULT16_32_P15(QCONST16(0.4f,15),scale), st->subframeSize);
1088 for (i=0;i<st->subframeSize;i++)
1089 exc[i] = ADD32(exc[i],innov2[i]);
1090 stack = tmp_stack;
1091 }
1092
1093 }
1094
1095 if (st->innov_save)
1096 {
1097 for (i=0;i<st->subframeSize;i++)
1098 innov_save[2*i]=EXTRACT16(PSHR32(exc[i],SIG_SHIFT));
1099 }
1100
1101 iir_mem16(st->excBuf, st->interp_qlpc, sp, st->subframeSize, st->lpcSize,
1102 st->mem_sp, stack);
1103 for (i=0;i<st->subframeSize;i++)
1104 st->excBuf[i]=EXTRACT16(PSHR32(exc[i],SIG_SHIFT));
1105 for (i=0;i<st->lpcSize;i++)
1106 st->interp_qlpc[i] = ak[i];
1107 st->exc_rms[sub] = compute_rms16(st->excBuf, st->subframeSize);
1108 exc_ener_sum = ADD32(exc_ener_sum, DIV32(MULT16_16(st->exc_rms[sub],st->exc_rms[sub]), st->nbSubframes));
1109 }
1110 st->last_ener = spx_sqrt(exc_ener_sum);
1111
1112 qmf_synth(out, out+st->frame_size, h0, out, st->full_frame_size, QMF_ORDER, st->g0_mem, st->g1_mem, stack);
1113 for (i=0;i<st->lpcSize;i++)
1114 st->old_qlsp[i] = qlsp[i];
1115
1116 st->first=0;
1117
1118 return 0;
1119}
1120
1121#ifndef SPEEX_DISABLE_ENCODER
1122int sb_encoder_ctl(void *state, int request, void *ptr)
1123{
1124 SBEncState *st;
1125 st=(SBEncState*)state;
1126 switch(request)
1127 {
1128 case SPEEX_GET_FRAME_SIZE:
1129 (*(spx_int32_t*)ptr) = st->full_frame_size;
1130 break;
1131 case SPEEX_SET_HIGH_MODE:
1132 st->submodeSelect = st->submodeID = (*(spx_int32_t*)ptr);
1133 break;
1134 case SPEEX_SET_LOW_MODE:
1135 speex_encoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr);
1136 break;
1137 case SPEEX_SET_DTX:
1138 speex_encoder_ctl(st->st_low, SPEEX_SET_DTX, ptr);
1139 break;
1140 case SPEEX_GET_DTX:
1141 speex_encoder_ctl(st->st_low, SPEEX_GET_DTX, ptr);
1142 break;
1143 case SPEEX_GET_LOW_MODE:
1144 speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr);
1145 break;
1146 case SPEEX_SET_MODE:
1147 speex_encoder_ctl(st, SPEEX_SET_QUALITY, ptr);
1148 break;
1149#ifndef DISABLE_VBR
1150 case SPEEX_SET_VBR:
1151 st->vbr_enabled = (*(spx_int32_t*)ptr);
1152 speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, ptr);
1153 break;
1154 case SPEEX_GET_VBR:
1155 (*(spx_int32_t*)ptr) = st->vbr_enabled;
1156 break;
1157 case SPEEX_SET_VAD:
1158 st->vad_enabled = (*(spx_int32_t*)ptr);
1159 speex_encoder_ctl(st->st_low, SPEEX_SET_VAD, ptr);
1160 break;
1161 case SPEEX_GET_VAD:
1162 (*(spx_int32_t*)ptr) = st->vad_enabled;
1163 break;
1164#endif /* #ifndef DISABLE_VBR */
1165#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API)
1166 case SPEEX_SET_VBR_QUALITY:
1167 {
1168 spx_int32_t q;
1169 float qual = (*(float*)ptr)+.6;
1170 st->vbr_quality = (*(float*)ptr);
1171 if (qual>10)
1172 qual=10;
1173 q=(int)floor(.5+*(float*)ptr);
1174 if (q>10)
1175 q=10;
1176 speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_QUALITY, &qual);
1177 speex_encoder_ctl(state, SPEEX_SET_QUALITY, &q);
1178 break;
1179 }
1180 case SPEEX_GET_VBR_QUALITY:
1181 (*(float*)ptr) = st->vbr_quality;
1182 break;
1183#endif /* #if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */
1184#ifndef DISABLE_VBR
1185 case SPEEX_SET_ABR:
1186 st->abr_enabled = (*(spx_int32_t*)ptr);
1187 st->vbr_enabled = st->abr_enabled!=0;
1188 speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, &st->vbr_enabled);
1189 if (st->vbr_enabled)
1190 {
1191 spx_int32_t i=10, rate, target;
1192 float vbr_qual;
1193 target = (*(spx_int32_t*)ptr);
1194 while (i>=0)
1195 {
1196 speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
1197 speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
1198 if (rate <= target)
1199 break;
1200 i--;
1201 }
1202 vbr_qual=i;
1203 if (vbr_qual<0)
1204 vbr_qual=0;
1205 speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual);
1206 st->abr_count=0;
1207 st->abr_drift=0;
1208 st->abr_drift2=0;
1209 }
1210
1211 break;
1212 case SPEEX_GET_ABR:
1213 (*(spx_int32_t*)ptr) = st->abr_enabled;
1214 break;
1215#endif /* #ifndef DISABLE_VBR */
1216
1217 case SPEEX_SET_QUALITY:
1218 {
1219 spx_int32_t nb_qual;
1220 int quality = (*(spx_int32_t*)ptr);
1221 if (quality < 0)
1222 quality = 0;
1223 if (quality > 10)
1224 quality = 10;
1225 st->submodeSelect = st->submodeID = ((const SpeexSBMode*)(st->mode->mode))->quality_map[quality];
1226 nb_qual = ((const SpeexSBMode*)(st->mode->mode))->low_quality_map[quality];
1227 speex_encoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual);
1228 }
1229 break;
1230 case SPEEX_SET_COMPLEXITY:
1231 speex_encoder_ctl(st->st_low, SPEEX_SET_COMPLEXITY, ptr);
1232 st->complexity = (*(spx_int32_t*)ptr);
1233 if (st->complexity<1)
1234 st->complexity=1;
1235 break;
1236 case SPEEX_GET_COMPLEXITY:
1237 (*(spx_int32_t*)ptr) = st->complexity;
1238 break;
1239 case SPEEX_SET_BITRATE:
1240 {
1241 spx_int32_t i=10;
1242 spx_int32_t rate, target;
1243 target = (*(spx_int32_t*)ptr);
1244 while (i>=0)
1245 {
1246 speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
1247 speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
1248 if (rate <= target)
1249 break;
1250 i--;
1251 }
1252 }
1253 break;
1254 case SPEEX_GET_BITRATE:
1255 speex_encoder_ctl(st->st_low, request, ptr);
1256 /*fprintf (stderr, "before: %d\n", (*(int*)ptr));*/
1257 if (st->submodes[st->submodeID])
1258 (*(spx_int32_t*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size;
1259 else
1260 (*(spx_int32_t*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size;
1261 /*fprintf (stderr, "after: %d\n", (*(int*)ptr));*/
1262 break;
1263 case SPEEX_SET_SAMPLING_RATE:
1264 {
1265 spx_int32_t tmp=(*(spx_int32_t*)ptr);
1266 st->sampling_rate = tmp;
1267 tmp>>=1;
1268 speex_encoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp);
1269 }
1270 break;
1271 case SPEEX_GET_SAMPLING_RATE:
1272 (*(spx_int32_t*)ptr)=st->sampling_rate;
1273 break;
1274 case SPEEX_RESET_STATE:
1275 {
1276 int i;
1277 st->first = 1;
1278 for (i=0;i<st->lpcSize;i++)
1279 st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
1280 for (i=0;i<st->lpcSize;i++)
1281 st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0;
1282 for (i=0;i<QMF_ORDER;i++)
1283 st->h0_mem[i]=st->h1_mem[i]=0;
1284 }
1285 break;
1286 case SPEEX_SET_SUBMODE_ENCODING:
1287 st->encode_submode = (*(spx_int32_t*)ptr);
1288 speex_encoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, ptr);
1289 break;
1290 case SPEEX_GET_SUBMODE_ENCODING:
1291 (*(spx_int32_t*)ptr) = st->encode_submode;
1292 break;
1293 case SPEEX_GET_LOOKAHEAD:
1294 speex_encoder_ctl(st->st_low, SPEEX_GET_LOOKAHEAD, ptr);
1295 (*(spx_int32_t*)ptr) = 2*(*(spx_int32_t*)ptr) + QMF_ORDER - 1;
1296 break;
1297 case SPEEX_SET_PLC_TUNING:
1298 speex_encoder_ctl(st->st_low, SPEEX_SET_PLC_TUNING, ptr);
1299 break;
1300 case SPEEX_GET_PLC_TUNING:
1301 speex_encoder_ctl(st->st_low, SPEEX_GET_PLC_TUNING, ptr);
1302 break;
1303#ifndef DISABLE_VBR
1304 case SPEEX_SET_VBR_MAX_BITRATE:
1305 {
1306 st->vbr_max = (*(spx_int32_t*)ptr);
1307 if (SPEEX_SET_VBR_MAX_BITRATE<1)
1308 {
1309 speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_MAX_BITRATE, &st->vbr_max);
1310 st->vbr_max_high = 17600;
1311 } else {
1312 spx_int32_t low_rate;
1313 if (st->vbr_max >= 42200)
1314 {
1315 st->vbr_max_high = 17600;
1316 } else if (st->vbr_max >= 27800)
1317 {
1318 st->vbr_max_high = 9600;
1319 } else if (st->vbr_max > 20600)
1320 {
1321 st->vbr_max_high = 5600;
1322 } else {
1323 st->vbr_max_high = 1800;
1324 }
1325 if (st->subframeSize==80)
1326 st->vbr_max_high = 1800;
1327 low_rate = st->vbr_max - st->vbr_max_high;
1328 speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_MAX_BITRATE, &low_rate);
1329 }
1330 }
1331 break;
1332 case SPEEX_GET_VBR_MAX_BITRATE:
1333 (*(spx_int32_t*)ptr) = st->vbr_max;
1334 break;
1335#endif /* #ifndef DISABLE_VBR */
1336 case SPEEX_SET_HIGHPASS:
1337 speex_encoder_ctl(st->st_low, SPEEX_SET_HIGHPASS, ptr);
1338 break;
1339 case SPEEX_GET_HIGHPASS:
1340 speex_encoder_ctl(st->st_low, SPEEX_GET_HIGHPASS, ptr);
1341 break;
1342
1343
1344 /* This is all internal stuff past this point */
1345 case SPEEX_GET_PI_GAIN:
1346 {
1347 int i;
1348 spx_word32_t *g = (spx_word32_t*)ptr;
1349 for (i=0;i<st->nbSubframes;i++)
1350 g[i]=st->pi_gain[i];
1351 }
1352 break;
1353 case SPEEX_GET_EXC:
1354 {
1355 int i;
1356 for (i=0;i<st->nbSubframes;i++)
1357 ((spx_word16_t*)ptr)[i] = st->exc_rms[i];
1358 }
1359 break;
1360#ifndef DISABLE_VBR
1361 case SPEEX_GET_RELATIVE_QUALITY:
1362 (*(float*)ptr)=st->relative_quality;
1363 break;
1364#endif /* #ifndef DISABLE_VBR */
1365 case SPEEX_SET_INNOVATION_SAVE:
1366 st->innov_rms_save = (spx_word16_t*)ptr;
1367 break;
1368 case SPEEX_SET_WIDEBAND:
1369 speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr);
1370 break;
1371 case SPEEX_GET_STACK:
1372 *((char**)ptr) = st->stack;
1373 break;
1374 default:
1375 speex_warning_int("Unknown nb_ctl request: ", request);
1376 return -1;
1377 }
1378 return 0;
1379}
1380#endif /* SPEEX_DISABLE_ENCODER */
1381
1382int sb_decoder_ctl(void *state, int request, void *ptr)
1383{
1384 SBDecState *st;
1385 st=(SBDecState*)state;
1386 switch(request)
1387 {
1388 case SPEEX_SET_HIGH_MODE:
1389 st->submodeID = (*(spx_int32_t*)ptr);
1390 break;
1391 case SPEEX_SET_LOW_MODE:
1392 speex_decoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr);
1393 break;
1394 case SPEEX_GET_LOW_MODE:
1395 speex_decoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr);
1396 break;
1397 case SPEEX_GET_FRAME_SIZE:
1398 (*(spx_int32_t*)ptr) = st->full_frame_size;
1399 break;
1400 case SPEEX_SET_ENH:
1401 speex_decoder_ctl(st->st_low, request, ptr);
1402 st->lpc_enh_enabled = *((spx_int32_t*)ptr);
1403 break;
1404 case SPEEX_GET_ENH:
1405 *((spx_int32_t*)ptr) = st->lpc_enh_enabled;
1406 break;
1407 case SPEEX_SET_MODE:
1408 case SPEEX_SET_QUALITY:
1409 {
1410 spx_int32_t nb_qual;
1411 int quality = (*(spx_int32_t*)ptr);
1412 if (quality < 0)
1413 quality = 0;
1414 if (quality > 10)
1415 quality = 10;
1416 st->submodeID = ((const SpeexSBMode*)(st->mode->mode))->quality_map[quality];
1417 nb_qual = ((const SpeexSBMode*)(st->mode->mode))->low_quality_map[quality];
1418 speex_decoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual);
1419 }
1420 break;
1421 case SPEEX_GET_BITRATE:
1422 speex_decoder_ctl(st->st_low, request, ptr);
1423 if (st->submodes[st->submodeID])
1424 (*(spx_int32_t*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size;
1425 else
1426 (*(spx_int32_t*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size;
1427 break;
1428 case SPEEX_SET_SAMPLING_RATE:
1429 {
1430 spx_int32_t tmp=(*(spx_int32_t*)ptr);
1431 st->sampling_rate = tmp;
1432 tmp>>=1;
1433 speex_decoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp);
1434 }
1435 break;
1436 case SPEEX_GET_SAMPLING_RATE:
1437 (*(spx_int32_t*)ptr)=st->sampling_rate;
1438 break;
1439 case SPEEX_SET_HANDLER:
1440 speex_decoder_ctl(st->st_low, SPEEX_SET_HANDLER, ptr);
1441 break;
1442 case SPEEX_SET_USER_HANDLER:
1443 speex_decoder_ctl(st->st_low, SPEEX_SET_USER_HANDLER, ptr);
1444 break;
1445 case SPEEX_RESET_STATE:
1446 {
1447 int i;
1448 for (i=0;i<2*st->lpcSize;i++)
1449 st->mem_sp[i]=0;
1450 for (i=0;i<QMF_ORDER;i++)
1451 st->g0_mem[i]=st->g1_mem[i]=0;
1452 st->last_ener=0;
1453 }
1454 break;
1455 case SPEEX_SET_SUBMODE_ENCODING:
1456 st->encode_submode = (*(spx_int32_t*)ptr);
1457 speex_decoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, ptr);
1458 break;
1459 case SPEEX_GET_SUBMODE_ENCODING:
1460 (*(spx_int32_t*)ptr) = st->encode_submode;
1461 break;
1462 case SPEEX_GET_LOOKAHEAD:
1463 speex_decoder_ctl(st->st_low, SPEEX_GET_LOOKAHEAD, ptr);
1464 (*(spx_int32_t*)ptr) = 2*(*(spx_int32_t*)ptr);
1465 break;
1466 case SPEEX_SET_HIGHPASS:
1467 speex_decoder_ctl(st->st_low, SPEEX_SET_HIGHPASS, ptr);
1468 break;
1469 case SPEEX_GET_HIGHPASS:
1470 speex_decoder_ctl(st->st_low, SPEEX_GET_HIGHPASS, ptr);
1471 break;
1472 case SPEEX_GET_ACTIVITY:
1473 speex_decoder_ctl(st->st_low, SPEEX_GET_ACTIVITY, ptr);
1474 break;
1475 case SPEEX_GET_PI_GAIN:
1476 {
1477 int i;
1478 spx_word32_t *g = (spx_word32_t*)ptr;
1479 for (i=0;i<st->nbSubframes;i++)
1480 g[i]=st->pi_gain[i];
1481 }
1482 break;
1483 case SPEEX_GET_EXC:
1484 {
1485 int i;
1486 for (i=0;i<st->nbSubframes;i++)
1487 ((spx_word16_t*)ptr)[i] = st->exc_rms[i];
1488 }
1489 break;
1490 case SPEEX_GET_DTX_STATUS:
1491 speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, ptr);
1492 break;
1493 case SPEEX_SET_INNOVATION_SAVE:
1494 st->innov_save = (spx_word16_t*)ptr;
1495 break;
1496 case SPEEX_SET_WIDEBAND:
1497 speex_decoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, ptr);
1498 break;
1499 case SPEEX_GET_STACK:
1500 *((char**)ptr) = st->stack;
1501 break;
1502 default:
1503 speex_warning_int("Unknown nb_ctl request: ", request);
1504 return -1;
1505 }
1506 return 0;
1507}
1508
1509#endif
1510