From a4833ffadaee1d293f230eb9e5fa5308128f0db8 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin <Jean-Marc.Valin@csiro.au> Date: Thu, 10 Jan 2008 15:34:00 +1100 Subject: [PATCH] Stereo decoding working again (fixed a few issues in the encoder at the same time) --- libcelt/celt.c | 24 +++++----- libcelt/modes.c | 4 +- libcelt/quant_bands.c | 102 +++++++++++++++++++++++++++++------------- libcelt/vq.c | 6 +-- 4 files changed, 88 insertions(+), 48 deletions(-) diff --git a/libcelt/celt.c b/libcelt/celt.c index c165762ab..f01ac1e3c 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -107,7 +107,7 @@ CELTEncoder *celt_encoder_new(const CELTMode *mode) = sin(.5*M_PI* sin(.5*M_PI*(i+.5)/st->overlap) * sin(.5*M_PI*(i+.5)/st->overlap)); for (i=0;i<2*N4;i++) st->window[N-N4+i] = 1; - st->oldBandE = celt_alloc(mode->nbEBands*sizeof(float)); + st->oldBandE = celt_alloc(C*mode->nbEBands*sizeof(float)); st->preemph = 0.8; st->preemph_memE = celt_alloc(C*sizeof(float));; @@ -318,7 +318,6 @@ int celt_encode(CELTEncoder *st, short *pcm) time_dct(X, N, B, C); time_dct(P, N, B, C); - quant_energy(st->mode, bandE, st->oldBandE, &st->enc); /* Pitch prediction */ @@ -447,7 +446,7 @@ CELTDecoder *celt_decoder_new(const CELTMode *mode) for (i=0;i<2*N4;i++) st->window[N-N4+i] = 1; - st->oldBandE = celt_alloc(mode->nbEBands*sizeof(float)); + st->oldBandE = celt_alloc(C*mode->nbEBands*sizeof(float)); st->preemph = 0.8; st->preemph_memD = celt_alloc(C*sizeof(float));; @@ -518,7 +517,7 @@ int celt_decode(CELTDecoder *st, char *data, int len, short *pcm) float X[C*B*N]; /**< Interleaved signal MDCTs */ float P[C*B*N]; /**< Interleaved pitch MDCTs*/ - float bandE[st->mode->nbEBands]; + float bandE[st->mode->nbEBands*C]; float gains[st->mode->nbPBands]; int pitch_index; ec_dec dec; @@ -543,16 +542,16 @@ int celt_decode(CELTDecoder *st, char *data, int len, short *pcm) /* Pitch MDCT */ compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index*C, P, N, B, C); - if (C==2) - haar1(P, B*N*C, 1); - time_dct(P, N, B, C); - { float bandEp[st->mode->nbEBands]; compute_band_energies(st->mode, P, bandEp); normalise_bands(st->mode, P, bandEp); } + if (C==2) + haar1(P, B*N*C, 1); + time_dct(P, N, B, C); + /* Get the pitch gains */ unquant_pitch(gains, st->mode->nbPBands, &dec); @@ -562,13 +561,16 @@ int celt_decode(CELTDecoder *st, char *data, int len, short *pcm) /* Decode fixed codebook and merge with pitch */ unquant_bands(st->mode, X, P, &dec); - /* Synthesis */ - denormalise_bands(st->mode, X, bandE); - time_idct(X, N, B, C); if (C==2) haar1(X, B*N*C, 1); + renormalise_bands(st->mode, X); + + /* Synthesis */ + denormalise_bands(st->mode, X, bandE); + + CELT_MOVE(st->out_mem, st->out_mem+C*B*N, C*(MAX_PERIOD-B*N)); /* Compute inverse MDCTs */ compute_inv_mdcts(&st->mdct_lookup, st->window, X, st->out_mem, st->mdct_overlap, N, st->overlap, B, C); diff --git a/libcelt/modes.c b/libcelt/modes.c index 8d8ee6954..b354880f3 100644 --- a/libcelt/modes.c +++ b/libcelt/modes.c @@ -77,9 +77,9 @@ const int pbank1[PBANDS128+2] = {0, 2, 4, 6, 8, 12, 20, 28, PITCH_END128, 128}; #define NBANDS256 15 #define PBANDS256 8 #define PITCH_END256 88 -const int qbank3[NBANDS256+2] = {0, 4, 8, 12, 16, 24, 32, 40, 48, 56, 72, 88, 104, 126, 168, 232, 256}; +const int qbank3[NBANDS256+2] = {0, 4, 8, 12, 16, 24, 32, 40, 48, 56, 72, 88, 104, 136, 168, 232, 256}; //const int pbank3[PBANDS256+2] = {0, 8, 16, 24, 40, PITCH_END256, 256}; -const int pbank3[PBANDS256+2] = {0, 4, 8, 12, 16, 24, 40, 56, PITCH_END128, 128}; +const int pbank3[PBANDS256+2] = {0, 4, 8, 12, 16, 24, 40, 56, PITCH_END256, 256}; const CELTMode mode0 = { 128, /**< overlap */ diff --git a/libcelt/quant_bands.c b/libcelt/quant_bands.c index c07915c60..d4dd2eab2 100644 --- a/libcelt/quant_bands.c +++ b/libcelt/quant_bands.c @@ -35,6 +35,38 @@ #include <math.h> #include "os_support.h" +static void quant_energy_mono(const CELTMode *m, float *eBands, float *oldEBands, ec_enc *enc) +{ + int i; + float prev = 0; + for (i=0;i<m->nbEBands;i++) + { + int qi; + float q; + float res; + float x; + float pred = m->ePredCoef*oldEBands[i]+m->eMeans[i]; + + x = 20*log10(.3+eBands[i]); + res = .25f*(i+3.f); + //res = 1; + qi = (int)floor(.5+(x-pred-prev)/res); + ec_laplace_encode(enc, qi, m->eDecay[i]); + q = qi*res; + + //printf("%d ", qi); + //printf("%f %f ", pred+prev+q, x); + //printf("%f ", x-pred); + + oldEBands[i] = pred+prev+q; + eBands[i] = pow(10, .05*oldEBands[i])-.3; + if (eBands[i] < 0) + eBands[i] = 0; + prev = (prev + .5*q); + } + //printf ("\n"); +} + void quant_energy(const CELTMode *m, float *eBands, float *oldEBands, ec_enc *enc) { int C; @@ -43,7 +75,23 @@ void quant_energy(const CELTMode *m, float *eBands, float *oldEBands, ec_enc *en if (C==1) quant_energy_mono(m, eBands, oldEBands, enc); - else if (C==2) + else +#if 1 + { + int c; + for (c=0;c<C;c++) + { + int i; + float E[m->nbEBands]; + for (i=0;i<m->nbEBands;i++) + E[i] = eBands[C*i+c]; + quant_energy_mono(m, E, oldEBands+c*m->nbEBands, enc); + for (i=0;i<m->nbEBands;i++) + eBands[C*i+c] = E[i]; + } + } +#else + if (C==2) { int i; int NB = m->nbEBands; @@ -75,9 +123,11 @@ void quant_energy(const CELTMode *m, float *eBands, float *oldEBands, ec_enc *en } else { celt_fatal("more than 2 channels not supported"); } +#endif } -void quant_energy_mono(const CELTMode *m, float *eBands, float *oldEBands, ec_enc *enc) + +static void unquant_energy_mono(const CELTMode *m, float *eBands, float *oldEBands, ec_dec *dec) { int i; float prev = 0; @@ -86,19 +136,14 @@ void quant_energy_mono(const CELTMode *m, float *eBands, float *oldEBands, ec_en int qi; float q; float res; - float x; float pred = m->ePredCoef*oldEBands[i]+m->eMeans[i]; - x = 20*log10(.3+eBands[i]); res = .25f*(i+3.f); - //res = 1; - qi = (int)floor(.5+(x-pred-prev)/res); - ec_laplace_encode(enc, qi, m->eDecay[i]); + qi = ec_laplace_decode(dec, m->eDecay[i]); q = qi*res; - - //printf("%d ", qi); //printf("%f %f ", pred+prev+q, x); - //printf("%f ", x-pred); + //printf("%d ", qi); + //printf("%f ", x-pred-prev); oldEBands[i] = pred+prev+q; eBands[i] = pow(10, .05*oldEBands[i])-.3; @@ -111,27 +156,20 @@ void quant_energy_mono(const CELTMode *m, float *eBands, float *oldEBands, ec_en void unquant_energy(const CELTMode *m, float *eBands, float *oldEBands, ec_dec *dec) { - int i; - float prev = 0; - for (i=0;i<m->nbEBands;i++) - { - int qi; - float q; - float res; - float pred = m->ePredCoef*oldEBands[i]+m->eMeans[i]; - - res = .25f*(i+3.f); - qi = ec_laplace_decode(dec, m->eDecay[i]); - q = qi*res; - //printf("%f %f ", pred+prev+q, x); - //printf("%d ", qi); - //printf("%f ", x-pred-prev); - - oldEBands[i] = pred+prev+q; - eBands[i] = pow(10, .05*oldEBands[i])-.3; - if (eBands[i] < 0) - eBands[i] = 0; - prev = (prev + .5*q); + int C; + C = m->nbChannels; + + if (C==1) + unquant_energy_mono(m, eBands, oldEBands, dec); + else { + int c; + for (c=0;c<C;c++) + { + int i; + float E[m->nbEBands]; + unquant_energy_mono(m, E, oldEBands+c*m->nbEBands, dec); + for (i=0;i<m->nbEBands;i++) + eBands[C*i+c] = E[i]; + } } - //printf ("\n"); } diff --git a/libcelt/vq.c b/libcelt/vq.c index 9dbb108fc..e38090070 100644 --- a/libcelt/vq.c +++ b/libcelt/vq.c @@ -188,8 +188,9 @@ void alg_quant(float *x, float *W, int N, int K, float *p, float alpha, ec_enc * pulse2comb(N, K, comb, signs, iy[0]); ec_enc_uint64(enc,icwrs64(N, K, comb, signs),ncwrs64(N, K)); - /* Recompute the gain in one pass (to reduce errors) */ - if (0) { + /* Recompute the gain in one pass to reduce the encoder-decoder mismatch + due to the recursive computation used in quantisation */ + if (1) { float Ryp=0; float Rpp=0; float Ryy=0; @@ -203,7 +204,6 @@ void alg_quant(float *x, float *W, int N, int K, float *p, float alpha, ec_enc * for (i=0;i<N;i++) y[0][i] = iy[0][i] - alpha*Ryp*p[i]; - /* Recompute after the projection (I think it's right) */ Ryp = 0; for (i=0;i<N;i++) Ryp += y[0][i]*p[i]; -- GitLab