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