Use SPREAD_AGGRESSIVE on non-transient hybrid frames
[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] = 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
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), 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
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 }