Skip to content

Commit

Permalink
Coding fine energy and PVQ up to 48 kHz
Browse files Browse the repository at this point in the history
  • Loading branch information
jmvalin committed Nov 3, 2024
1 parent 02c32ca commit 46c64a3
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 30 deletions.
27 changes: 19 additions & 8 deletions celt/celt_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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<<BITRES, extra_pulses, extra_quant, C, LM, &ext_dec, 0);
ALLOC(extra_quant, nbEBands+NB_QEXT_BANDS, int);
ALLOC(extra_pulses, nbEBands+NB_QEXT_BANDS, int);
qext_bits = ((opus_int32)qext_bytes*8<<BITRES) - ec_tell_frac(dec) - 1;
clt_compute_extra_allocation(mode, qext_mode, start, end, NULL, NULL,
qext_bits, extra_pulses, extra_quant, C, LM, &ext_dec, 0);
if (qext_bytes > 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<<BITRES), balance, &ext_dec, LM, codedBands, &st->rng, 0,
st->arch, st->disable_inv, &foo_enc, zeros, 0);
}
#endif

c=0; do {
Expand All @@ -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<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng, 0,
Expand Down
23 changes: 18 additions & 5 deletions celt/celt_encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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<<BITRES, extra_pulses, extra_quant, C, LM, &ext_enc, 1);
qext_bits = ((opus_int32)qext_bytes*8<<BITRES) - ec_tell_frac(enc) - 1;
clt_compute_extra_allocation(mode, qext_mode, start, end, bandLogE, qext_bandLogE,
qext_bits, extra_pulses, extra_quant, C, LM, &ext_enc, 1);
OPUS_COPY(error_bak, error, C*nbEBands);
if (qext_bytes > 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<<BITRES),
balance, &ext_enc, LM, codedBands, &st->rng, st->complexity, st->arch, st->disable_inv, &foo_enc, zeros, 0);
}
#endif

/* Residual quantisation */
Expand Down Expand Up @@ -2576,7 +2589,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in
} while (++c<CC);

celt_synthesis(mode, X, out_mem, oldBandE, start, effEnd,
C, CC, isTransient, LM, st->upsample, 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);
Expand Down
6 changes: 3 additions & 3 deletions celt/cwrs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.*/
Expand Down Expand Up @@ -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.*/
Expand Down
1 change: 1 addition & 0 deletions celt/modes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion celt/modes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
55 changes: 43 additions & 12 deletions celt/rate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.*/
Expand Down Expand Up @@ -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<<LM;
} else {
tot_bands = end;
tot_samples = (m->eBands[end]-m->eBands[start])*C<<LM;
}

if (total <= 0) {
for (i=start;i<end;i++) {
for (i=start;i<m->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;i<end;i++) {
Ncoef[i] = (m->eBands[i+1]-m->eBands[i])*C<<LM;
}
Expand All @@ -681,21 +693,34 @@ void clt_compute_extra_allocation(const CELTMode *m, int start, int end, const c
flatE[i] = MAXG(flatE[i], PSHR32(bandLogE[m->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;i<NB_QEXT_BANDS;i++) {
Ncoef[end+i] = (qext_mode->eBands[i+1]-qext_mode->eBands[i])*C<<LM;
}
for (i=0;i<NB_QEXT_BANDS;i++) {
flatE[end+i] = PSHR32(qext_bandLogE[i] - GCONST(0.0625f)*qext_mode->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;i<NB_QEXT_BANDS;i++) {
flatE[end+i] = MAXG(flatE[end+i], PSHR32(qext_bandLogE[NB_QEXT_BANDS+i] - GCONST(0.0625f)*qext_mode->logN[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<end;i++) {
for (i=start;i<tot_bands;i++) {
sum += MULT16_16(Ncoef[i], flatE[i]);
}
total >>= BITRES;
fill = (SHL32(total, 10) + sum)/((m->eBands[end]-m->eBands[start])*C<<LM);
fill = (SHL32(total, 10) + sum)/tot_samples;
/* Iteratively refine the fill level considering that we allow between 0 and 12 bits of depth. */
for (iter=0;iter<10;iter++) {
sum = 0;
for (i=start;i<end;i++)
for (i=start;i<tot_bands;i++)
sum += Ncoef[i] * MIN32(QCONST16(12.f, 10), MAX32(0, flatE[i]-fill));
fill -= (SHL32(total, 10) - sum)/((m->eBands[end]-m->eBands[start])*C<<LM);
fill -= (SHL32(total, 10) - sum)/tot_samples;
}
for (i=start;i<end;i++) {
for (i=start;i<tot_bands;i++) {
#ifdef FIXED_POINT
depth[i] = PSHR32(MIN32(QCONST16(12.f, 10), MAX32(0, flatE[i]-fill)), 10-2);
#else
Expand All @@ -707,7 +732,7 @@ void clt_compute_extra_allocation(const CELTMode *m, int start, int end, const c
depth[i] = 0;
}
} else {
for (i=start;i<end;i++) {
for (i=start;i<tot_bands;i++) {
if (ec_tell_frac(ec) + 45 < ec->storage*8<<BITRES)
depth[i] = ec_dec_uint(ec, 49);
else
Expand All @@ -718,5 +743,11 @@ void clt_compute_extra_allocation(const CELTMode *m, int start, int end, const c
extra_equant[i] = (depth[i]+3)>>2;
extra_pulses[i] = ((((m->eBands[i+1]-m->eBands[i])<<LM)-1)*C * depth[i] * (1<<BITRES) + 2)>>2;
}
if (qext_mode) {
for (i=0;i<NB_QEXT_BANDS;i++) {
extra_equant[end+i] = (depth[end+i]+3)>>2;
extra_pulses[end+i] = ((((qext_mode->eBands[i+1]-qext_mode->eBands[i])<<LM)-1)*C * depth[end+i] * (1<<BITRES) + 2)>>2;
}
}
}
#endif
2 changes: 1 addition & 1 deletion celt/rate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 46c64a3

Please sign in to comment.