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