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