summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libopus/celt/celt_decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libopus/celt/celt_decoder.c')
-rw-r--r--lib/rbcodec/codecs/libopus/celt/celt_decoder.c263
1 files changed, 197 insertions, 66 deletions
diff --git a/lib/rbcodec/codecs/libopus/celt/celt_decoder.c b/lib/rbcodec/codecs/libopus/celt/celt_decoder.c
index 8af96b7931..e6efce9358 100644
--- a/lib/rbcodec/codecs/libopus/celt/celt_decoder.c
+++ b/lib/rbcodec/codecs/libopus/celt/celt_decoder.c
@@ -51,6 +51,14 @@
51#include "celt_lpc.h" 51#include "celt_lpc.h"
52#include "vq.h" 52#include "vq.h"
53 53
54/* The maximum pitch lag to allow in the pitch-based PLC. It's possible to save
55 CPU time in the PLC pitch search by making this smaller than MAX_PERIOD. The
56 current value corresponds to a pitch of 66.67 Hz. */
57#define PLC_PITCH_LAG_MAX (720)
58/* The minimum pitch lag to allow in the pitch-based PLC. This corresponds to a
59 pitch of 480 Hz. */
60#define PLC_PITCH_LAG_MIN (100)
61
54#if defined(SMALL_FOOTPRINT) && defined(FIXED_POINT) 62#if defined(SMALL_FOOTPRINT) && defined(FIXED_POINT)
55#define NORM_ALIASING_HACK 63#define NORM_ALIASING_HACK
56#endif 64#endif
@@ -73,6 +81,7 @@ struct OpusCustomDecoder {
73 int downsample; 81 int downsample;
74 int start, end; 82 int start, end;
75 int signalling; 83 int signalling;
84 int disable_inv;
76 int arch; 85 int arch;
77 86
78 /* Everything beyond this point gets cleared on a reset */ 87 /* Everything beyond this point gets cleared on a reset */
@@ -82,6 +91,7 @@ struct OpusCustomDecoder {
82 int error; 91 int error;
83 int last_pitch_index; 92 int last_pitch_index;
84 int loss_count; 93 int loss_count;
94 int skip_plc;
85 int postfilter_period; 95 int postfilter_period;
86 int postfilter_period_old; 96 int postfilter_period_old;
87 opus_val16 postfilter_gain; 97 opus_val16 postfilter_gain;
@@ -99,6 +109,38 @@ struct OpusCustomDecoder {
99 /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */ 109 /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */
100}; 110};
101 111
112#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
113/* Make basic checks on the CELT state to ensure we don't end
114 up writing all over memory. */
115void validate_celt_decoder(CELTDecoder *st)
116{
117#ifndef CUSTOM_MODES
118 celt_assert(st->mode == opus_custom_mode_create(48000, 960, NULL));
119 celt_assert(st->overlap == 120);
120#endif
121 celt_assert(st->channels == 1 || st->channels == 2);
122 celt_assert(st->stream_channels == 1 || st->stream_channels == 2);
123 celt_assert(st->downsample > 0);
124 celt_assert(st->start == 0 || st->start == 17);
125 celt_assert(st->start < st->end);
126 celt_assert(st->end <= 21);
127#ifdef OPUS_ARCHMASK
128 celt_assert(st->arch >= 0);
129 celt_assert(st->arch <= OPUS_ARCHMASK);
130#endif
131 celt_assert(st->last_pitch_index <= PLC_PITCH_LAG_MAX);
132 celt_assert(st->last_pitch_index >= PLC_PITCH_LAG_MIN || st->last_pitch_index == 0);
133 celt_assert(st->postfilter_period < MAX_PERIOD);
134 celt_assert(st->postfilter_period >= COMBFILTER_MINPERIOD || st->postfilter_period == 0);
135 celt_assert(st->postfilter_period_old < MAX_PERIOD);
136 celt_assert(st->postfilter_period_old >= COMBFILTER_MINPERIOD || st->postfilter_period_old == 0);
137 celt_assert(st->postfilter_tapset <= 2);
138 celt_assert(st->postfilter_tapset >= 0);
139 celt_assert(st->postfilter_tapset_old <= 2);
140 celt_assert(st->postfilter_tapset_old >= 0);
141}
142#endif
143
102int celt_decoder_get_size(int channels) 144int celt_decoder_get_size(int channels)
103{ 145{
104 const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); 146 const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
@@ -162,10 +204,13 @@ OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMod
162 st->start = 0; 204 st->start = 0;
163 st->end = st->mode->effEBands; 205 st->end = st->mode->effEBands;
164 st->signalling = 1; 206 st->signalling = 1;
207#ifndef DISABLE_UPDATE_DRAFT
208 st->disable_inv = channels == 1;
209#else
210 st->disable_inv = 0;
211#endif
165 st->arch = opus_select_arch(); 212 st->arch = opus_select_arch();
166 213
167 st->loss_count = 0;
168
169 opus_custom_decoder_ctl(st, OPUS_RESET_STATE); 214 opus_custom_decoder_ctl(st, OPUS_RESET_STATE);
170 215
171 return OPUS_OK; 216 return OPUS_OK;
@@ -178,6 +223,36 @@ void opus_custom_decoder_destroy(CELTDecoder *st)
178} 223}
179#endif /* CUSTOM_MODES */ 224#endif /* CUSTOM_MODES */
180 225
226#ifndef CUSTOM_MODES
227/* Special case for stereo with no downsampling and no accumulation. This is
228 quite common and we can make it faster by processing both channels in the
229 same loop, reducing overhead due to the dependency loop in the IIR filter. */
230static void deemphasis_stereo_simple(celt_sig *in[], opus_val16 *pcm, int N, const opus_val16 coef0,
231 celt_sig *mem)
232{
233 celt_sig * OPUS_RESTRICT x0;
234 celt_sig * OPUS_RESTRICT x1;
235 celt_sig m0, m1;
236 int j;
237 x0=in[0];
238 x1=in[1];
239 m0 = mem[0];
240 m1 = mem[1];
241 for (j=0;j<N;j++)
242 {
243 celt_sig tmp0, tmp1;
244 /* Add VERY_SMALL to x[] first to reduce dependency chain. */
245 tmp0 = x0[j] + VERY_SMALL + m0;
246 tmp1 = x1[j] + VERY_SMALL + m1;
247 m0 = MULT16_32_Q15(coef0, tmp0);
248 m1 = MULT16_32_Q15(coef0, tmp1);
249 pcm[2*j ] = SCALEOUT(SIG2WORD16(tmp0));
250 pcm[2*j+1] = SCALEOUT(SIG2WORD16(tmp1));
251 }
252 mem[0] = m0;
253 mem[1] = m1;
254}
255#endif
181 256
182#ifndef RESYNTH 257#ifndef RESYNTH
183static 258static
@@ -191,6 +266,14 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
191 opus_val16 coef0; 266 opus_val16 coef0;
192 VARDECL(celt_sig, scratch); 267 VARDECL(celt_sig, scratch);
193 SAVE_STACK; 268 SAVE_STACK;
269#ifndef CUSTOM_MODES
270 /* Short version for common case. */
271 if (downsample == 1 && C == 2 && !accum)
272 {
273 deemphasis_stereo_simple(in, pcm, N, coef[0], mem);
274 return;
275 }
276#endif
194#ifndef FIXED_POINT 277#ifndef FIXED_POINT
195 (void)accum; 278 (void)accum;
196 celt_assert(accum==0); 279 celt_assert(accum==0);
@@ -226,7 +309,7 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
226 /* Shortcut for the standard (non-custom modes) case */ 309 /* Shortcut for the standard (non-custom modes) case */
227 for (j=0;j<N;j++) 310 for (j=0;j<N;j++)
228 { 311 {
229 celt_sig tmp = x[j] + m + VERY_SMALL; 312 celt_sig tmp = x[j] + VERY_SMALL + m;
230 m = MULT16_32_Q15(coef0, tmp); 313 m = MULT16_32_Q15(coef0, tmp);
231 scratch[j] = tmp; 314 scratch[j] = tmp;
232 } 315 }
@@ -247,7 +330,7 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
247 { 330 {
248 for (j=0;j<N;j++) 331 for (j=0;j<N;j++)
249 { 332 {
250 celt_sig tmp = x[j] + m + VERY_SMALL; 333 celt_sig tmp = x[j] + VERY_SMALL + m;
251 m = MULT16_32_Q15(coef0, tmp); 334 m = MULT16_32_Q15(coef0, tmp);
252 y[j*C] = SCALEOUT(SIG2WORD16(tmp)); 335 y[j*C] = SCALEOUT(SIG2WORD16(tmp));
253 } 336 }
@@ -278,8 +361,9 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
278static 361static
279#endif 362#endif
280void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[], 363void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
281 opus_val16 *oldBandE, int start, int effEnd, int C, int CC, int isTransient, 364 opus_val16 *oldBandE, int start, int effEnd, int C, int CC,
282 int LM, int downsample, int silence) 365 int isTransient, int LM, int downsample,
366 int silence, int arch)
283{ 367{
284 int c, i; 368 int c, i;
285 int M; 369 int M;
@@ -319,9 +403,9 @@ void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
319 freq2 = out_syn[1]+overlap/2; 403 freq2 = out_syn[1]+overlap/2;
320 OPUS_COPY(freq2, freq, N); 404 OPUS_COPY(freq2, freq, N);
321 for (b=0;b<B;b++) 405 for (b=0;b<B;b++)
322 clt_mdct_backward(&mode->mdct, &freq2[b], out_syn[0]+NB*b, mode->window, overlap, shift, B); 406 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++) 407 for (b=0;b<B;b++)
324 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[1]+NB*b, mode->window, overlap, shift, B); 408 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) 409 } else if (CC==1&&C==2)
326 { 410 {
327 /* Downmixing a stereo stream to mono */ 411 /* Downmixing a stereo stream to mono */
@@ -333,18 +417,24 @@ void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
333 denormalise_bands(mode, X+N, freq2, oldBandE+nbEBands, start, effEnd, M, 417 denormalise_bands(mode, X+N, freq2, oldBandE+nbEBands, start, effEnd, M,
334 downsample, silence); 418 downsample, silence);
335 for (i=0;i<N;i++) 419 for (i=0;i<N;i++)
336 freq[i] = HALF32(ADD32(freq[i],freq2[i])); 420 freq[i] = ADD32(HALF32(freq[i]), HALF32(freq2[i]));
337 for (b=0;b<B;b++) 421 for (b=0;b<B;b++)
338 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[0]+NB*b, mode->window, overlap, shift, B); 422 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch);
339 } else { 423 } else {
340 /* Normal case (mono or stereo) */ 424 /* Normal case (mono or stereo) */
341 c=0; do { 425 c=0; do {
342 denormalise_bands(mode, X+c*N, freq, oldBandE+c*nbEBands, start, effEnd, M, 426 denormalise_bands(mode, X+c*N, freq, oldBandE+c*nbEBands, start, effEnd, M,
343 downsample, silence); 427 downsample, silence);
344 for (b=0;b<B;b++) 428 for (b=0;b<B;b++)
345 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B); 429 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B, arch);
346 } while (++c<CC); 430 } while (++c<CC);
347 } 431 }
432 /* Saturate IMDCT output so that we can't overflow in the pitch postfilter
433 or in the */
434 c=0; do {
435 for (i=0;i<N;i++)
436 out_syn[c][i] = SATURATE(out_syn[c][i], SIG_SAT);
437 } while (++c<CC);
348 RESTORE_STACK; 438 RESTORE_STACK;
349} 439}
350 440
@@ -387,14 +477,6 @@ static void tf_decode(int start, int end, int isTransient, int *tf_res, int LM,
387 } 477 }
388} 478}
389 479
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
398static int celt_plc_pitch_search(celt_sig *decode_mem[2], int C, int arch) 480static int celt_plc_pitch_search(celt_sig *decode_mem[2], int C, int arch)
399{ 481{
400 int pitch_index; 482 int pitch_index;
@@ -446,7 +528,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
446 528
447 loss_count = st->loss_count; 529 loss_count = st->loss_count;
448 start = st->start; 530 start = st->start;
449 noise_based = loss_count >= 5 || start != 0; 531 noise_based = loss_count >= 5 || start != 0 || st->skip_plc;
450 if (noise_based) 532 if (noise_based)
451 { 533 {
452 /* Noise-based PLC/CNG */ 534 /* Noise-based PLC/CNG */
@@ -456,10 +538,9 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
456 VARDECL(celt_norm, X); 538 VARDECL(celt_norm, X);
457#endif 539#endif
458 opus_uint32 seed; 540 opus_uint32 seed;
459 opus_val16 *plcLogE;
460 int end; 541 int end;
461 int effEnd; 542 int effEnd;
462 543 opus_val16 decay;
463 end = st->end; 544 end = st->end;
464 effEnd = IMAX(start, IMIN(end, mode->effEBands)); 545 effEnd = IMAX(start, IMIN(end, mode->effEBands));
465 546
@@ -471,19 +552,13 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
471 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ 552 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
472#endif 553#endif
473 554
474 if (loss_count >= 5) 555 /* Energy decay */
475 plcLogE = backgroundLogE; 556 decay = loss_count==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT);
476 else { 557 c=0; do
477 /* Energy decay */ 558 {
478 opus_val16 decay = loss_count==0 ? 559 for (i=start;i<end;i++)
479 QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT); 560 oldBandE[c*nbEBands+i] = MAX16(backgroundLogE[c*nbEBands+i], oldBandE[c*nbEBands+i] - decay);
480 c=0; do 561 } while (++c<C);
481 {
482 for (i=start;i<end;i++)
483 oldBandE[c*nbEBands+i] -= decay;
484 } while (++c<C);
485 plcLogE = oldBandE;
486 }
487 seed = st->rng; 562 seed = st->rng;
488 for (c=0;c<C;c++) 563 for (c=0;c<C;c++)
489 { 564 {
@@ -499,7 +574,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
499 seed = celt_lcg_rand(seed); 574 seed = celt_lcg_rand(seed);
500 X[boffs+j] = (celt_norm)((opus_int32)seed>>20); 575 X[boffs+j] = (celt_norm)((opus_int32)seed>>20);
501 } 576 }
502 renormalise_vector(X+boffs, blen, Q15ONE); 577 renormalise_vector(X+boffs, blen, Q15ONE, st->arch);
503 } 578 }
504 } 579 }
505 st->rng = seed; 580 st->rng = seed;
@@ -509,14 +584,17 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
509 DECODE_BUFFER_SIZE-N+(overlap>>1)); 584 DECODE_BUFFER_SIZE-N+(overlap>>1));
510 } while (++c<C); 585 } while (++c<C);
511 586
512 celt_synthesis(mode, X, out_syn, plcLogE, start, effEnd, C, C, 0, LM, st->downsample, 0); 587 celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, C, C, 0, LM, st->downsample, 0, st->arch);
513 } else { 588 } else {
589 int exc_length;
514 /* Pitch-based PLC */ 590 /* Pitch-based PLC */
515 const opus_val16 *window; 591 const opus_val16 *window;
592 opus_val16 *exc;
516 opus_val16 fade = Q15ONE; 593 opus_val16 fade = Q15ONE;
517 int pitch_index; 594 int pitch_index;
518 VARDECL(opus_val32, etmp); 595 VARDECL(opus_val32, etmp);
519 VARDECL(opus_val16, exc); 596 VARDECL(opus_val16, _exc);
597 VARDECL(opus_val16, fir_tmp);
520 598
521 if (loss_count == 0) 599 if (loss_count == 0)
522 { 600 {
@@ -526,8 +604,14 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
526 fade = QCONST16(.8f,15); 604 fade = QCONST16(.8f,15);
527 } 605 }
528 606
607 /* We want the excitation for 2 pitch periods in order to look for a
608 decaying signal, but we can't get more than MAX_PERIOD. */
609 exc_length = IMIN(2*pitch_index, MAX_PERIOD);
610
529 ALLOC(etmp, overlap, opus_val32); 611 ALLOC(etmp, overlap, opus_val32);
530 ALLOC(exc, MAX_PERIOD, opus_val16); 612 ALLOC(_exc, MAX_PERIOD+LPC_ORDER, opus_val16);
613 ALLOC(fir_tmp, exc_length, opus_val16);
614 exc = _exc+LPC_ORDER;
531 window = mode->window; 615 window = mode->window;
532 c=0; do { 616 c=0; do {
533 opus_val16 decay; 617 opus_val16 decay;
@@ -536,13 +620,11 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
536 celt_sig *buf; 620 celt_sig *buf;
537 int extrapolation_offset; 621 int extrapolation_offset;
538 int extrapolation_len; 622 int extrapolation_len;
539 int exc_length;
540 int j; 623 int j;
541 624
542 buf = decode_mem[c]; 625 buf = decode_mem[c];
543 for (i=0;i<MAX_PERIOD;i++) { 626 for (i=0;i<MAX_PERIOD+LPC_ORDER;i++)
544 exc[i] = ROUND16(buf[DECODE_BUFFER_SIZE-MAX_PERIOD+i], SIG_SHIFT); 627 exc[i-LPC_ORDER] = ROUND16(buf[DECODE_BUFFER_SIZE-MAX_PERIOD-LPC_ORDER+i], SIG_SHIFT);
545 }
546 628
547 if (loss_count == 0) 629 if (loss_count == 0)
548 { 630 {
@@ -568,22 +650,32 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
568#endif 650#endif
569 } 651 }
570 _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER); 652 _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
653#ifdef FIXED_POINT
654 /* For fixed-point, apply bandwidth expansion until we can guarantee that
655 no overflow can happen in the IIR filter. This means:
656 32768*sum(abs(filter)) < 2^31 */
657 while (1) {
658 opus_val16 tmp=Q15ONE;
659 opus_val32 sum=QCONST16(1., SIG_SHIFT);
660 for (i=0;i<LPC_ORDER;i++)
661 sum += ABS16(lpc[c*LPC_ORDER+i]);
662 if (sum < 65535) break;
663 for (i=0;i<LPC_ORDER;i++)
664 {
665 tmp = MULT16_16_Q15(QCONST16(.99f,15), tmp);
666 lpc[c*LPC_ORDER+i] = MULT16_16_Q15(lpc[c*LPC_ORDER+i], tmp);
667 }
668 }
669#endif
571 } 670 }
572 /* We want the excitation for 2 pitch periods in order to look for a
573 decaying signal, but we can't get more than MAX_PERIOD. */
574 exc_length = IMIN(2*pitch_index, MAX_PERIOD);
575 /* Initialize the LPC history with the samples just before the start 671 /* Initialize the LPC history with the samples just before the start
576 of the region for which we're computing the excitation. */ 672 of the region for which we're computing the excitation. */
577 { 673 {
578 opus_val16 lpc_mem[LPC_ORDER]; 674 /* Compute the excitation for exc_length samples before the loss. We need the copy
579 for (i=0;i<LPC_ORDER;i++) 675 because celt_fir() cannot filter in-place. */
580 {
581 lpc_mem[i] =
582 ROUND16(buf[DECODE_BUFFER_SIZE-exc_length-1-i], SIG_SHIFT);
583 }
584 /* Compute the excitation for exc_length samples before the loss. */
585 celt_fir(exc+MAX_PERIOD-exc_length, lpc+c*LPC_ORDER, 676 celt_fir(exc+MAX_PERIOD-exc_length, lpc+c*LPC_ORDER,
586 exc+MAX_PERIOD-exc_length, exc_length, LPC_ORDER, lpc_mem); 677 fir_tmp, exc_length, LPC_ORDER, st->arch);
678 OPUS_COPY(exc+MAX_PERIOD-exc_length, fir_tmp, exc_length);
587 } 679 }
588 680
589 /* Check if the waveform is decaying, and if so how fast. 681 /* Check if the waveform is decaying, and if so how fast.
@@ -637,9 +729,8 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
637 tmp = ROUND16( 729 tmp = ROUND16(
638 buf[DECODE_BUFFER_SIZE-MAX_PERIOD-N+extrapolation_offset+j], 730 buf[DECODE_BUFFER_SIZE-MAX_PERIOD-N+extrapolation_offset+j],
639 SIG_SHIFT); 731 SIG_SHIFT);
640 S1 += SHR32(MULT16_16(tmp, tmp), 8); 732 S1 += SHR32(MULT16_16(tmp, tmp), 10);
641 } 733 }
642
643 { 734 {
644 opus_val16 lpc_mem[LPC_ORDER]; 735 opus_val16 lpc_mem[LPC_ORDER];
645 /* Copy the last decoded samples (prior to the overlap region) to 736 /* Copy the last decoded samples (prior to the overlap region) to
@@ -650,7 +741,11 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
650 the signal domain. */ 741 the signal domain. */
651 celt_iir(buf+DECODE_BUFFER_SIZE-N, lpc+c*LPC_ORDER, 742 celt_iir(buf+DECODE_BUFFER_SIZE-N, lpc+c*LPC_ORDER,
652 buf+DECODE_BUFFER_SIZE-N, extrapolation_len, LPC_ORDER, 743 buf+DECODE_BUFFER_SIZE-N, extrapolation_len, LPC_ORDER,
653 lpc_mem); 744 lpc_mem, st->arch);
745#ifdef FIXED_POINT
746 for (i=0; i < extrapolation_len; i++)
747 buf[DECODE_BUFFER_SIZE-N+i] = SATURATE(buf[DECODE_BUFFER_SIZE-N+i], SIG_SAT);
748#endif
654 } 749 }
655 750
656 /* Check if the synthesis energy is higher than expected, which can 751 /* Check if the synthesis energy is higher than expected, which can
@@ -661,7 +756,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
661 for (i=0;i<extrapolation_len;i++) 756 for (i=0;i<extrapolation_len;i++)
662 { 757 {
663 opus_val16 tmp = ROUND16(buf[DECODE_BUFFER_SIZE-N+i], SIG_SHIFT); 758 opus_val16 tmp = ROUND16(buf[DECODE_BUFFER_SIZE-N+i], SIG_SHIFT);
664 S2 += SHR32(MULT16_16(tmp, tmp), 8); 759 S2 += SHR32(MULT16_16(tmp, tmp), 10);
665 } 760 }
666 /* This checks for an "explosion" in the synthesis. */ 761 /* This checks for an "explosion" in the synthesis. */
667#ifdef FIXED_POINT 762#ifdef FIXED_POINT
@@ -698,7 +793,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
698 comb_filter(etmp, buf+DECODE_BUFFER_SIZE, 793 comb_filter(etmp, buf+DECODE_BUFFER_SIZE,
699 st->postfilter_period, st->postfilter_period, overlap, 794 st->postfilter_period, st->postfilter_period, overlap,
700 -st->postfilter_gain, -st->postfilter_gain, 795 -st->postfilter_gain, -st->postfilter_gain,
701 st->postfilter_tapset, st->postfilter_tapset, NULL, 0); 796 st->postfilter_tapset, st->postfilter_tapset, NULL, 0, st->arch);
702 797
703 /* Simulate TDAC on the concealed audio so that it blends with the 798 /* Simulate TDAC on the concealed audio so that it blends with the
704 MDCT of the next frame. */ 799 MDCT of the next frame. */
@@ -769,6 +864,7 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
769 const opus_int16 *eBands; 864 const opus_int16 *eBands;
770 ALLOC_STACK; 865 ALLOC_STACK;
771 866
867 VALIDATE_CELT_DECODER(st);
772 mode = st->mode; 868 mode = st->mode;
773 nbEBands = mode->nbEBands; 869 nbEBands = mode->nbEBands;
774 overlap = mode->overlap; 870 overlap = mode->overlap;
@@ -838,6 +934,10 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
838 return frame_size/st->downsample; 934 return frame_size/st->downsample;
839 } 935 }
840 936
937 /* Check if there are at least two packets received consecutively before
938 * turning on the pitch-based PLC */
939 st->skip_plc = st->loss_count != 0;
940
841 if (dec == NULL) 941 if (dec == NULL)
842 { 942 {
843 ec_dec_init(&_dec,(unsigned char*)data,len); 943 ec_dec_init(&_dec,(unsigned char*)data,len);
@@ -959,7 +1059,7 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
959 ALLOC(pulses, nbEBands, int); 1059 ALLOC(pulses, nbEBands, int);
960 ALLOC(fine_priority, nbEBands, int); 1060 ALLOC(fine_priority, nbEBands, int);
961 1061
962 codedBands = compute_allocation(mode, start, end, offsets, cap, 1062 codedBands = clt_compute_allocation(mode, start, end, offsets, cap,
963 alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses, 1063 alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
964 fine_quant, fine_priority, C, LM, dec, 0, 0, 0); 1064 fine_quant, fine_priority, C, LM, dec, 0, 0, 0);
965 1065
@@ -982,7 +1082,8 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
982 1082
983 quant_all_bands(0, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks, 1083 quant_all_bands(0, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks,
984 NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res, 1084 NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res,
985 len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng); 1085 len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng, 0,
1086 st->arch, st->disable_inv);
986 1087
987 if (anti_collapse_rsv > 0) 1088 if (anti_collapse_rsv > 0)
988 { 1089 {
@@ -994,7 +1095,7 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
994 1095
995 if (anti_collapse_on) 1096 if (anti_collapse_on)
996 anti_collapse(mode, X, collapse_masks, LM, C, N, 1097 anti_collapse(mode, X, collapse_masks, LM, C, N,
997 start, end, oldBandE, oldLogE, oldLogE2, pulses, st->rng); 1098 start, end, oldBandE, oldLogE, oldLogE2, pulses, st->rng, st->arch);
998 1099
999 if (silence) 1100 if (silence)
1000 { 1101 {
@@ -1002,18 +1103,19 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
1002 oldBandE[i] = -QCONST16(28.f,DB_SHIFT); 1103 oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
1003 } 1104 }
1004 1105
1005 celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, C, CC, isTransient, LM, st->downsample, silence); 1106 celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd,
1107 C, CC, isTransient, LM, st->downsample, silence, st->arch);
1006 1108
1007 c=0; do { 1109 c=0; do {
1008 st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD); 1110 st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD);
1009 st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD); 1111 st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD);
1010 comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, mode->shortMdctSize, 1112 comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, mode->shortMdctSize,
1011 st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset, 1113 st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset,
1012 mode->window, overlap); 1114 mode->window, overlap, st->arch);
1013 if (LM!=0) 1115 if (LM!=0)
1014 comb_filter(out_syn[c]+mode->shortMdctSize, out_syn[c]+mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-mode->shortMdctSize, 1116 comb_filter(out_syn[c]+mode->shortMdctSize, out_syn[c]+mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-mode->shortMdctSize,
1015 st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset, 1117 st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset,
1016 mode->window, overlap); 1118 mode->window, overlap, st->arch);
1017 1119
1018 } while (++c<CC); 1120 } while (++c<CC);
1019 st->postfilter_period_old = st->postfilter_period; 1121 st->postfilter_period_old = st->postfilter_period;
@@ -1035,10 +1137,18 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
1035 /* In case start or end were to change */ 1137 /* In case start or end were to change */
1036 if (!isTransient) 1138 if (!isTransient)
1037 { 1139 {
1140 opus_val16 max_background_increase;
1038 OPUS_COPY(oldLogE2, oldLogE, 2*nbEBands); 1141 OPUS_COPY(oldLogE2, oldLogE, 2*nbEBands);
1039 OPUS_COPY(oldLogE, oldBandE, 2*nbEBands); 1142 OPUS_COPY(oldLogE, oldBandE, 2*nbEBands);
1143 /* In normal circumstances, we only allow the noise floor to increase by
1144 up to 2.4 dB/second, but when we're in DTX, we allow up to 6 dB
1145 increase for each update.*/
1146 if (st->loss_count < 10)
1147 max_background_increase = M*QCONST16(0.001f,DB_SHIFT);
1148 else
1149 max_background_increase = QCONST16(1.f,DB_SHIFT);
1040 for (i=0;i<2*nbEBands;i++) 1150 for (i=0;i<2*nbEBands;i++)
1041 backgroundLogE[i] = MIN16(backgroundLogE[i] + M*QCONST16(0.001f,DB_SHIFT), oldBandE[i]); 1151 backgroundLogE[i] = MIN16(backgroundLogE[i] + max_background_increase, oldBandE[i]);
1042 } else { 1152 } else {
1043 for (i=0;i<2*nbEBands;i++) 1153 for (i=0;i<2*nbEBands;i++)
1044 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]); 1154 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
@@ -1195,6 +1305,7 @@ int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
1195 ((char*)&st->DECODER_RESET_START - (char*)st)); 1305 ((char*)&st->DECODER_RESET_START - (char*)st));
1196 for (i=0;i<2*st->mode->nbEBands;i++) 1306 for (i=0;i<2*st->mode->nbEBands;i++)
1197 oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); 1307 oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT);
1308 st->skip_plc = 1;
1198 } 1309 }
1199 break; 1310 break;
1200 case OPUS_GET_PITCH_REQUEST: 1311 case OPUS_GET_PITCH_REQUEST:
@@ -1227,6 +1338,26 @@ int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
1227 *value=st->rng; 1338 *value=st->rng;
1228 } 1339 }
1229 break; 1340 break;
1341 case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
1342 {
1343 opus_int32 value = va_arg(ap, opus_int32);
1344 if(value<0 || value>1)
1345 {
1346 goto bad_arg;
1347 }
1348 st->disable_inv = value;
1349 }
1350 break;
1351 case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
1352 {
1353 opus_int32 *value = va_arg(ap, opus_int32*);
1354 if (!value)
1355 {
1356 goto bad_arg;
1357 }
1358 *value = st->disable_inv;
1359 }
1360 break;
1230 default: 1361 default:
1231 goto bad_request; 1362 goto bad_request;
1232 } 1363 }