• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2007-2008 CSIRO
2    Copyright (c) 2007-2010 Xiph.Org Foundation
3    Copyright (c) 2008 Gregory Maxwell
4    Written by Jean-Marc Valin and Gregory Maxwell */
5 /*
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9 
10    - Redistributions of source code must retain the above copyright
11    notice, this list of conditions and the following disclaimer.
12 
13    - Redistributions in binary form must reproduce the above copyright
14    notice, this list of conditions and the following disclaimer in the
15    documentation and/or other materials provided with the distribution.
16 
17    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33 
34 #define CELT_DECODER_C
35 
36 #include "cpu_support.h"
37 #include "os_support.h"
38 #include "mdct.h"
39 #include <math.h>
40 #include "celt.h"
41 #include "pitch.h"
42 #include "bands.h"
43 #include "modes.h"
44 #include "entcode.h"
45 #include "quant_bands.h"
46 #include "rate.h"
47 #include "stack_alloc.h"
48 #include "mathops.h"
49 #include "float_cast.h"
50 #include <stdarg.h>
51 #include "celt_lpc.h"
52 #include "vq.h"
53 
54 #if defined(SMALL_FOOTPRINT) && defined(FIXED_POINT)
55 #define NORM_ALIASING_HACK
56 #endif
57 /**********************************************************************/
58 /*                                                                    */
59 /*                             DECODER                                */
60 /*                                                                    */
61 /**********************************************************************/
62 #define DECODE_BUFFER_SIZE 2048
63 
64 /** Decoder state
65  @brief Decoder state
66  */
67 struct OpusCustomDecoder {
68    const OpusCustomMode *mode;
69    int overlap;
70    int channels;
71    int stream_channels;
72 
73    int downsample;
74    int start, end;
75    int signalling;
76    int arch;
77 
78    /* Everything beyond this point gets cleared on a reset */
79 #define DECODER_RESET_START rng
80 
81    opus_uint32 rng;
82    int error;
83    int last_pitch_index;
84    int loss_count;
85    int skip_plc;
86    int postfilter_period;
87    int postfilter_period_old;
88    opus_val16 postfilter_gain;
89    opus_val16 postfilter_gain_old;
90    int postfilter_tapset;
91    int postfilter_tapset_old;
92 
93    celt_sig preemph_memD[2];
94 
95    celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */
96    /* opus_val16 lpc[],  Size = channels*LPC_ORDER */
97    /* opus_val16 oldEBands[], Size = 2*mode->nbEBands */
98    /* opus_val16 oldLogE[], Size = 2*mode->nbEBands */
99    /* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */
100    /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */
101 };
102 
celt_decoder_get_size(int channels)103 int celt_decoder_get_size(int channels)
104 {
105    const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
106    return opus_custom_decoder_get_size(mode, channels);
107 }
108 
opus_custom_decoder_get_size(const CELTMode * mode,int channels)109 OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_get_size(const CELTMode *mode, int channels)
110 {
111    int size = sizeof(struct CELTDecoder)
112             + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig)
113             + channels*LPC_ORDER*sizeof(opus_val16)
114             + 4*2*mode->nbEBands*sizeof(opus_val16);
115    return size;
116 }
117 
118 #ifdef CUSTOM_MODES
opus_custom_decoder_create(const CELTMode * mode,int channels,int * error)119 CELTDecoder *opus_custom_decoder_create(const CELTMode *mode, int channels, int *error)
120 {
121    int ret;
122    CELTDecoder *st = (CELTDecoder *)opus_alloc(opus_custom_decoder_get_size(mode, channels));
123    ret = opus_custom_decoder_init(st, mode, channels);
124    if (ret != OPUS_OK)
125    {
126       opus_custom_decoder_destroy(st);
127       st = NULL;
128    }
129    if (error)
130       *error = ret;
131    return st;
132 }
133 #endif /* CUSTOM_MODES */
134 
celt_decoder_init(CELTDecoder * st,opus_int32 sampling_rate,int channels)135 int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels)
136 {
137    int ret;
138    ret = opus_custom_decoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels);
139    if (ret != OPUS_OK)
140       return ret;
141    st->downsample = resampling_factor(sampling_rate);
142    if (st->downsample==0)
143       return OPUS_BAD_ARG;
144    else
145       return OPUS_OK;
146 }
147 
opus_custom_decoder_init(CELTDecoder * st,const CELTMode * mode,int channels)148 OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels)
149 {
150    if (channels < 0 || channels > 2)
151       return OPUS_BAD_ARG;
152 
153    if (st==NULL)
154       return OPUS_ALLOC_FAIL;
155 
156    OPUS_CLEAR((char*)st, opus_custom_decoder_get_size(mode, channels));
157 
158    st->mode = mode;
159    st->overlap = mode->overlap;
160    st->stream_channels = st->channels = channels;
161 
162    st->downsample = 1;
163    st->start = 0;
164    st->end = st->mode->effEBands;
165    st->signalling = 1;
166    st->arch = opus_select_arch();
167 
168    opus_custom_decoder_ctl(st, OPUS_RESET_STATE);
169 
170    return OPUS_OK;
171 }
172 
173 #ifdef CUSTOM_MODES
opus_custom_decoder_destroy(CELTDecoder * st)174 void opus_custom_decoder_destroy(CELTDecoder *st)
175 {
176    opus_free(st);
177 }
178 #endif /* CUSTOM_MODES */
179 
180 
181 #ifndef RESYNTH
182 static
183 #endif
deemphasis(celt_sig * in[],opus_val16 * pcm,int N,int C,int downsample,const opus_val16 * coef,celt_sig * mem,int accum)184 void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef,
185       celt_sig *mem, int accum)
186 {
187    int c;
188    int Nd;
189    int apply_downsampling=0;
190    opus_val16 coef0;
191    VARDECL(celt_sig, scratch);
192    SAVE_STACK;
193 #ifndef FIXED_POINT
194    (void)accum;
195    celt_assert(accum==0);
196 #endif
197    ALLOC(scratch, N, celt_sig);
198    coef0 = coef[0];
199    Nd = N/downsample;
200    c=0; do {
201       int j;
202       celt_sig * OPUS_RESTRICT x;
203       opus_val16  * OPUS_RESTRICT y;
204       celt_sig m = mem[c];
205       x =in[c];
206       y = pcm+c;
207 #ifdef CUSTOM_MODES
208       if (coef[1] != 0)
209       {
210          opus_val16 coef1 = coef[1];
211          opus_val16 coef3 = coef[3];
212          for (j=0;j<N;j++)
213          {
214             celt_sig tmp = x[j] + m + VERY_SMALL;
215             m = MULT16_32_Q15(coef0, tmp)
216                           - MULT16_32_Q15(coef1, x[j]);
217             tmp = SHL32(MULT16_32_Q15(coef3, tmp), 2);
218             scratch[j] = tmp;
219          }
220          apply_downsampling=1;
221       } else
222 #endif
223       if (downsample>1)
224       {
225          /* Shortcut for the standard (non-custom modes) case */
226          for (j=0;j<N;j++)
227          {
228             celt_sig tmp = x[j] + m + VERY_SMALL;
229             m = MULT16_32_Q15(coef0, tmp);
230             scratch[j] = tmp;
231          }
232          apply_downsampling=1;
233       } else {
234          /* Shortcut for the standard (non-custom modes) case */
235 #ifdef FIXED_POINT
236          if (accum)
237          {
238             for (j=0;j<N;j++)
239             {
240                celt_sig tmp = x[j] + m + VERY_SMALL;
241                m = MULT16_32_Q15(coef0, tmp);
242                y[j*C] = SAT16(ADD32(y[j*C], SCALEOUT(SIG2WORD16(tmp))));
243             }
244          } else
245 #endif
246          {
247             for (j=0;j<N;j++)
248             {
249                celt_sig tmp = x[j] + m + VERY_SMALL;
250                m = MULT16_32_Q15(coef0, tmp);
251                y[j*C] = SCALEOUT(SIG2WORD16(tmp));
252             }
253          }
254       }
255       mem[c] = m;
256 
257       if (apply_downsampling)
258       {
259          /* Perform down-sampling */
260 #ifdef FIXED_POINT
261          if (accum)
262          {
263             for (j=0;j<Nd;j++)
264                y[j*C] = SAT16(ADD32(y[j*C], SCALEOUT(SIG2WORD16(scratch[j*downsample]))));
265          } else
266 #endif
267          {
268             for (j=0;j<Nd;j++)
269                y[j*C] = SCALEOUT(SIG2WORD16(scratch[j*downsample]));
270          }
271       }
272    } while (++c<C);
273    RESTORE_STACK;
274 }
275 
276 #ifndef RESYNTH
277 static
278 #endif
celt_synthesis(const CELTMode * mode,celt_norm * X,celt_sig * out_syn[],opus_val16 * oldBandE,int start,int effEnd,int C,int CC,int isTransient,int LM,int downsample,int silence,int arch)279 void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
280                     opus_val16 *oldBandE, int start, int effEnd, int C, int CC,
281                     int isTransient, int LM, int downsample,
282                     int silence, int arch)
283 {
284    int c, i;
285    int M;
286    int b;
287    int B;
288    int N, NB;
289    int shift;
290    int nbEBands;
291    int overlap;
292    VARDECL(celt_sig, freq);
293    SAVE_STACK;
294 
295    overlap = mode->overlap;
296    nbEBands = mode->nbEBands;
297    N = mode->shortMdctSize<<LM;
298    ALLOC(freq, N, celt_sig); /**< Interleaved signal MDCTs */
299    M = 1<<LM;
300 
301    if (isTransient)
302    {
303       B = M;
304       NB = mode->shortMdctSize;
305       shift = mode->maxLM;
306    } else {
307       B = 1;
308       NB = mode->shortMdctSize<<LM;
309       shift = mode->maxLM-LM;
310    }
311 
312    if (CC==2&&C==1)
313    {
314       /* Copying a mono streams to two channels */
315       celt_sig *freq2;
316       denormalise_bands(mode, X, freq, oldBandE, start, effEnd, M,
317             downsample, silence);
318       /* Store a temporary copy in the output buffer because the IMDCT destroys its input. */
319       freq2 = out_syn[1]+overlap/2;
320       OPUS_COPY(freq2, freq, N);
321       for (b=0;b<B;b++)
322          clt_mdct_backward(&mode->mdct, &freq2[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch);
323       for (b=0;b<B;b++)
324          clt_mdct_backward(&mode->mdct, &freq[b], out_syn[1]+NB*b, mode->window, overlap, shift, B, arch);
325    } else if (CC==1&&C==2)
326    {
327       /* Downmixing a stereo stream to mono */
328       celt_sig *freq2;
329       freq2 = out_syn[0]+overlap/2;
330       denormalise_bands(mode, X, freq, oldBandE, start, effEnd, M,
331             downsample, silence);
332       /* Use the output buffer as temp array before downmixing. */
333       denormalise_bands(mode, X+N, freq2, oldBandE+nbEBands, start, effEnd, M,
334             downsample, silence);
335       for (i=0;i<N;i++)
336          freq[i] = HALF32(ADD32(freq[i],freq2[i]));
337       for (b=0;b<B;b++)
338          clt_mdct_backward(&mode->mdct, &freq[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch);
339    } else {
340       /* Normal case (mono or stereo) */
341       c=0; do {
342          denormalise_bands(mode, X+c*N, freq, oldBandE+c*nbEBands, start, effEnd, M,
343                downsample, silence);
344          for (b=0;b<B;b++)
345             clt_mdct_backward(&mode->mdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B, arch);
346       } while (++c<CC);
347    }
348    RESTORE_STACK;
349 }
350 
tf_decode(int start,int end,int isTransient,int * tf_res,int LM,ec_dec * dec)351 static void tf_decode(int start, int end, int isTransient, int *tf_res, int LM, ec_dec *dec)
352 {
353    int i, curr, tf_select;
354    int tf_select_rsv;
355    int tf_changed;
356    int logp;
357    opus_uint32 budget;
358    opus_uint32 tell;
359 
360    budget = dec->storage*8;
361    tell = ec_tell(dec);
362    logp = isTransient ? 2 : 4;
363    tf_select_rsv = LM>0 && tell+logp+1<=budget;
364    budget -= tf_select_rsv;
365    tf_changed = curr = 0;
366    for (i=start;i<end;i++)
367    {
368       if (tell+logp<=budget)
369       {
370          curr ^= ec_dec_bit_logp(dec, logp);
371          tell = ec_tell(dec);
372          tf_changed |= curr;
373       }
374       tf_res[i] = curr;
375       logp = isTransient ? 4 : 5;
376    }
377    tf_select = 0;
378    if (tf_select_rsv &&
379      tf_select_table[LM][4*isTransient+0+tf_changed] !=
380      tf_select_table[LM][4*isTransient+2+tf_changed])
381    {
382       tf_select = ec_dec_bit_logp(dec, 1);
383    }
384    for (i=start;i<end;i++)
385    {
386       tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
387    }
388 }
389 
390 /* The maximum pitch lag to allow in the pitch-based PLC. It's possible to save
391    CPU time in the PLC pitch search by making this smaller than MAX_PERIOD. The
392    current value corresponds to a pitch of 66.67 Hz. */
393 #define PLC_PITCH_LAG_MAX (720)
394 /* The minimum pitch lag to allow in the pitch-based PLC. This corresponds to a
395    pitch of 480 Hz. */
396 #define PLC_PITCH_LAG_MIN (100)
397 
celt_plc_pitch_search(celt_sig * decode_mem[2],int C,int arch)398 static int celt_plc_pitch_search(celt_sig *decode_mem[2], int C, int arch)
399 {
400    int pitch_index;
401    VARDECL( opus_val16, lp_pitch_buf );
402    SAVE_STACK;
403    ALLOC( lp_pitch_buf, DECODE_BUFFER_SIZE>>1, opus_val16 );
404    pitch_downsample(decode_mem, lp_pitch_buf,
405          DECODE_BUFFER_SIZE, C, arch);
406    pitch_search(lp_pitch_buf+(PLC_PITCH_LAG_MAX>>1), lp_pitch_buf,
407          DECODE_BUFFER_SIZE-PLC_PITCH_LAG_MAX,
408          PLC_PITCH_LAG_MAX-PLC_PITCH_LAG_MIN, &pitch_index, arch);
409    pitch_index = PLC_PITCH_LAG_MAX-pitch_index;
410    RESTORE_STACK;
411    return pitch_index;
412 }
413 
celt_decode_lost(CELTDecoder * OPUS_RESTRICT st,int N,int LM)414 static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
415 {
416    int c;
417    int i;
418    const int C = st->channels;
419    celt_sig *decode_mem[2];
420    celt_sig *out_syn[2];
421    opus_val16 *lpc;
422    opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
423    const OpusCustomMode *mode;
424    int nbEBands;
425    int overlap;
426    int start;
427    int loss_count;
428    int noise_based;
429    const opus_int16 *eBands;
430    SAVE_STACK;
431 
432    mode = st->mode;
433    nbEBands = mode->nbEBands;
434    overlap = mode->overlap;
435    eBands = mode->eBands;
436 
437    c=0; do {
438       decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap);
439       out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N;
440    } while (++c<C);
441    lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+overlap)*C);
442    oldBandE = lpc+C*LPC_ORDER;
443    oldLogE = oldBandE + 2*nbEBands;
444    oldLogE2 = oldLogE + 2*nbEBands;
445    backgroundLogE = oldLogE2  + 2*nbEBands;
446 
447    loss_count = st->loss_count;
448    start = st->start;
449    noise_based = loss_count >= 5 || start != 0 || st->skip_plc;
450    if (noise_based)
451    {
452       /* Noise-based PLC/CNG */
453 #ifdef NORM_ALIASING_HACK
454       celt_norm *X;
455 #else
456       VARDECL(celt_norm, X);
457 #endif
458       opus_uint32 seed;
459       int end;
460       int effEnd;
461       opus_val16 decay;
462       end = st->end;
463       effEnd = IMAX(start, IMIN(end, mode->effEBands));
464 
465 #ifdef NORM_ALIASING_HACK
466       /* This is an ugly hack that breaks aliasing rules and would be easily broken,
467          but it saves almost 4kB of stack. */
468       X = (celt_norm*)(out_syn[C-1]+overlap/2);
469 #else
470       ALLOC(X, C*N, celt_norm);   /**< Interleaved normalised MDCTs */
471 #endif
472 
473       /* Energy decay */
474       decay = loss_count==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT);
475       c=0; do
476       {
477          for (i=start;i<end;i++)
478             oldBandE[c*nbEBands+i] = MAX16(backgroundLogE[c*nbEBands+i], oldBandE[c*nbEBands+i] - decay);
479       } while (++c<C);
480       seed = st->rng;
481       for (c=0;c<C;c++)
482       {
483          for (i=start;i<effEnd;i++)
484          {
485             int j;
486             int boffs;
487             int blen;
488             boffs = N*c+(eBands[i]<<LM);
489             blen = (eBands[i+1]-eBands[i])<<LM;
490             for (j=0;j<blen;j++)
491             {
492                seed = celt_lcg_rand(seed);
493                X[boffs+j] = (celt_norm)((opus_int32)seed>>20);
494             }
495             renormalise_vector(X+boffs, blen, Q15ONE, st->arch);
496          }
497       }
498       st->rng = seed;
499 
500       c=0; do {
501          OPUS_MOVE(decode_mem[c], decode_mem[c]+N,
502                DECODE_BUFFER_SIZE-N+(overlap>>1));
503       } while (++c<C);
504 
505       celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, C, C, 0, LM, st->downsample, 0, st->arch);
506    } else {
507       /* Pitch-based PLC */
508       const opus_val16 *window;
509       opus_val16 fade = Q15ONE;
510       int pitch_index;
511       VARDECL(opus_val32, etmp);
512       VARDECL(opus_val16, exc);
513 
514       if (loss_count == 0)
515       {
516          st->last_pitch_index = pitch_index = celt_plc_pitch_search(decode_mem, C, st->arch);
517       } else {
518          pitch_index = st->last_pitch_index;
519          fade = QCONST16(.8f,15);
520       }
521 
522       ALLOC(etmp, overlap, opus_val32);
523       ALLOC(exc, MAX_PERIOD, opus_val16);
524       window = mode->window;
525       c=0; do {
526          opus_val16 decay;
527          opus_val16 attenuation;
528          opus_val32 S1=0;
529          celt_sig *buf;
530          int extrapolation_offset;
531          int extrapolation_len;
532          int exc_length;
533          int j;
534 
535          buf = decode_mem[c];
536          for (i=0;i<MAX_PERIOD;i++) {
537             exc[i] = ROUND16(buf[DECODE_BUFFER_SIZE-MAX_PERIOD+i], SIG_SHIFT);
538          }
539 
540          if (loss_count == 0)
541          {
542             opus_val32 ac[LPC_ORDER+1];
543             /* Compute LPC coefficients for the last MAX_PERIOD samples before
544                the first loss so we can work in the excitation-filter domain. */
545             _celt_autocorr(exc, ac, window, overlap,
546                    LPC_ORDER, MAX_PERIOD, st->arch);
547             /* Add a noise floor of -40 dB. */
548 #ifdef FIXED_POINT
549             ac[0] += SHR32(ac[0],13);
550 #else
551             ac[0] *= 1.0001f;
552 #endif
553             /* Use lag windowing to stabilize the Levinson-Durbin recursion. */
554             for (i=1;i<=LPC_ORDER;i++)
555             {
556                /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
557 #ifdef FIXED_POINT
558                ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);
559 #else
560                ac[i] -= ac[i]*(0.008f*0.008f)*i*i;
561 #endif
562             }
563             _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
564          }
565          /* We want the excitation for 2 pitch periods in order to look for a
566             decaying signal, but we can't get more than MAX_PERIOD. */
567          exc_length = IMIN(2*pitch_index, MAX_PERIOD);
568          /* Initialize the LPC history with the samples just before the start
569             of the region for which we're computing the excitation. */
570          {
571             opus_val16 lpc_mem[LPC_ORDER];
572             for (i=0;i<LPC_ORDER;i++)
573             {
574                lpc_mem[i] =
575                      ROUND16(buf[DECODE_BUFFER_SIZE-exc_length-1-i], SIG_SHIFT);
576             }
577             /* Compute the excitation for exc_length samples before the loss. */
578             celt_fir(exc+MAX_PERIOD-exc_length, lpc+c*LPC_ORDER,
579                   exc+MAX_PERIOD-exc_length, exc_length, LPC_ORDER, lpc_mem, st->arch);
580          }
581 
582          /* Check if the waveform is decaying, and if so how fast.
583             We do this to avoid adding energy when concealing in a segment
584             with decaying energy. */
585          {
586             opus_val32 E1=1, E2=1;
587             int decay_length;
588 #ifdef FIXED_POINT
589             int shift = IMAX(0,2*celt_zlog2(celt_maxabs16(&exc[MAX_PERIOD-exc_length], exc_length))-20);
590 #endif
591             decay_length = exc_length>>1;
592             for (i=0;i<decay_length;i++)
593             {
594                opus_val16 e;
595                e = exc[MAX_PERIOD-decay_length+i];
596                E1 += SHR32(MULT16_16(e, e), shift);
597                e = exc[MAX_PERIOD-2*decay_length+i];
598                E2 += SHR32(MULT16_16(e, e), shift);
599             }
600             E1 = MIN32(E1, E2);
601             decay = celt_sqrt(frac_div32(SHR32(E1, 1), E2));
602          }
603 
604          /* Move the decoder memory one frame to the left to give us room to
605             add the data for the new frame. We ignore the overlap that extends
606             past the end of the buffer, because we aren't going to use it. */
607          OPUS_MOVE(buf, buf+N, DECODE_BUFFER_SIZE-N);
608 
609          /* Extrapolate from the end of the excitation with a period of
610             "pitch_index", scaling down each period by an additional factor of
611             "decay". */
612          extrapolation_offset = MAX_PERIOD-pitch_index;
613          /* We need to extrapolate enough samples to cover a complete MDCT
614             window (including overlap/2 samples on both sides). */
615          extrapolation_len = N+overlap;
616          /* We also apply fading if this is not the first loss. */
617          attenuation = MULT16_16_Q15(fade, decay);
618          for (i=j=0;i<extrapolation_len;i++,j++)
619          {
620             opus_val16 tmp;
621             if (j >= pitch_index) {
622                j -= pitch_index;
623                attenuation = MULT16_16_Q15(attenuation, decay);
624             }
625             buf[DECODE_BUFFER_SIZE-N+i] =
626                   SHL32(EXTEND32(MULT16_16_Q15(attenuation,
627                         exc[extrapolation_offset+j])), SIG_SHIFT);
628             /* Compute the energy of the previously decoded signal whose
629                excitation we're copying. */
630             tmp = ROUND16(
631                   buf[DECODE_BUFFER_SIZE-MAX_PERIOD-N+extrapolation_offset+j],
632                   SIG_SHIFT);
633             S1 += SHR32(MULT16_16(tmp, tmp), 8);
634          }
635 
636          {
637             opus_val16 lpc_mem[LPC_ORDER];
638             /* Copy the last decoded samples (prior to the overlap region) to
639                synthesis filter memory so we can have a continuous signal. */
640             for (i=0;i<LPC_ORDER;i++)
641                lpc_mem[i] = ROUND16(buf[DECODE_BUFFER_SIZE-N-1-i], SIG_SHIFT);
642             /* Apply the synthesis filter to convert the excitation back into
643                the signal domain. */
644             celt_iir(buf+DECODE_BUFFER_SIZE-N, lpc+c*LPC_ORDER,
645                   buf+DECODE_BUFFER_SIZE-N, extrapolation_len, LPC_ORDER,
646                   lpc_mem, st->arch);
647          }
648 
649          /* Check if the synthesis energy is higher than expected, which can
650             happen with the signal changes during our window. If so,
651             attenuate. */
652          {
653             opus_val32 S2=0;
654             for (i=0;i<extrapolation_len;i++)
655             {
656                opus_val16 tmp = ROUND16(buf[DECODE_BUFFER_SIZE-N+i], SIG_SHIFT);
657                S2 += SHR32(MULT16_16(tmp, tmp), 8);
658             }
659             /* This checks for an "explosion" in the synthesis. */
660 #ifdef FIXED_POINT
661             if (!(S1 > SHR32(S2,2)))
662 #else
663             /* The float test is written this way to catch NaNs in the output
664                of the IIR filter at the same time. */
665             if (!(S1 > 0.2f*S2))
666 #endif
667             {
668                for (i=0;i<extrapolation_len;i++)
669                   buf[DECODE_BUFFER_SIZE-N+i] = 0;
670             } else if (S1 < S2)
671             {
672                opus_val16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
673                for (i=0;i<overlap;i++)
674                {
675                   opus_val16 tmp_g = Q15ONE
676                         - MULT16_16_Q15(window[i], Q15ONE-ratio);
677                   buf[DECODE_BUFFER_SIZE-N+i] =
678                         MULT16_32_Q15(tmp_g, buf[DECODE_BUFFER_SIZE-N+i]);
679                }
680                for (i=overlap;i<extrapolation_len;i++)
681                {
682                   buf[DECODE_BUFFER_SIZE-N+i] =
683                         MULT16_32_Q15(ratio, buf[DECODE_BUFFER_SIZE-N+i]);
684                }
685             }
686          }
687 
688          /* Apply the pre-filter to the MDCT overlap for the next frame because
689             the post-filter will be re-applied in the decoder after the MDCT
690             overlap. */
691          comb_filter(etmp, buf+DECODE_BUFFER_SIZE,
692               st->postfilter_period, st->postfilter_period, overlap,
693               -st->postfilter_gain, -st->postfilter_gain,
694               st->postfilter_tapset, st->postfilter_tapset, NULL, 0, st->arch);
695 
696          /* Simulate TDAC on the concealed audio so that it blends with the
697             MDCT of the next frame. */
698          for (i=0;i<overlap/2;i++)
699          {
700             buf[DECODE_BUFFER_SIZE+i] =
701                MULT16_32_Q15(window[i], etmp[overlap-1-i])
702                + MULT16_32_Q15(window[overlap-i-1], etmp[i]);
703          }
704       } while (++c<C);
705    }
706 
707    st->loss_count = loss_count+1;
708 
709    RESTORE_STACK;
710 }
711 
celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st,const unsigned char * data,int len,opus_val16 * OPUS_RESTRICT pcm,int frame_size,ec_dec * dec,int accum)712 int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data,
713       int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum)
714 {
715    int c, i, N;
716    int spread_decision;
717    opus_int32 bits;
718    ec_dec _dec;
719 #ifdef NORM_ALIASING_HACK
720    celt_norm *X;
721 #else
722    VARDECL(celt_norm, X);
723 #endif
724    VARDECL(int, fine_quant);
725    VARDECL(int, pulses);
726    VARDECL(int, cap);
727    VARDECL(int, offsets);
728    VARDECL(int, fine_priority);
729    VARDECL(int, tf_res);
730    VARDECL(unsigned char, collapse_masks);
731    celt_sig *decode_mem[2];
732    celt_sig *out_syn[2];
733    opus_val16 *lpc;
734    opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
735 
736    int shortBlocks;
737    int isTransient;
738    int intra_ener;
739    const int CC = st->channels;
740    int LM, M;
741    int start;
742    int end;
743    int effEnd;
744    int codedBands;
745    int alloc_trim;
746    int postfilter_pitch;
747    opus_val16 postfilter_gain;
748    int intensity=0;
749    int dual_stereo=0;
750    opus_int32 total_bits;
751    opus_int32 balance;
752    opus_int32 tell;
753    int dynalloc_logp;
754    int postfilter_tapset;
755    int anti_collapse_rsv;
756    int anti_collapse_on=0;
757    int silence;
758    int C = st->stream_channels;
759    const OpusCustomMode *mode;
760    int nbEBands;
761    int overlap;
762    const opus_int16 *eBands;
763    ALLOC_STACK;
764 
765    mode = st->mode;
766    nbEBands = mode->nbEBands;
767    overlap = mode->overlap;
768    eBands = mode->eBands;
769    start = st->start;
770    end = st->end;
771    frame_size *= st->downsample;
772 
773    lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+overlap)*CC);
774    oldBandE = lpc+CC*LPC_ORDER;
775    oldLogE = oldBandE + 2*nbEBands;
776    oldLogE2 = oldLogE + 2*nbEBands;
777    backgroundLogE = oldLogE2  + 2*nbEBands;
778 
779 #ifdef CUSTOM_MODES
780    if (st->signalling && data!=NULL)
781    {
782       int data0=data[0];
783       /* Convert "standard mode" to Opus header */
784       if (mode->Fs==48000 && mode->shortMdctSize==120)
785       {
786          data0 = fromOpus(data0);
787          if (data0<0)
788             return OPUS_INVALID_PACKET;
789       }
790       st->end = end = IMAX(1, mode->effEBands-2*(data0>>5));
791       LM = (data0>>3)&0x3;
792       C = 1 + ((data0>>2)&0x1);
793       data++;
794       len--;
795       if (LM>mode->maxLM)
796          return OPUS_INVALID_PACKET;
797       if (frame_size < mode->shortMdctSize<<LM)
798          return OPUS_BUFFER_TOO_SMALL;
799       else
800          frame_size = mode->shortMdctSize<<LM;
801    } else {
802 #else
803    {
804 #endif
805       for (LM=0;LM<=mode->maxLM;LM++)
806          if (mode->shortMdctSize<<LM==frame_size)
807             break;
808       if (LM>mode->maxLM)
809          return OPUS_BAD_ARG;
810    }
811    M=1<<LM;
812 
813    if (len<0 || len>1275 || pcm==NULL)
814       return OPUS_BAD_ARG;
815 
816    N = M*mode->shortMdctSize;
817    c=0; do {
818       decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap);
819       out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N;
820    } while (++c<CC);
821 
822    effEnd = end;
823    if (effEnd > mode->effEBands)
824       effEnd = mode->effEBands;
825 
826    if (data == NULL || len<=1)
827    {
828       celt_decode_lost(st, N, LM);
829       deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum);
830       RESTORE_STACK;
831       return frame_size/st->downsample;
832    }
833 
834    /* Check if there are at least two packets received consecutively before
835     * turning on the pitch-based PLC */
836    st->skip_plc = st->loss_count != 0;
837 
838    if (dec == NULL)
839    {
840       ec_dec_init(&_dec,(unsigned char*)data,len);
841       dec = &_dec;
842    }
843 
844    if (C==1)
845    {
846       for (i=0;i<nbEBands;i++)
847          oldBandE[i]=MAX16(oldBandE[i],oldBandE[nbEBands+i]);
848    }
849 
850    total_bits = len*8;
851    tell = ec_tell(dec);
852 
853    if (tell >= total_bits)
854       silence = 1;
855    else if (tell==1)
856       silence = ec_dec_bit_logp(dec, 15);
857    else
858       silence = 0;
859    if (silence)
860    {
861       /* Pretend we've read all the remaining bits */
862       tell = len*8;
863       dec->nbits_total+=tell-ec_tell(dec);
864    }
865 
866    postfilter_gain = 0;
867    postfilter_pitch = 0;
868    postfilter_tapset = 0;
869    if (start==0 && tell+16 <= total_bits)
870    {
871       if(ec_dec_bit_logp(dec, 1))
872       {
873          int qg, octave;
874          octave = ec_dec_uint(dec, 6);
875          postfilter_pitch = (16<<octave)+ec_dec_bits(dec, 4+octave)-1;
876          qg = ec_dec_bits(dec, 3);
877          if (ec_tell(dec)+2<=total_bits)
878             postfilter_tapset = ec_dec_icdf(dec, tapset_icdf, 2);
879          postfilter_gain = QCONST16(.09375f,15)*(qg+1);
880       }
881       tell = ec_tell(dec);
882    }
883 
884    if (LM > 0 && tell+3 <= total_bits)
885    {
886       isTransient = ec_dec_bit_logp(dec, 3);
887       tell = ec_tell(dec);
888    }
889    else
890       isTransient = 0;
891 
892    if (isTransient)
893       shortBlocks = M;
894    else
895       shortBlocks = 0;
896 
897    /* Decode the global flags (first symbols in the stream) */
898    intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0;
899    /* Get band energies */
900    unquant_coarse_energy(mode, start, end, oldBandE,
901          intra_ener, dec, C, LM);
902 
903    ALLOC(tf_res, nbEBands, int);
904    tf_decode(start, end, isTransient, tf_res, LM, dec);
905 
906    tell = ec_tell(dec);
907    spread_decision = SPREAD_NORMAL;
908    if (tell+4 <= total_bits)
909       spread_decision = ec_dec_icdf(dec, spread_icdf, 5);
910 
911    ALLOC(cap, nbEBands, int);
912 
913    init_caps(mode,cap,LM,C);
914 
915    ALLOC(offsets, nbEBands, int);
916 
917    dynalloc_logp = 6;
918    total_bits<<=BITRES;
919    tell = ec_tell_frac(dec);
920    for (i=start;i<end;i++)
921    {
922       int width, quanta;
923       int dynalloc_loop_logp;
924       int boost;
925       width = C*(eBands[i+1]-eBands[i])<<LM;
926       /* quanta is 6 bits, but no more than 1 bit/sample
927          and no less than 1/8 bit/sample */
928       quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));
929       dynalloc_loop_logp = dynalloc_logp;
930       boost = 0;
931       while (tell+(dynalloc_loop_logp<<BITRES) < total_bits && boost < cap[i])
932       {
933          int flag;
934          flag = ec_dec_bit_logp(dec, dynalloc_loop_logp);
935          tell = ec_tell_frac(dec);
936          if (!flag)
937             break;
938          boost += quanta;
939          total_bits -= quanta;
940          dynalloc_loop_logp = 1;
941       }
942       offsets[i] = boost;
943       /* Making dynalloc more likely */
944       if (boost>0)
945          dynalloc_logp = IMAX(2, dynalloc_logp-1);
946    }
947 
948    ALLOC(fine_quant, nbEBands, int);
949    alloc_trim = tell+(6<<BITRES) <= total_bits ?
950          ec_dec_icdf(dec, trim_icdf, 7) : 5;
951 
952    bits = (((opus_int32)len*8)<<BITRES) - ec_tell_frac(dec) - 1;
953    anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0;
954    bits -= anti_collapse_rsv;
955 
956    ALLOC(pulses, nbEBands, int);
957    ALLOC(fine_priority, nbEBands, int);
958 
959    codedBands = compute_allocation(mode, start, end, offsets, cap,
960          alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
961          fine_quant, fine_priority, C, LM, dec, 0, 0, 0);
962 
963    unquant_fine_energy(mode, start, end, oldBandE, fine_quant, dec, C);
964 
965    c=0; do {
966       OPUS_MOVE(decode_mem[c], decode_mem[c]+N, DECODE_BUFFER_SIZE-N+overlap/2);
967    } while (++c<CC);
968 
969    /* Decode fixed codebook */
970    ALLOC(collapse_masks, C*nbEBands, unsigned char);
971 
972 #ifdef NORM_ALIASING_HACK
973    /* This is an ugly hack that breaks aliasing rules and would be easily broken,
974       but it saves almost 4kB of stack. */
975    X = (celt_norm*)(out_syn[CC-1]+overlap/2);
976 #else
977    ALLOC(X, C*N, celt_norm);   /**< Interleaved normalised MDCTs */
978 #endif
979 
980    quant_all_bands(0, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks,
981          NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res,
982          len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng, st->arch);
983 
984    if (anti_collapse_rsv > 0)
985    {
986       anti_collapse_on = ec_dec_bits(dec, 1);
987    }
988 
989    unquant_energy_finalise(mode, start, end, oldBandE,
990          fine_quant, fine_priority, len*8-ec_tell(dec), dec, C);
991 
992    if (anti_collapse_on)
993       anti_collapse(mode, X, collapse_masks, LM, C, N,
994             start, end, oldBandE, oldLogE, oldLogE2, pulses, st->rng, st->arch);
995 
996    if (silence)
997    {
998       for (i=0;i<C*nbEBands;i++)
999          oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
1000    }
1001 
1002    celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd,
1003                   C, CC, isTransient, LM, st->downsample, silence, st->arch);
1004 
1005    c=0; do {
1006       st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD);
1007       st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD);
1008       comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, mode->shortMdctSize,
1009             st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset,
1010             mode->window, overlap, st->arch);
1011       if (LM!=0)
1012          comb_filter(out_syn[c]+mode->shortMdctSize, out_syn[c]+mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-mode->shortMdctSize,
1013                st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset,
1014                mode->window, overlap, st->arch);
1015 
1016    } while (++c<CC);
1017    st->postfilter_period_old = st->postfilter_period;
1018    st->postfilter_gain_old = st->postfilter_gain;
1019    st->postfilter_tapset_old = st->postfilter_tapset;
1020    st->postfilter_period = postfilter_pitch;
1021    st->postfilter_gain = postfilter_gain;
1022    st->postfilter_tapset = postfilter_tapset;
1023    if (LM!=0)
1024    {
1025       st->postfilter_period_old = st->postfilter_period;
1026       st->postfilter_gain_old = st->postfilter_gain;
1027       st->postfilter_tapset_old = st->postfilter_tapset;
1028    }
1029 
1030    if (C==1)
1031       OPUS_COPY(&oldBandE[nbEBands], oldBandE, nbEBands);
1032 
1033    /* In case start or end were to change */
1034    if (!isTransient)
1035    {
1036       opus_val16 max_background_increase;
1037       OPUS_COPY(oldLogE2, oldLogE, 2*nbEBands);
1038       OPUS_COPY(oldLogE, oldBandE, 2*nbEBands);
1039       /* In normal circumstances, we only allow the noise floor to increase by
1040          up to 2.4 dB/second, but when we're in DTX, we allow up to 6 dB
1041          increase for each update.*/
1042       if (st->loss_count < 10)
1043          max_background_increase = M*QCONST16(0.001f,DB_SHIFT);
1044       else
1045          max_background_increase = QCONST16(1.f,DB_SHIFT);
1046       for (i=0;i<2*nbEBands;i++)
1047          backgroundLogE[i] = MIN16(backgroundLogE[i] + max_background_increase, oldBandE[i]);
1048    } else {
1049       for (i=0;i<2*nbEBands;i++)
1050          oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
1051    }
1052    c=0; do
1053    {
1054       for (i=0;i<start;i++)
1055       {
1056          oldBandE[c*nbEBands+i]=0;
1057          oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
1058       }
1059       for (i=end;i<nbEBands;i++)
1060       {
1061          oldBandE[c*nbEBands+i]=0;
1062          oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
1063       }
1064    } while (++c<2);
1065    st->rng = dec->rng;
1066 
1067    deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum);
1068    st->loss_count = 0;
1069    RESTORE_STACK;
1070    if (ec_tell(dec) > 8*len)
1071       return OPUS_INTERNAL_ERROR;
1072    if(ec_get_error(dec))
1073       st->error = 1;
1074    return frame_size/st->downsample;
1075 }
1076 
1077 
1078 #ifdef CUSTOM_MODES
1079 
1080 #ifdef FIXED_POINT
1081 int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size)
1082 {
1083    return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0);
1084 }
1085 
1086 #ifndef DISABLE_FLOAT_API
1087 int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size)
1088 {
1089    int j, ret, C, N;
1090    VARDECL(opus_int16, out);
1091    ALLOC_STACK;
1092 
1093    if (pcm==NULL)
1094       return OPUS_BAD_ARG;
1095 
1096    C = st->channels;
1097    N = frame_size;
1098 
1099    ALLOC(out, C*N, opus_int16);
1100    ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0);
1101    if (ret>0)
1102       for (j=0;j<C*ret;j++)
1103          pcm[j]=out[j]*(1.f/32768.f);
1104 
1105    RESTORE_STACK;
1106    return ret;
1107 }
1108 #endif /* DISABLE_FLOAT_API */
1109 
1110 #else
1111 
1112 int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size)
1113 {
1114    return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0);
1115 }
1116 
1117 int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size)
1118 {
1119    int j, ret, C, N;
1120    VARDECL(celt_sig, out);
1121    ALLOC_STACK;
1122 
1123    if (pcm==NULL)
1124       return OPUS_BAD_ARG;
1125 
1126    C = st->channels;
1127    N = frame_size;
1128    ALLOC(out, C*N, celt_sig);
1129 
1130    ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0);
1131 
1132    if (ret>0)
1133       for (j=0;j<C*ret;j++)
1134          pcm[j] = FLOAT2INT16 (out[j]);
1135 
1136    RESTORE_STACK;
1137    return ret;
1138 }
1139 
1140 #endif
1141 #endif /* CUSTOM_MODES */
1142 
1143 int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
1144 {
1145    va_list ap;
1146 
1147    va_start(ap, request);
1148    switch (request)
1149    {
1150       case CELT_SET_START_BAND_REQUEST:
1151       {
1152          opus_int32 value = va_arg(ap, opus_int32);
1153          if (value<0 || value>=st->mode->nbEBands)
1154             goto bad_arg;
1155          st->start = value;
1156       }
1157       break;
1158       case CELT_SET_END_BAND_REQUEST:
1159       {
1160          opus_int32 value = va_arg(ap, opus_int32);
1161          if (value<1 || value>st->mode->nbEBands)
1162             goto bad_arg;
1163          st->end = value;
1164       }
1165       break;
1166       case CELT_SET_CHANNELS_REQUEST:
1167       {
1168          opus_int32 value = va_arg(ap, opus_int32);
1169          if (value<1 || value>2)
1170             goto bad_arg;
1171          st->stream_channels = value;
1172       }
1173       break;
1174       case CELT_GET_AND_CLEAR_ERROR_REQUEST:
1175       {
1176          opus_int32 *value = va_arg(ap, opus_int32*);
1177          if (value==NULL)
1178             goto bad_arg;
1179          *value=st->error;
1180          st->error = 0;
1181       }
1182       break;
1183       case OPUS_GET_LOOKAHEAD_REQUEST:
1184       {
1185          opus_int32 *value = va_arg(ap, opus_int32*);
1186          if (value==NULL)
1187             goto bad_arg;
1188          *value = st->overlap/st->downsample;
1189       }
1190       break;
1191       case OPUS_RESET_STATE:
1192       {
1193          int i;
1194          opus_val16 *lpc, *oldBandE, *oldLogE, *oldLogE2;
1195          lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels);
1196          oldBandE = lpc+st->channels*LPC_ORDER;
1197          oldLogE = oldBandE + 2*st->mode->nbEBands;
1198          oldLogE2 = oldLogE + 2*st->mode->nbEBands;
1199          OPUS_CLEAR((char*)&st->DECODER_RESET_START,
1200                opus_custom_decoder_get_size(st->mode, st->channels)-
1201                ((char*)&st->DECODER_RESET_START - (char*)st));
1202          for (i=0;i<2*st->mode->nbEBands;i++)
1203             oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT);
1204          st->skip_plc = 1;
1205       }
1206       break;
1207       case OPUS_GET_PITCH_REQUEST:
1208       {
1209          opus_int32 *value = va_arg(ap, opus_int32*);
1210          if (value==NULL)
1211             goto bad_arg;
1212          *value = st->postfilter_period;
1213       }
1214       break;
1215       case CELT_GET_MODE_REQUEST:
1216       {
1217          const CELTMode ** value = va_arg(ap, const CELTMode**);
1218          if (value==0)
1219             goto bad_arg;
1220          *value=st->mode;
1221       }
1222       break;
1223       case CELT_SET_SIGNALLING_REQUEST:
1224       {
1225          opus_int32 value = va_arg(ap, opus_int32);
1226          st->signalling = value;
1227       }
1228       break;
1229       case OPUS_GET_FINAL_RANGE_REQUEST:
1230       {
1231          opus_uint32 * value = va_arg(ap, opus_uint32 *);
1232          if (value==0)
1233             goto bad_arg;
1234          *value=st->rng;
1235       }
1236       break;
1237       default:
1238          goto bad_request;
1239    }
1240    va_end(ap);
1241    return OPUS_OK;
1242 bad_arg:
1243    va_end(ap);
1244    return OPUS_BAD_ARG;
1245 bad_request:
1246       va_end(ap);
1247   return OPUS_UNIMPLEMENTED;
1248 }
1249