From 46c64a3eb195e48396af44c6d3d25613ec5d5840 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin Date: Fri, 20 Sep 2024 12:06:56 -0400 Subject: [PATCH] Coding fine energy and PVQ up to 48 kHz --- celt/celt_decoder.c | 27 +++++++++++++++------- celt/celt_encoder.c | 23 ++++++++++++++----- celt/cwrs.c | 6 ++--- celt/modes.c | 1 + celt/modes.h | 2 +- celt/rate.c | 55 +++++++++++++++++++++++++++++++++++---------- celt/rate.h | 2 +- 7 files changed, 86 insertions(+), 30 deletions(-) diff --git a/celt/celt_decoder.c b/celt/celt_decoder.c index e2123a2e0..6c8cdb828 100644 --- a/celt/celt_decoder.c +++ b/celt/celt_decoder.c @@ -1039,6 +1039,7 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char const opus_int16 *eBands; celt_glog max_background_increase; #ifdef ENABLE_QEXT + opus_int32 qext_bits; ec_dec ext_dec; int qext_bytes=0; VARDECL(int, extra_quant); @@ -1333,13 +1334,27 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char unquant_fine_energy(mode, start, end, oldBandE, NULL, fine_quant, dec, C); + ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ + #ifdef ENABLE_QEXT - ALLOC(extra_quant, nbEBands, int); - ALLOC(extra_pulses, nbEBands, int); - clt_compute_extra_allocation(mode, start, end, NULL, - qext_bytes*8< 0) unquant_fine_energy(mode, start, end, oldBandE, fine_quant, extra_quant, &ext_dec, C); + if (qext_mode) { + ec_enc foo_enc; + ec_enc_init(&foo_enc, NULL, 0); + int zeros[21] = {0}; + ALLOC(qext_collapse_masks, C*NB_QEXT_BANDS, unsigned char); + unquant_fine_energy(qext_mode, 0, NB_QEXT_BANDS, qext_oldBandE, NULL, &extra_quant[nbEBands], &ext_dec, C); + quant_all_bands(0, qext_mode, 0, NB_QEXT_BANDS, X, C==2 ? X+N : NULL, qext_collapse_masks, + NULL, &extra_pulses[nbEBands], shortBlocks, spread_decision, dual_stereo, intensity, zeros, + qext_bytes*(8<rng, 0, + st->arch, st->disable_inv, &foo_enc, zeros, 0); + } #endif c=0; do { @@ -1349,10 +1364,6 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char /* Decode fixed codebook */ 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, diff --git a/celt/celt_encoder.c b/celt/celt_encoder.c index 1e69c82f9..0ec6657ca 100644 --- a/celt/celt_encoder.c +++ b/celt/celt_encoder.c @@ -1701,6 +1701,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in int qext_scale; int padding_len_bytes=0; unsigned char *ext_payload; + opus_int32 qext_bits; ec_enc ext_enc; VARDECL(int, extra_quant); VARDECL(int, extra_pulses); @@ -2507,15 +2508,27 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in quant_fine_energy(mode, start, end, oldBandE, error, NULL, fine_quant, enc, C); OPUS_CLEAR(energyError, nbEBands*CC); #ifdef ENABLE_QEXT - ALLOC(extra_quant, nbEBands, int); - ALLOC(extra_pulses, nbEBands, int); + ALLOC(extra_quant, nbEBands+NB_QEXT_BANDS, int); + ALLOC(extra_pulses, nbEBands+NB_QEXT_BANDS, int); ALLOC(error_bak, C*nbEBands, celt_glog); - clt_compute_extra_allocation(mode, start, end, bandLogE, - qext_bytes*8< 0) quant_fine_energy(mode, start, end, oldBandE, error, fine_quant, extra_quant, &ext_enc, C); + if (qext_mode) { + quant_fine_energy(qext_mode, 0, NB_QEXT_BANDS, qext_oldBandE, qext_error, NULL, &extra_quant[nbEBands], &ext_enc, C); + ec_enc foo_enc; + ec_enc_init(&foo_enc, NULL, 0); + int zeros[21] = {0}; + ALLOC(qext_collapse_masks, C*NB_QEXT_BANDS, unsigned char); + quant_all_bands(1, qext_mode, 0, NB_QEXT_BANDS, X, C==2 ? X+N : NULL, qext_collapse_masks, + qext_bandE, &extra_pulses[nbEBands], shortBlocks, st->spread_decision, + dual_stereo, st->intensity, zeros, qext_bytes*(8<rng, st->complexity, st->arch, st->disable_inv, &foo_enc, zeros, 0); + } #endif /* Residual quantisation */ @@ -2576,7 +2589,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in } while (++cupsample, silence, st->arch ARG_QEXT(qext_mode) ARG_QEXT(qext_bandLogE)); + C, CC, isTransient, LM, st->upsample, silence, st->arch ARG_QEXT(qext_mode) ARG_QEXT(qext_oldBandE)); c=0; do { st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); diff --git a/celt/cwrs.c b/celt/cwrs.c index a552e4f0f..00c369b22 100644 --- a/celt/cwrs.c +++ b/celt/cwrs.c @@ -36,7 +36,7 @@ #include "mathops.h" #include "arch.h" -#ifdef CUSTOM_MODES +#if defined(CUSTOM_MODES) || defined(ENABLE_QEXT) /*Guaranteed to return a conservatively large estimate of the binary logarithm with frac bits of fractional precision. @@ -427,7 +427,7 @@ static const opus_uint32 *const CELT_PVQ_U_ROW[15]={ }; #endif -#if defined(CUSTOM_MODES) +#if defined(CUSTOM_MODES) || defined(ENABLE_QEXT) void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){ int k; /*_maxk==0 => there's nothing to do.*/ @@ -666,7 +666,7 @@ static OPUS_INLINE opus_uint32 icwrs(int _n,int _k,opus_uint32 *_nc,const int *_ return i; } -#ifdef CUSTOM_MODES +#if defined(CUSTOM_MODES) || defined(ENABLE_QEXT) void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){ int k; /*_maxk==0 => there's nothing to do.*/ diff --git a/celt/modes.c b/celt/modes.c index 249431f3f..0d31e01c3 100644 --- a/celt/modes.c +++ b/celt/modes.c @@ -494,5 +494,6 @@ void compute_qext_mode(CELTMode *qext, const CELTMode *m) qext->nbEBands = qext->effEBands = NB_QEXT_BANDS; qext->nbAllocVectors = 0; qext->allocVectors = NULL; + compute_pulse_cache(qext, qext->maxLM); } #endif diff --git a/celt/modes.h b/celt/modes.h index 137a565f3..2acf1cde8 100644 --- a/celt/modes.h +++ b/celt/modes.h @@ -78,7 +78,7 @@ struct OpusCustomMode { }; #ifdef ENABLE_QEXT -#define NB_QEXT_BANDS 7 +#define NB_QEXT_BANDS 14 void compute_qext_mode(CELTMode *qext, const CELTMode *m); #endif diff --git a/celt/rate.c b/celt/rate.c index 9aa9cd424..37b982cd8 100644 --- a/celt/rate.c +++ b/celt/rate.c @@ -48,7 +48,7 @@ static const unsigned char LOG2_FRAC_TABLE[24]={ 32,33,34,34,35,36,36,37,37 }; -#ifdef CUSTOM_MODES +#if defined(CUSTOM_MODES) || defined(ENABLE_QEXT) /*Determines if V(N,K) fits in a 32-bit unsigned integer. N and K are themselves limited to 15 bits.*/ @@ -647,28 +647,40 @@ int clt_compute_allocation(const CELTMode *m, int start, int end, const int *off #ifdef ENABLE_QEXT -void clt_compute_extra_allocation(const CELTMode *m, int start, int end, const celt_glog *bandLogE, +void clt_compute_extra_allocation(const CELTMode *m, const CELTMode *qext_mode, int start, int end, const celt_glog *bandLogE, const celt_glog *qext_bandLogE, opus_int32 total, int *extra_pulses, int *extra_equant, int C, int LM, ec_ctx *ec, int encode) { int i; opus_val32 sum; opus_val32 fill; int iter; + int tot_bands; + int tot_samples; VARDECL(int, depth); + if (qext_mode != NULL) { + celt_assert(start==0); + celt_assert(end==m->nbEBands); + tot_bands = end + NB_QEXT_BANDS; + tot_samples = qext_mode->eBands[NB_QEXT_BANDS]*C<eBands[end]-m->eBands[start])*C<nbEBands+NB_QEXT_BANDS;i++) { extra_pulses[i] = extra_equant[i] = 0; } return; } - ALLOC(depth, end, int); + ALLOC(depth, tot_bands, int); if (encode) { VARDECL(opus_val16, flatE); VARDECL(int, Ncoef); - ALLOC(flatE, end, opus_val16); - ALLOC(Ncoef, end, int); + ALLOC(flatE, tot_bands, opus_val16); + ALLOC(Ncoef, tot_bands, int); for (i=start;ieBands[i+1]-m->eBands[i])*C<nbEBands+i] - GCONST(0.0625f)*m->logN[i] + SHL32(eMeans[i],DB_SHIFT-4) - GCONST(.0062f)*(i+5)*(i+5), DB_SHIFT-10)); } } + if (qext_mode != NULL) { + for (i=0;ieBands[i+1]-qext_mode->eBands[i])*C<logN[i] + SHL32(eMeans[i],DB_SHIFT-4) - GCONST(.0062f)*(end+i+5)*(end+i+5), DB_SHIFT-10); + } + if (C==2) { + for (i=0;ilogN[i] + SHL32(eMeans[i],DB_SHIFT-4) - GCONST(.0062f)*(end+i+5)*(end+i+5), DB_SHIFT-10)); + } + } + } /* Approximate fill level assuming all bands contribute fully. */ sum = 0; - for (i=start;i>= BITRES; - fill = (SHL32(total, 10) + sum)/((m->eBands[end]-m->eBands[start])*C<eBands[end]-m->eBands[start])*C<storage*8<>2; extra_pulses[i] = ((((m->eBands[i+1]-m->eBands[i])<>2; } + if (qext_mode) { + for (i=0;i>2; + extra_pulses[end+i] = ((((qext_mode->eBands[i+1]-qext_mode->eBands[i])<>2; + } + } } #endif diff --git a/celt/rate.h b/celt/rate.h index fbe1929b4..e69d78f30 100644 --- a/celt/rate.h +++ b/celt/rate.h @@ -98,7 +98,7 @@ static OPUS_INLINE int pulses2bits(const CELTMode *m, int band, int LM, int puls int clt_compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo, opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth); -void clt_compute_extra_allocation(const CELTMode *m, int start, int end, const celt_glog *bandLogE, +void clt_compute_extra_allocation(const CELTMode *m, const CELTMode *qext_mode, int start, int end, const celt_glog *bandLogE, const celt_glog *qext_bandLogE, opus_int32 total, int *extra_pulses, int *extra_equant, int C, int LM, ec_ctx *ec, int encode); #endif