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