~ubuntu-branches/debian/sid/sflphone/sid

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/third_party/speex/libspeex/nb_celp.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
Tags: 1.3.0-1
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

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