]> 4ch.mooo.com Git - 16.git/blob - src/lib/dl/ext/speex/nb_celp.c
meh did some cleanings and i will work on mapread to mm thingy sometime soon! oops...
[16.git] / src / lib / dl / ext / speex / nb_celp.c
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 time).
68    This does not apply when using variable-size arrays or alloca. */
69 #ifndef NB_ENC_STACK
70 #define NB_ENC_STACK (8000*sizeof(spx_sig_t))
71 #endif
72
73 #ifndef NB_DEC_STACK
74 #define NB_DEC_STACK (4000*sizeof(spx_sig_t))
75 #endif
76
77
78 #ifdef FIXED_POINT
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, 17967238, 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.492054f, 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)*sizeof(spx_word16_t));
162    st->exc = st->excBuf + mode->pitchEnd + 2;
163    st->swBuf = (spx_word16_t*)speex_alloc((mode->frameSize+mode->pitchEnd+2)*sizeof(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_SHIFT));
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 filter*/
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->nbSubframes, 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_subframe_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->lpcSize, st->mem_sw_whole, stack);
368
369          open_loop_nbest_pitch(st->sw, st->min_pitch, st->max_pitch, st->frameSize, 
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->mem_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-st->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-st->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->nbSubframes);
664       lsp_interpolate(st->old_qlsp, qlsp, interp_qlsp, st->lpcSize, sub, st->nbSubframes);
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, st->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, mem, 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->lpcSize, 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 speech) */
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_tuning, &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],SIG_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_codebook));
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 noise 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, st->subframeSize, 
865                                       innov2, syn_resp, bits, stack, st->complexity, 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 the right thing) */
883       if (st->complexity!=0)
884          filter_mem16(sw, bw_lpc1, bw_lpc2, sw, st->subframeSize, st->lpcSize, st->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.237, 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_gain_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,MULT16_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->subframeSize + 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->mem_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 anyway) */
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, &advance);*/
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_BITS);
1151                /*speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);*/
1152                advance = wb_skip_table[submode];
1153                if (advance < 0)
1154                {
1155                   speex_notify("Invalid mode encountered. The stream is corrupted.");
1156                   return -2;
1157                } 
1158                advance -= (SB_SUBMODE_BITS+1);
1159                speex_bits_advance(bits, advance);
1160                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->subframeSize + 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, SUBMODE(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 encoder is 
1360          crafting packets to make us produce NaNs and slow down the decoder (vague 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(32000,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*best_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->subframeSize, 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), st->subframeSize, bits, stack, &st->seed);
1413                signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545f,15),ener), 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]) , MULT16_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*st->subframeSize, best_pitch, 40, SUBMODE(comb_gain), stack);
1471       multicomb(st->exc+st->subframeSize, out+2*st->subframeSize, st->interp_qlpc, 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 energy 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->nbSubframes);
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:HIGHPASS_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->level);
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->mode))->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->frameSize;
1687       else
1688          (*(spx_int32_t*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize;
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->frameSize;
1806       else
1807          (*(spx_int32_t*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize;
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 disabled */
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 }