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