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