Skip to content

Commit

Permalink
Add coarse energy quantization for 20-48 kHz
Browse files Browse the repository at this point in the history
  • Loading branch information
jmvalin committed Nov 3, 2024
1 parent 9da69e9 commit 02c32ca
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 20 deletions.
9 changes: 7 additions & 2 deletions celt/bands.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;i<M*eBands[start];i++)
*f++ = 0;
if (start != 0)
{
for (i=0;i<M*eBands[start];i++)
*f++ = 0;
} else {
f += M*eBands[start];
}
for (i=start;i<end;i++)
{
int j, band_end;
Expand Down
6 changes: 0 additions & 6 deletions celt/bands.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@
#include "entdec.h"
#include "rate.h"

#ifdef ENABLE_QEXT
#define ARG_QEXT(arg) , arg
#else
#define ARG_QEXT(arg)
#endif

opus_int16 bitexact_cos(opus_int16 x);
int bitexact_log2tan(int isin,int icos);

Expand Down
9 changes: 8 additions & 1 deletion celt/celt.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@
#include "arch.h"
#include "kiss_fft.h"

#ifdef ENABLE_QEXT
#define ARG_QEXT(arg) , arg
#else
#define ARG_QEXT(arg)
#endif


#ifdef ENABLE_DEEP_PLC
#include "lpcnet.h"
#endif
Expand Down Expand Up @@ -245,7 +252,7 @@ void init_caps(const CELTMode *m,int *cap,int LM,int C);
void deemphasis(celt_sig *in[], opus_res *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem, int accum);
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 LM, int downsample, int silence, int arch ARG_QEXT(const CELTMode *qext_mode) ARG_QEXT(const celt_glog *qext_bandLogE));
#endif

#ifdef ENABLE_QEXT
Expand Down
55 changes: 49 additions & 6 deletions celt/celt_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,18 @@ int celt_decoder_get_size(int channels)

OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_get_size(const CELTMode *mode, int channels)
{
int size = sizeof(struct CELTDecoder)
int size;
int extra=0;
#ifdef ENABLE_QEXT
if (mode->Fs == 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;
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;i<N;i++)
freq[i] = ADD32(HALF32(freq[i]), HALF32(freq2[i]));
for (b=0;b<B;b++)
Expand All @@ -436,6 +458,11 @@ void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
c=0; do {
denormalise_bands(mode, X+c*N, freq, oldBandE+c*nbEBands, start, effEnd, M,
downsample, silence);
#ifdef ENABLE_QEXT
if (qext_mode)
denormalise_bands(qext_mode, X+c*N, freq, qext_bandLogE+c*NB_QEXT_BANDS, 0, NB_QEXT_BANDS, M,
downsample, silence);
#endif
for (b=0;b<B;b++)
clt_mdct_backward(&mode->mdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B, arch);
} while (++c<CC);
Expand Down Expand Up @@ -685,7 +712,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM
}
st->rng = 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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng, 0,
Expand Down Expand Up @@ -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);
Expand Down
39 changes: 34 additions & 5 deletions celt/celt_encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -2429,13 +2439,32 @@ 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;
}
} 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 */
Expand Down Expand Up @@ -2547,7 +2576,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);
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);
Expand Down
35 changes: 35 additions & 0 deletions celt/modes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 4 additions & 0 deletions celt/modes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 02c32ca

Please sign in to comment.