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