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