Stereo decoding working again (fixed a few issues in the encoder at the same
authorJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Thu, 10 Jan 2008 04:34:00 +0000 (15:34 +1100)
committerJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Thu, 10 Jan 2008 04:34:00 +0000 (15:34 +1100)
time)

libcelt/celt.c
libcelt/modes.c
libcelt/quant_bands.c
libcelt/vq.c

index c165762..f01ac1e 100644 (file)
@@ -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);
index 8d8ee69..b354880 100644 (file)
@@ -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 */
index c07915c..d4dd2ea 100644 (file)
 #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");
 }
index 9dbb108..e380900 100644 (file)
@@ -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];