Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(539)

Side by Side Diff: speex/libspeex/nb_celp.c

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

Powered by Google App Engine
This is Rietveld 408576698