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