diff options
Diffstat (limited to 'lib/rbcodec/codecs/libopus/celt/celt_decoder.c')
-rw-r--r-- | lib/rbcodec/codecs/libopus/celt/celt_decoder.c | 263 |
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. */ | ||
115 | void 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 | |||
102 | int celt_decoder_get_size(int channels) | 144 | int 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. */ | ||
230 | static 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 |
183 | static | 258 | static |
@@ -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 | |||
278 | static | 361 | static |
279 | #endif | 362 | #endif |
280 | void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[], | 363 | void 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 | |||
398 | static int celt_plc_pitch_search(celt_sig *decode_mem[2], int C, int arch) | 480 | static 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 | } |