Prevent overflows in PLC celt_iir()
[opus.git] / celt / celt_decoder.c
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
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
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
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
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
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
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
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
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] = ADD32(HALF32(freq[i]), HALF32(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
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
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
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), 9);
634          }
635 #ifdef FIXED_POINT
636          /* For fixed-point, apply bandwidth expansion until we can guarantee that
637             no overflow can happen in the IIR filter. This means:
638             attenuation*32768*sum(abs(filter)) < 2^31 */
639          while (1) {
640             opus_val16 tmp=Q15ONE;
641             opus_val32 sum=QCONST16(1., SIG_SHIFT);
642             for (i=0;i<LPC_ORDER;i++)
643                sum += ABS16(lpc[c*LPC_ORDER+i]);
644             if (MULT16_32_Q15(attenuation, sum) < 65535) break;
645             for (i=0;i<LPC_ORDER;i++)
646             {
647                tmp = MULT16_16_Q15(QCONST16(.99f,15), tmp);
648                lpc[c*LPC_ORDER+i] = MULT16_16_Q15(lpc[c*LPC_ORDER+i], tmp);
649             }
650          }
651 #endif
652          {
653             opus_val16 lpc_mem[LPC_ORDER];
654             /* Copy the last decoded samples (prior to the overlap region) to
655                synthesis filter memory so we can have a continuous signal. */
656             for (i=0;i<LPC_ORDER;i++)
657                lpc_mem[i] = ROUND16(buf[DECODE_BUFFER_SIZE-N-1-i], SIG_SHIFT);
658             /* Apply the synthesis filter to convert the excitation back into
659                the signal domain. */
660             celt_iir(buf+DECODE_BUFFER_SIZE-N, lpc+c*LPC_ORDER,
661                   buf+DECODE_BUFFER_SIZE-N, extrapolation_len, LPC_ORDER,
662                   lpc_mem, st->arch);
663          }
664
665          /* Check if the synthesis energy is higher than expected, which can
666             happen with the signal changes during our window. If so,
667             attenuate. */
668          {
669             opus_val32 S2=0;
670             for (i=0;i<extrapolation_len;i++)
671             {
672                opus_val16 tmp = ROUND16(buf[DECODE_BUFFER_SIZE-N+i], SIG_SHIFT);
673                S2 += SHR32(MULT16_16(tmp, tmp), 9);
674             }
675             /* This checks for an "explosion" in the synthesis. */
676 #ifdef FIXED_POINT
677             if (!(S1 > SHR32(S2,2)))
678 #else
679             /* The float test is written this way to catch NaNs in the output
680                of the IIR filter at the same time. */
681             if (!(S1 > 0.2f*S2))
682 #endif
683             {
684                for (i=0;i<extrapolation_len;i++)
685                   buf[DECODE_BUFFER_SIZE-N+i] = 0;
686             } else if (S1 < S2)
687             {
688                opus_val16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
689                for (i=0;i<overlap;i++)
690                {
691                   opus_val16 tmp_g = Q15ONE
692                         - MULT16_16_Q15(window[i], Q15ONE-ratio);
693                   buf[DECODE_BUFFER_SIZE-N+i] =
694                         MULT16_32_Q15(tmp_g, buf[DECODE_BUFFER_SIZE-N+i]);
695                }
696                for (i=overlap;i<extrapolation_len;i++)
697                {
698                   buf[DECODE_BUFFER_SIZE-N+i] =
699                         MULT16_32_Q15(ratio, buf[DECODE_BUFFER_SIZE-N+i]);
700                }
701             }
702          }
703
704          /* Apply the pre-filter to the MDCT overlap for the next frame because
705             the post-filter will be re-applied in the decoder after the MDCT
706             overlap. */
707          comb_filter(etmp, buf+DECODE_BUFFER_SIZE,
708               st->postfilter_period, st->postfilter_period, overlap,
709               -st->postfilter_gain, -st->postfilter_gain,
710               st->postfilter_tapset, st->postfilter_tapset, NULL, 0, st->arch);
711
712          /* Simulate TDAC on the concealed audio so that it blends with the
713             MDCT of the next frame. */
714          for (i=0;i<overlap/2;i++)
715          {
716             buf[DECODE_BUFFER_SIZE+i] =
717                MULT16_32_Q15(window[i], etmp[overlap-1-i])
718                + MULT16_32_Q15(window[overlap-i-1], etmp[i]);
719          }
720       } while (++c<C);
721    }
722
723    st->loss_count = loss_count+1;
724
725    RESTORE_STACK;
726 }
727
728 int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data,
729       int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum)
730 {
731    int c, i, N;
732    int spread_decision;
733    opus_int32 bits;
734    ec_dec _dec;
735 #ifdef NORM_ALIASING_HACK
736    celt_norm *X;
737 #else
738    VARDECL(celt_norm, X);
739 #endif
740    VARDECL(int, fine_quant);
741    VARDECL(int, pulses);
742    VARDECL(int, cap);
743    VARDECL(int, offsets);
744    VARDECL(int, fine_priority);
745    VARDECL(int, tf_res);
746    VARDECL(unsigned char, collapse_masks);
747    celt_sig *decode_mem[2];
748    celt_sig *out_syn[2];
749    opus_val16 *lpc;
750    opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
751
752    int shortBlocks;
753    int isTransient;
754    int intra_ener;
755    const int CC = st->channels;
756    int LM, M;
757    int start;
758    int end;
759    int effEnd;
760    int codedBands;
761    int alloc_trim;
762    int postfilter_pitch;
763    opus_val16 postfilter_gain;
764    int intensity=0;
765    int dual_stereo=0;
766    opus_int32 total_bits;
767    opus_int32 balance;
768    opus_int32 tell;
769    int dynalloc_logp;
770    int postfilter_tapset;
771    int anti_collapse_rsv;
772    int anti_collapse_on=0;
773    int silence;
774    int C = st->stream_channels;
775    const OpusCustomMode *mode;
776    int nbEBands;
777    int overlap;
778    const opus_int16 *eBands;
779    ALLOC_STACK;
780
781    mode = st->mode;
782    nbEBands = mode->nbEBands;
783    overlap = mode->overlap;
784    eBands = mode->eBands;
785    start = st->start;
786    end = st->end;
787    frame_size *= st->downsample;
788
789    lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+overlap)*CC);
790    oldBandE = lpc+CC*LPC_ORDER;
791    oldLogE = oldBandE + 2*nbEBands;
792    oldLogE2 = oldLogE + 2*nbEBands;
793    backgroundLogE = oldLogE2  + 2*nbEBands;
794
795 #ifdef CUSTOM_MODES
796    if (st->signalling && data!=NULL)
797    {
798       int data0=data[0];
799       /* Convert "standard mode" to Opus header */
800       if (mode->Fs==48000 && mode->shortMdctSize==120)
801       {
802          data0 = fromOpus(data0);
803          if (data0<0)
804             return OPUS_INVALID_PACKET;
805       }
806       st->end = end = IMAX(1, mode->effEBands-2*(data0>>5));
807       LM = (data0>>3)&0x3;
808       C = 1 + ((data0>>2)&0x1);
809       data++;
810       len--;
811       if (LM>mode->maxLM)
812          return OPUS_INVALID_PACKET;
813       if (frame_size < mode->shortMdctSize<<LM)
814          return OPUS_BUFFER_TOO_SMALL;
815       else
816          frame_size = mode->shortMdctSize<<LM;
817    } else {
818 #else
819    {
820 #endif
821       for (LM=0;LM<=mode->maxLM;LM++)
822          if (mode->shortMdctSize<<LM==frame_size)
823             break;
824       if (LM>mode->maxLM)
825          return OPUS_BAD_ARG;
826    }
827    M=1<<LM;
828
829    if (len<0 || len>1275 || pcm==NULL)
830       return OPUS_BAD_ARG;
831
832    N = M*mode->shortMdctSize;
833    c=0; do {
834       decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap);
835       out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N;
836    } while (++c<CC);
837
838    effEnd = end;
839    if (effEnd > mode->effEBands)
840       effEnd = mode->effEBands;
841
842    if (data == NULL || len<=1)
843    {
844       celt_decode_lost(st, N, LM);
845       deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum);
846       RESTORE_STACK;
847       return frame_size/st->downsample;
848    }
849
850    /* Check if there are at least two packets received consecutively before
851     * turning on the pitch-based PLC */
852    st->skip_plc = st->loss_count != 0;
853
854    if (dec == NULL)
855    {
856       ec_dec_init(&_dec,(unsigned char*)data,len);
857       dec = &_dec;
858    }
859
860    if (C==1)
861    {
862       for (i=0;i<nbEBands;i++)
863          oldBandE[i]=MAX16(oldBandE[i],oldBandE[nbEBands+i]);
864    }
865
866    total_bits = len*8;
867    tell = ec_tell(dec);
868
869    if (tell >= total_bits)
870       silence = 1;
871    else if (tell==1)
872       silence = ec_dec_bit_logp(dec, 15);
873    else
874       silence = 0;
875    if (silence)
876    {
877       /* Pretend we've read all the remaining bits */
878       tell = len*8;
879       dec->nbits_total+=tell-ec_tell(dec);
880    }
881
882    postfilter_gain = 0;
883    postfilter_pitch = 0;
884    postfilter_tapset = 0;
885    if (start==0 && tell+16 <= total_bits)
886    {
887       if(ec_dec_bit_logp(dec, 1))
888       {
889          int qg, octave;
890          octave = ec_dec_uint(dec, 6);
891          postfilter_pitch = (16<<octave)+ec_dec_bits(dec, 4+octave)-1;
892          qg = ec_dec_bits(dec, 3);
893          if (ec_tell(dec)+2<=total_bits)
894             postfilter_tapset = ec_dec_icdf(dec, tapset_icdf, 2);
895          postfilter_gain = QCONST16(.09375f,15)*(qg+1);
896       }
897       tell = ec_tell(dec);
898    }
899
900    if (LM > 0 && tell+3 <= total_bits)
901    {
902       isTransient = ec_dec_bit_logp(dec, 3);
903       tell = ec_tell(dec);
904    }
905    else
906       isTransient = 0;
907
908    if (isTransient)
909       shortBlocks = M;
910    else
911       shortBlocks = 0;
912
913    /* Decode the global flags (first symbols in the stream) */
914    intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0;
915    /* Get band energies */
916    unquant_coarse_energy(mode, start, end, oldBandE,
917          intra_ener, dec, C, LM);
918
919    ALLOC(tf_res, nbEBands, int);
920    tf_decode(start, end, isTransient, tf_res, LM, dec);
921
922    tell = ec_tell(dec);
923    spread_decision = SPREAD_NORMAL;
924    if (tell+4 <= total_bits)
925       spread_decision = ec_dec_icdf(dec, spread_icdf, 5);
926
927    ALLOC(cap, nbEBands, int);
928
929    init_caps(mode,cap,LM,C);
930
931    ALLOC(offsets, nbEBands, int);
932
933    dynalloc_logp = 6;
934    total_bits<<=BITRES;
935    tell = ec_tell_frac(dec);
936    for (i=start;i<end;i++)
937    {
938       int width, quanta;
939       int dynalloc_loop_logp;
940       int boost;
941       width = C*(eBands[i+1]-eBands[i])<<LM;
942       /* quanta is 6 bits, but no more than 1 bit/sample
943          and no less than 1/8 bit/sample */
944       quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));
945       dynalloc_loop_logp = dynalloc_logp;
946       boost = 0;
947       while (tell+(dynalloc_loop_logp<<BITRES) < total_bits && boost < cap[i])
948       {
949          int flag;
950          flag = ec_dec_bit_logp(dec, dynalloc_loop_logp);
951          tell = ec_tell_frac(dec);
952          if (!flag)
953             break;
954          boost += quanta;
955          total_bits -= quanta;
956          dynalloc_loop_logp = 1;
957       }
958       offsets[i] = boost;
959       /* Making dynalloc more likely */
960       if (boost>0)
961          dynalloc_logp = IMAX(2, dynalloc_logp-1);
962    }
963
964    ALLOC(fine_quant, nbEBands, int);
965    alloc_trim = tell+(6<<BITRES) <= total_bits ?
966          ec_dec_icdf(dec, trim_icdf, 7) : 5;
967
968    bits = (((opus_int32)len*8)<<BITRES) - ec_tell_frac(dec) - 1;
969    anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0;
970    bits -= anti_collapse_rsv;
971
972    ALLOC(pulses, nbEBands, int);
973    ALLOC(fine_priority, nbEBands, int);
974
975    codedBands = compute_allocation(mode, start, end, offsets, cap,
976          alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
977          fine_quant, fine_priority, C, LM, dec, 0, 0, 0);
978
979    unquant_fine_energy(mode, start, end, oldBandE, fine_quant, dec, C);
980
981    c=0; do {
982       OPUS_MOVE(decode_mem[c], decode_mem[c]+N, DECODE_BUFFER_SIZE-N+overlap/2);
983    } while (++c<CC);
984
985    /* Decode fixed codebook */
986    ALLOC(collapse_masks, C*nbEBands, unsigned char);
987
988 #ifdef NORM_ALIASING_HACK
989    /* This is an ugly hack that breaks aliasing rules and would be easily broken,
990       but it saves almost 4kB of stack. */
991    X = (celt_norm*)(out_syn[CC-1]+overlap/2);
992 #else
993    ALLOC(X, C*N, celt_norm);   /**< Interleaved normalised MDCTs */
994 #endif
995
996    quant_all_bands(0, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks,
997          NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res,
998          len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng, st->arch);
999
1000    if (anti_collapse_rsv > 0)
1001    {
1002       anti_collapse_on = ec_dec_bits(dec, 1);
1003    }
1004
1005    unquant_energy_finalise(mode, start, end, oldBandE,
1006          fine_quant, fine_priority, len*8-ec_tell(dec), dec, C);
1007
1008    if (anti_collapse_on)
1009       anti_collapse(mode, X, collapse_masks, LM, C, N,
1010             start, end, oldBandE, oldLogE, oldLogE2, pulses, st->rng, st->arch);
1011
1012    if (silence)
1013    {
1014       for (i=0;i<C*nbEBands;i++)
1015          oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
1016    }
1017
1018    celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd,
1019                   C, CC, isTransient, LM, st->downsample, silence, st->arch);
1020
1021    c=0; do {
1022       st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD);
1023       st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD);
1024       comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, mode->shortMdctSize,
1025             st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset,
1026             mode->window, overlap, st->arch);
1027       if (LM!=0)
1028          comb_filter(out_syn[c]+mode->shortMdctSize, out_syn[c]+mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-mode->shortMdctSize,
1029                st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset,
1030                mode->window, overlap, st->arch);
1031
1032    } while (++c<CC);
1033    st->postfilter_period_old = st->postfilter_period;
1034    st->postfilter_gain_old = st->postfilter_gain;
1035    st->postfilter_tapset_old = st->postfilter_tapset;
1036    st->postfilter_period = postfilter_pitch;
1037    st->postfilter_gain = postfilter_gain;
1038    st->postfilter_tapset = postfilter_tapset;
1039    if (LM!=0)
1040    {
1041       st->postfilter_period_old = st->postfilter_period;
1042       st->postfilter_gain_old = st->postfilter_gain;
1043       st->postfilter_tapset_old = st->postfilter_tapset;
1044    }
1045
1046    if (C==1)
1047       OPUS_COPY(&oldBandE[nbEBands], oldBandE, nbEBands);
1048
1049    /* In case start or end were to change */
1050    if (!isTransient)
1051    {
1052       opus_val16 max_background_increase;
1053       OPUS_COPY(oldLogE2, oldLogE, 2*nbEBands);
1054       OPUS_COPY(oldLogE, oldBandE, 2*nbEBands);
1055       /* In normal circumstances, we only allow the noise floor to increase by
1056          up to 2.4 dB/second, but when we're in DTX, we allow up to 6 dB
1057          increase for each update.*/
1058       if (st->loss_count < 10)
1059          max_background_increase = M*QCONST16(0.001f,DB_SHIFT);
1060       else
1061          max_background_increase = QCONST16(1.f,DB_SHIFT);
1062       for (i=0;i<2*nbEBands;i++)
1063          backgroundLogE[i] = MIN16(backgroundLogE[i] + max_background_increase, oldBandE[i]);
1064    } else {
1065       for (i=0;i<2*nbEBands;i++)
1066          oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
1067    }
1068    c=0; do
1069    {
1070       for (i=0;i<start;i++)
1071       {
1072          oldBandE[c*nbEBands+i]=0;
1073          oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
1074       }
1075       for (i=end;i<nbEBands;i++)
1076       {
1077          oldBandE[c*nbEBands+i]=0;
1078          oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
1079       }
1080    } while (++c<2);
1081    st->rng = dec->rng;
1082
1083    deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum);
1084    st->loss_count = 0;
1085    RESTORE_STACK;
1086    if (ec_tell(dec) > 8*len)
1087       return OPUS_INTERNAL_ERROR;
1088    if(ec_get_error(dec))
1089       st->error = 1;
1090    return frame_size/st->downsample;
1091 }
1092
1093
1094 #ifdef CUSTOM_MODES
1095
1096 #ifdef FIXED_POINT
1097 int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size)
1098 {
1099    return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0);
1100 }
1101
1102 #ifndef DISABLE_FLOAT_API
1103 int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size)
1104 {
1105    int j, ret, C, N;
1106    VARDECL(opus_int16, out);
1107    ALLOC_STACK;
1108
1109    if (pcm==NULL)
1110       return OPUS_BAD_ARG;
1111
1112    C = st->channels;
1113    N = frame_size;
1114
1115    ALLOC(out, C*N, opus_int16);
1116    ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0);
1117    if (ret>0)
1118       for (j=0;j<C*ret;j++)
1119          pcm[j]=out[j]*(1.f/32768.f);
1120
1121    RESTORE_STACK;
1122    return ret;
1123 }
1124 #endif /* DISABLE_FLOAT_API */
1125
1126 #else
1127
1128 int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size)
1129 {
1130    return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0);
1131 }
1132
1133 int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size)
1134 {
1135    int j, ret, C, N;
1136    VARDECL(celt_sig, out);
1137    ALLOC_STACK;
1138
1139    if (pcm==NULL)
1140       return OPUS_BAD_ARG;
1141
1142    C = st->channels;
1143    N = frame_size;
1144    ALLOC(out, C*N, celt_sig);
1145
1146    ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0);
1147
1148    if (ret>0)
1149       for (j=0;j<C*ret;j++)
1150          pcm[j] = FLOAT2INT16 (out[j]);
1151
1152    RESTORE_STACK;
1153    return ret;
1154 }
1155
1156 #endif
1157 #endif /* CUSTOM_MODES */
1158
1159 int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
1160 {
1161    va_list ap;
1162
1163    va_start(ap, request);
1164    switch (request)
1165    {
1166       case CELT_SET_START_BAND_REQUEST:
1167       {
1168          opus_int32 value = va_arg(ap, opus_int32);
1169          if (value<0 || value>=st->mode->nbEBands)
1170             goto bad_arg;
1171          st->start = value;
1172       }
1173       break;
1174       case CELT_SET_END_BAND_REQUEST:
1175       {
1176          opus_int32 value = va_arg(ap, opus_int32);
1177          if (value<1 || value>st->mode->nbEBands)
1178             goto bad_arg;
1179          st->end = value;
1180       }
1181       break;
1182       case CELT_SET_CHANNELS_REQUEST:
1183       {
1184          opus_int32 value = va_arg(ap, opus_int32);
1185          if (value<1 || value>2)
1186             goto bad_arg;
1187          st->stream_channels = value;
1188       }
1189       break;
1190       case CELT_GET_AND_CLEAR_ERROR_REQUEST:
1191       {
1192          opus_int32 *value = va_arg(ap, opus_int32*);
1193          if (value==NULL)
1194             goto bad_arg;
1195          *value=st->error;
1196          st->error = 0;
1197       }
1198       break;
1199       case OPUS_GET_LOOKAHEAD_REQUEST:
1200       {
1201          opus_int32 *value = va_arg(ap, opus_int32*);
1202          if (value==NULL)
1203             goto bad_arg;
1204          *value = st->overlap/st->downsample;
1205       }
1206       break;
1207       case OPUS_RESET_STATE:
1208       {
1209          int i;
1210          opus_val16 *lpc, *oldBandE, *oldLogE, *oldLogE2;
1211          lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels);
1212          oldBandE = lpc+st->channels*LPC_ORDER;
1213          oldLogE = oldBandE + 2*st->mode->nbEBands;
1214          oldLogE2 = oldLogE + 2*st->mode->nbEBands;
1215          OPUS_CLEAR((char*)&st->DECODER_RESET_START,
1216                opus_custom_decoder_get_size(st->mode, st->channels)-
1217                ((char*)&st->DECODER_RESET_START - (char*)st));
1218          for (i=0;i<2*st->mode->nbEBands;i++)
1219             oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT);
1220          st->skip_plc = 1;
1221       }
1222       break;
1223       case OPUS_GET_PITCH_REQUEST:
1224       {
1225          opus_int32 *value = va_arg(ap, opus_int32*);
1226          if (value==NULL)
1227             goto bad_arg;
1228          *value = st->postfilter_period;
1229       }
1230       break;
1231       case CELT_GET_MODE_REQUEST:
1232       {
1233          const CELTMode ** value = va_arg(ap, const CELTMode**);
1234          if (value==0)
1235             goto bad_arg;
1236          *value=st->mode;
1237       }
1238       break;
1239       case CELT_SET_SIGNALLING_REQUEST:
1240       {
1241          opus_int32 value = va_arg(ap, opus_int32);
1242          st->signalling = value;
1243       }
1244       break;
1245       case OPUS_GET_FINAL_RANGE_REQUEST:
1246       {
1247          opus_uint32 * value = va_arg(ap, opus_uint32 *);
1248          if (value==0)
1249             goto bad_arg;
1250          *value=st->rng;
1251       }
1252       break;
1253       default:
1254          goto bad_request;
1255    }
1256    va_end(ap);
1257    return OPUS_OK;
1258 bad_arg:
1259    va_end(ap);
1260    return OPUS_BAD_ARG;
1261 bad_request:
1262       va_end(ap);
1263   return OPUS_UNIMPLEMENTED;
1264 }