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