diff --git a/celt/bands.c b/celt/bands.c index 335884e36..aa9f40315 100644 --- a/celt/bands.c +++ b/celt/bands.c @@ -230,8 +230,13 @@ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X, } f = freq; x = X+M*eBands[start]; - for (i=0;iFs == 96000 && (mode->shortMdctSize==240 || mode->shortMdctSize==180)) { + extra = 2*NB_QEXT_BANDS*sizeof(celt_glog); + } +#endif + size = sizeof(struct CELTDecoder) + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig) + channels*CELT_LPC_ORDER*sizeof(opus_val16) - + 4*2*mode->nbEBands*sizeof(celt_glog); + + 4*2*mode->nbEBands*sizeof(celt_glog) + + extra; return size; } @@ -374,7 +382,7 @@ static void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[], celt_glog *oldBandE, int start, int effEnd, int C, int CC, int isTransient, int LM, int downsample, - int silence, int arch) + int silence, int arch ARG_QEXT(const CELTMode *qext_mode) ARG_QEXT(const celt_glog *qext_bandLogE)) { int c, i; int M; @@ -410,6 +418,11 @@ void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[], celt_sig *freq2; denormalise_bands(mode, X, freq, oldBandE, start, effEnd, M, downsample, silence); +#ifdef ENABLE_QEXT + if (qext_mode) + denormalise_bands(qext_mode, X, freq, qext_bandLogE, 0, NB_QEXT_BANDS, M, + downsample, silence); +#endif /* Store a temporary copy in the output buffer because the IMDCT destroys its input. */ freq2 = out_syn[1]+overlap/2; OPUS_COPY(freq2, freq, N); @@ -427,6 +440,15 @@ void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[], /* Use the output buffer as temp array before downmixing. */ denormalise_bands(mode, X+N, freq2, oldBandE+nbEBands, start, effEnd, M, downsample, silence); +#ifdef ENABLE_QEXT + if (qext_mode) + { + denormalise_bands(qext_mode, X, freq, qext_bandLogE, 0, NB_QEXT_BANDS, M, + downsample, silence); + denormalise_bands(qext_mode, X+N, freq2, qext_bandLogE+NB_QEXT_BANDS, 0, NB_QEXT_BANDS, M, + downsample, silence); + } +#endif for (i=0;imdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B, arch); } while (++crng = seed; - celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, C, C, 0, LM, st->downsample, 0, st->arch); + celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, C, C, 0, LM, st->downsample, 0, st->arch ARG_QEXT(NULL) ARG_QEXT(NULL)); st->prefilter_and_fold = 0; /* Skip regular PLC until we get two consecutive packets. */ st->skip_plc = 1; @@ -1016,6 +1043,9 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char int qext_bytes=0; VARDECL(int, extra_quant); VARDECL(int, extra_pulses); + const CELTMode *qext_mode = NULL; + CELTMode qext_mode_struct; + celt_glog *qext_oldBandE=NULL; #else # define qext_bytes 0 #endif @@ -1229,6 +1259,17 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char /* Get band energies */ unquant_coarse_energy(mode, start, end, oldBandE, intra_ener, dec, C, LM); +#ifdef ENABLE_QEXT + if (qext_bytes && mode->Fs == 96000 && (mode->shortMdctSize==240 || mode->shortMdctSize==180)) { + int qext_intra_ener; + qext_oldBandE = backgroundLogE + 2*nbEBands; + compute_qext_mode(&qext_mode_struct, mode); + qext_mode = &qext_mode_struct; + qext_intra_ener = ec_tell(&ext_dec)+3<=qext_bytes*8 ? ec_dec_bit_logp(&ext_dec, 3) : 0; + unquant_coarse_energy(qext_mode, 0, NB_QEXT_BANDS, qext_oldBandE, + qext_intra_ener, &ext_dec, C, LM); + } +#endif ALLOC(tf_res, nbEBands, int); tf_decode(start, end, isTransient, tf_res, LM, dec); @@ -1309,7 +1350,9 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char ALLOC(collapse_masks, C*nbEBands, unsigned char); ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ - +#ifdef ENABLE_QEXT + if (qext_mode) OPUS_CLEAR(X, C*N); +#endif 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<rng, 0, @@ -1338,7 +1381,7 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char prefilter_and_fold(st, N); } celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, - C, CC, isTransient, LM, st->downsample, silence, st->arch); + C, CC, isTransient, LM, st->downsample, silence, st->arch ARG_QEXT(qext_mode) ARG_QEXT(qext_oldBandE)); c=0; do { st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD); diff --git a/celt/celt_encoder.c b/celt/celt_encoder.c index 25b4ab5e8..1e69c82f9 100644 --- a/celt/celt_encoder.c +++ b/celt/celt_encoder.c @@ -144,18 +144,22 @@ int celt_encoder_get_size(int channels) OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_get_size(const CELTMode *mode, int channels) { + int extra=0; #ifdef ENABLE_QEXT int qext_scale; - if (mode->Fs == 96000 && mode->shortMdctSize==240) qext_scale = 2; - else qext_scale = 1; + if (mode->Fs == 96000 && (mode->shortMdctSize==240 || mode->shortMdctSize==180)) { + qext_scale = 2; + extra = channels*NB_QEXT_BANDS*sizeof(celt_glog); + } else qext_scale = 1; #endif int size = sizeof(struct CELTEncoder) + (channels*mode->overlap-1)*sizeof(celt_sig) /* celt_sig in_mem[channels*mode->overlap]; */ + channels*QEXT_SCALE(COMBFILTER_MAXPERIOD)*sizeof(celt_sig) /* celt_sig prefilter_mem[channels*COMBFILTER_MAXPERIOD]; */ - + 4*channels*mode->nbEBands*sizeof(celt_glog); /* celt_glog oldBandE[channels*mode->nbEBands]; */ + + 4*channels*mode->nbEBands*sizeof(celt_glog) /* celt_glog oldBandE[channels*mode->nbEBands]; */ /* celt_glog oldLogE[channels*mode->nbEBands]; */ /* celt_glog oldLogE2[channels*mode->nbEBands]; */ /* celt_glog energyError[channels*mode->nbEBands]; */ + + extra; return size; } @@ -207,7 +211,7 @@ static int opus_custom_encoder_init_arch(CELTEncoder *st, const CELTMode *mode, st->lsb_depth=24; #ifdef ENABLE_QEXT - if (st->mode->Fs == 96000 && mode->shortMdctSize==240) st->qext_scale = 2; + if (st->mode->Fs == 96000 && (mode->shortMdctSize==240 || mode->shortMdctSize==180)) st->qext_scale = 2; else st->qext_scale = 1; #endif @@ -1701,6 +1705,12 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in VARDECL(int, extra_quant); VARDECL(int, extra_pulses); VARDECL(celt_glog, error_bak); + const CELTMode *qext_mode = NULL; + CELTMode qext_mode_struct; + celt_ener qext_bandE[2*NB_QEXT_BANDS]; + celt_glog qext_bandLogE[2*NB_QEXT_BANDS]; + celt_glog *qext_oldBandE=NULL; + celt_glog qext_error[2*NB_QEXT_BANDS]; #endif ALLOC_STACK; @@ -2429,6 +2439,11 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in OPUS_CLEAR(ext_payload, qext_bytes); ec_enc_init(&ext_enc, ext_payload, qext_bytes); nbCompressedBytes = new_compressedBytes; + if (qext_scale == 2) + { + compute_qext_mode(&qext_mode_struct, mode); + qext_mode = &qext_mode_struct; + } } else { ec_enc_init(&ext_enc, NULL, 0); qext_bytes = 0; @@ -2436,6 +2451,20 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in } else { ec_enc_init(&ext_enc, NULL, 0); } + if (qext_mode) + { + /* Don't bias for intra. */ + opus_val32 qext_delayedIntra=0; + qext_oldBandE = energyError + CC*nbEBands; + compute_band_energies(qext_mode, freq, qext_bandE, NB_QEXT_BANDS, C, LM, st->arch); + normalise_bands(qext_mode, freq, X, qext_bandE, NB_QEXT_BANDS, C, M); + amp2Log2(qext_mode, NB_QEXT_BANDS, NB_QEXT_BANDS, qext_bandE, qext_bandLogE, C); + + quant_coarse_energy(qext_mode, 0, NB_QEXT_BANDS, NB_QEXT_BANDS, qext_bandLogE, + qext_oldBandE, qext_bytes*8, qext_error, &ext_enc, + C, LM, qext_bytes, st->force_intra, + &qext_delayedIntra, st->complexity >= 4, st->loss_rate, st->lfe); + } #endif /* Bit allocation */ @@ -2547,7 +2576,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in } while (++cupsample, silence, st->arch); + C, CC, isTransient, LM, st->upsample, silence, st->arch ARG_QEXT(qext_mode) ARG_QEXT(qext_bandLogE)); c=0; do { st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); diff --git a/celt/modes.c b/celt/modes.c index 9d27a21b9..249431f3f 100644 --- a/celt/modes.c +++ b/celt/modes.c @@ -461,3 +461,38 @@ void opus_custom_mode_destroy(CELTMode *mode) opus_free((CELTMode *)mode); } #endif + +#ifdef ENABLE_QEXT + +static const opus_int16 qext_eBands_180[] = { +/* 20k 22k 24k 26k 28k 30k 32k 34k 36k 38k 40k 42k 44k 47k 48k */ + 74, 82, 90, 98, 106, 114, 122, 130, 138, 146, 154, 162, 168, 174, 180 +}; + +static const opus_int16 qext_logN_180[] = {24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 21, 21, 21}; + +/* Extra bands. */ +static const opus_int16 qext_eBands_240[] = { +/* 20k 22k 24k 26k 28k 30k 32k 34k 36k 38k 40k 42k 44k 47k 48k */ + 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240 +}; + +static const opus_int16 qext_logN_240[] = {27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27}; + +void compute_qext_mode(CELTMode *qext, const CELTMode *m) +{ + OPUS_COPY(qext, m, 1); + if (m->shortMdctSize == 240) { + qext->eBands = qext_eBands_240; + qext->logN = qext_logN_240; + } else if (m->shortMdctSize == 180) { + qext->eBands = qext_eBands_180; + qext->logN = qext_logN_180; + } else { + celt_assert(0); + } + qext->nbEBands = qext->effEBands = NB_QEXT_BANDS; + qext->nbAllocVectors = 0; + qext->allocVectors = NULL; +} +#endif diff --git a/celt/modes.h b/celt/modes.h index 311845523..137a565f3 100644 --- a/celt/modes.h +++ b/celt/modes.h @@ -77,5 +77,9 @@ struct OpusCustomMode { PulseCache cache; }; +#ifdef ENABLE_QEXT +#define NB_QEXT_BANDS 7 +void compute_qext_mode(CELTMode *qext, const CELTMode *m); +#endif #endif