| Index: third_party/opus/src/celt/celt_decoder.c
|
| diff --git a/third_party/opus/src/celt/celt_decoder.c b/third_party/opus/src/celt/celt_decoder.c
|
| index b978bb34d1b7015817637cd0172425aa8fabb60b..567d745649b98ad9c661fbf53f73d0a7da0a78b0 100644
|
| --- a/third_party/opus/src/celt/celt_decoder.c
|
| +++ b/third_party/opus/src/celt/celt_decoder.c
|
| @@ -73,6 +73,7 @@ struct OpusCustomDecoder {
|
| int downsample;
|
| int start, end;
|
| int signalling;
|
| + int disable_inv;
|
| int arch;
|
|
|
| /* Everything beyond this point gets cleared on a reset */
|
| @@ -163,6 +164,11 @@ OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMod
|
| st->start = 0;
|
| st->end = st->mode->effEBands;
|
| st->signalling = 1;
|
| +#ifdef ENABLE_UPDATE_DRAFT
|
| + st->disable_inv = channels == 1;
|
| +#else
|
| + st->disable_inv = 0;
|
| +#endif
|
| st->arch = opus_select_arch();
|
|
|
| opus_custom_decoder_ctl(st, OPUS_RESET_STATE);
|
| @@ -177,6 +183,36 @@ void opus_custom_decoder_destroy(CELTDecoder *st)
|
| }
|
| #endif /* CUSTOM_MODES */
|
|
|
| +#ifndef CUSTOM_MODES
|
| +/* Special case for stereo with no downsampling and no accumulation. This is
|
| + quite common and we can make it faster by processing both channels in the
|
| + same loop, reducing overhead due to the dependency loop in the IIR filter. */
|
| +static void deemphasis_stereo_simple(celt_sig *in[], opus_val16 *pcm, int N, const opus_val16 coef0,
|
| + celt_sig *mem)
|
| +{
|
| + celt_sig * OPUS_RESTRICT x0;
|
| + celt_sig * OPUS_RESTRICT x1;
|
| + celt_sig m0, m1;
|
| + int j;
|
| + x0=in[0];
|
| + x1=in[1];
|
| + m0 = mem[0];
|
| + m1 = mem[1];
|
| + for (j=0;j<N;j++)
|
| + {
|
| + celt_sig tmp0, tmp1;
|
| + /* Add VERY_SMALL to x[] first to reduce dependency chain. */
|
| + tmp0 = x0[j] + VERY_SMALL + m0;
|
| + tmp1 = x1[j] + VERY_SMALL + m1;
|
| + m0 = MULT16_32_Q15(coef0, tmp0);
|
| + m1 = MULT16_32_Q15(coef0, tmp1);
|
| + pcm[2*j ] = SCALEOUT(SIG2WORD16(tmp0));
|
| + pcm[2*j+1] = SCALEOUT(SIG2WORD16(tmp1));
|
| + }
|
| + mem[0] = m0;
|
| + mem[1] = m1;
|
| +}
|
| +#endif
|
|
|
| #ifndef RESYNTH
|
| static
|
| @@ -190,6 +226,14 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
|
| opus_val16 coef0;
|
| VARDECL(celt_sig, scratch);
|
| SAVE_STACK;
|
| +#ifndef CUSTOM_MODES
|
| + /* Short version for common case. */
|
| + if (downsample == 1 && C == 2 && !accum)
|
| + {
|
| + deemphasis_stereo_simple(in, pcm, N, coef[0], mem);
|
| + return;
|
| + }
|
| +#endif
|
| #ifndef FIXED_POINT
|
| (void)accum;
|
| celt_assert(accum==0);
|
| @@ -225,7 +269,7 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
|
| /* Shortcut for the standard (non-custom modes) case */
|
| for (j=0;j<N;j++)
|
| {
|
| - celt_sig tmp = x[j] + m + VERY_SMALL;
|
| + celt_sig tmp = x[j] + VERY_SMALL + m;
|
| m = MULT16_32_Q15(coef0, tmp);
|
| scratch[j] = tmp;
|
| }
|
| @@ -246,7 +290,7 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
|
| {
|
| for (j=0;j<N;j++)
|
| {
|
| - celt_sig tmp = x[j] + m + VERY_SMALL;
|
| + celt_sig tmp = x[j] + VERY_SMALL + m;
|
| m = MULT16_32_Q15(coef0, tmp);
|
| y[j*C] = SCALEOUT(SIG2WORD16(tmp));
|
| }
|
| @@ -333,7 +377,7 @@ void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
|
| denormalise_bands(mode, X+N, freq2, oldBandE+nbEBands, start, effEnd, M,
|
| downsample, silence);
|
| for (i=0;i<N;i++)
|
| - freq[i] = HALF32(ADD32(freq[i],freq2[i]));
|
| + freq[i] = ADD32(HALF32(freq[i]), HALF32(freq2[i]));
|
| for (b=0;b<B;b++)
|
| clt_mdct_backward(&mode->mdct, &freq[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch);
|
| } else {
|
| @@ -345,6 +389,12 @@ void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
|
| clt_mdct_backward(&mode->mdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B, arch);
|
| } while (++c<CC);
|
| }
|
| + /* Saturate IMDCT output so that we can't overflow in the pitch postfilter
|
| + or in the */
|
| + c=0; do {
|
| + for (i=0;i<N;i++)
|
| + out_syn[c][i] = SATURATE(out_syn[c][i], SIG_SAT);
|
| + } while (++c<CC);
|
| RESTORE_STACK;
|
| }
|
|
|
| @@ -506,10 +556,11 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
|
| } else {
|
| /* Pitch-based PLC */
|
| const opus_val16 *window;
|
| + opus_val16 *exc;
|
| opus_val16 fade = Q15ONE;
|
| int pitch_index;
|
| VARDECL(opus_val32, etmp);
|
| - VARDECL(opus_val16, exc);
|
| + VARDECL(opus_val16, _exc);
|
|
|
| if (loss_count == 0)
|
| {
|
| @@ -520,7 +571,8 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
|
| }
|
|
|
| ALLOC(etmp, overlap, opus_val32);
|
| - ALLOC(exc, MAX_PERIOD, opus_val16);
|
| + ALLOC(_exc, MAX_PERIOD+LPC_ORDER, opus_val16);
|
| + exc = _exc+LPC_ORDER;
|
| window = mode->window;
|
| c=0; do {
|
| opus_val16 decay;
|
| @@ -561,6 +613,23 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
|
| #endif
|
| }
|
| _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
|
| +#ifdef FIXED_POINT
|
| + /* For fixed-point, apply bandwidth expansion until we can guarantee that
|
| + no overflow can happen in the IIR filter. This means:
|
| + 32768*sum(abs(filter)) < 2^31 */
|
| + while (1) {
|
| + opus_val16 tmp=Q15ONE;
|
| + opus_val32 sum=QCONST16(1., SIG_SHIFT);
|
| + for (i=0;i<LPC_ORDER;i++)
|
| + sum += ABS16(lpc[c*LPC_ORDER+i]);
|
| + if (sum < 65535) break;
|
| + for (i=0;i<LPC_ORDER;i++)
|
| + {
|
| + tmp = MULT16_16_Q15(QCONST16(.99f,15), tmp);
|
| + lpc[c*LPC_ORDER+i] = MULT16_16_Q15(lpc[c*LPC_ORDER+i], tmp);
|
| + }
|
| + }
|
| +#endif
|
| }
|
| /* We want the excitation for 2 pitch periods in order to look for a
|
| decaying signal, but we can't get more than MAX_PERIOD. */
|
| @@ -568,15 +637,14 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
|
| /* Initialize the LPC history with the samples just before the start
|
| of the region for which we're computing the excitation. */
|
| {
|
| - opus_val16 lpc_mem[LPC_ORDER];
|
| for (i=0;i<LPC_ORDER;i++)
|
| {
|
| - lpc_mem[i] =
|
| - ROUND16(buf[DECODE_BUFFER_SIZE-exc_length-1-i], SIG_SHIFT);
|
| + exc[MAX_PERIOD-exc_length-LPC_ORDER+i] =
|
| + ROUND16(buf[DECODE_BUFFER_SIZE-exc_length-LPC_ORDER+i], SIG_SHIFT);
|
| }
|
| /* Compute the excitation for exc_length samples before the loss. */
|
| celt_fir(exc+MAX_PERIOD-exc_length, lpc+c*LPC_ORDER,
|
| - exc+MAX_PERIOD-exc_length, exc_length, LPC_ORDER, lpc_mem, st->arch);
|
| + exc+MAX_PERIOD-exc_length, exc_length, LPC_ORDER, st->arch);
|
| }
|
|
|
| /* Check if the waveform is decaying, and if so how fast.
|
| @@ -630,9 +698,8 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
|
| tmp = ROUND16(
|
| buf[DECODE_BUFFER_SIZE-MAX_PERIOD-N+extrapolation_offset+j],
|
| SIG_SHIFT);
|
| - S1 += SHR32(MULT16_16(tmp, tmp), 8);
|
| + S1 += SHR32(MULT16_16(tmp, tmp), 10);
|
| }
|
| -
|
| {
|
| opus_val16 lpc_mem[LPC_ORDER];
|
| /* Copy the last decoded samples (prior to the overlap region) to
|
| @@ -644,6 +711,10 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
|
| celt_iir(buf+DECODE_BUFFER_SIZE-N, lpc+c*LPC_ORDER,
|
| buf+DECODE_BUFFER_SIZE-N, extrapolation_len, LPC_ORDER,
|
| lpc_mem, st->arch);
|
| +#ifdef FIXED_POINT
|
| + for (i=0; i < extrapolation_len; i++)
|
| + buf[DECODE_BUFFER_SIZE-N+i] = SATURATE(buf[DECODE_BUFFER_SIZE-N+i], SIG_SAT);
|
| +#endif
|
| }
|
|
|
| /* Check if the synthesis energy is higher than expected, which can
|
| @@ -654,7 +725,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
|
| for (i=0;i<extrapolation_len;i++)
|
| {
|
| opus_val16 tmp = ROUND16(buf[DECODE_BUFFER_SIZE-N+i], SIG_SHIFT);
|
| - S2 += SHR32(MULT16_16(tmp, tmp), 8);
|
| + S2 += SHR32(MULT16_16(tmp, tmp), 10);
|
| }
|
| /* This checks for an "explosion" in the synthesis. */
|
| #ifdef FIXED_POINT
|
| @@ -979,7 +1050,8 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
|
|
|
| quant_all_bands(0, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks,
|
| NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res,
|
| - len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng, st->arch);
|
| + len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng, 0,
|
| + st->arch, st->disable_inv);
|
|
|
| if (anti_collapse_rsv > 0)
|
| {
|
| @@ -1234,6 +1306,26 @@ int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
|
| *value=st->rng;
|
| }
|
| break;
|
| + case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
|
| + {
|
| + opus_int32 value = va_arg(ap, opus_int32);
|
| + if(value<0 || value>1)
|
| + {
|
| + goto bad_arg;
|
| + }
|
| + st->disable_inv = value;
|
| + }
|
| + break;
|
| + case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
|
| + {
|
| + opus_int32 *value = va_arg(ap, opus_int32*);
|
| + if (!value)
|
| + {
|
| + goto bad_arg;
|
| + }
|
| + *value = st->disable_inv;
|
| + }
|
| + break;
|
| default:
|
| goto bad_request;
|
| }
|
|
|