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