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