Doing stereo mixing adaptively based on amplitude difference.
authorJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Fri, 11 Jan 2008 03:02:07 +0000 (14:02 +1100)
committerJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Fri, 11 Jan 2008 03:02:07 +0000 (14:02 +1100)
libcelt/bands.c
libcelt/bands.h
libcelt/celt.c

index aef1465..bf747b9 100644 (file)
@@ -298,3 +298,32 @@ void unquant_bands(const CELTMode *m, float *X, float *P, ec_dec *dec)
    for (i=B*eBands[m->nbEBands];i<B*eBands[m->nbEBands+1];i++)
       X[i] = 0;
 }
+
+void stereo_mix(const CELTMode *m, float *X, float *bank, int dir)
+{
+   int i, B, C;
+   const int *eBands = m->eBands;
+   B = m->nbMdctBlocks;
+   C = m->nbChannels;
+   for (i=0;i<m->nbEBands;i++)
+   {
+      int j;
+      float left, right;
+      float a1, a2;
+      left = bank[i*C];
+      right = bank[i*C+1];
+      a1 = left/sqrt(.01+left*left+right*right);
+      a2 = dir*right/sqrt(.01+left*left+right*right);
+      for (j=B*eBands[i];j<B*eBands[i+1];j++)
+      {
+         float r, l;
+         l = X[j*C];
+         r = X[j*C+1];         
+         X[j*C] = a1*l + a2*r;
+         X[j*C+1] = a1*r - a2*l;
+      }
+   }
+   for (i=B*C*eBands[m->nbEBands];i<B*C*eBands[m->nbEBands+1];i++)
+      X[i] = 0;
+
+}
\ No newline at end of file
index af15e89..a7603e3 100644 (file)
@@ -89,4 +89,6 @@ void quant_bands(const CELTMode *m, float *X, float *P, float *W, ec_enc *enc);
 */
 void unquant_bands(const CELTMode *m, float *X, float *P, ec_dec *dec);
 
+void stereo_mix(const CELTMode *m, float *X, float *bank, int dir);
+
 #endif /* BANDS_H */
index f01ac1e..e887428 100644 (file)
@@ -309,16 +309,22 @@ int celt_encode(CELTEncoder *st, short *pcm)
       normalise_bands(st->mode, P, bandEp);
    }
 
+   quant_energy(st->mode, bandE, st->oldBandE, &st->enc);
+
    if (C==2)
    {
-      haar1(X, B*N*C, 1);
-      haar1(P, B*N*C, 1);
+      stereo_mix(st->mode, X, bandE, 1);
+      stereo_mix(st->mode, P, bandE, 1);
+      //haar1(X, B*N*C, 1);
+      //haar1(P, B*N*C, 1);
    }
+   /* Simulates intensity stereo */
+   //for (i=30;i<N*B;i++)
+   //   X[i*C+1] = P[i*C+1] = 0;
    /* Get a tiny bit more frequency resolution and prevent unstable energy when quantising */
    time_dct(X, N, B, C);
    time_dct(P, N, B, C);
 
-   quant_energy(st->mode, bandE, st->oldBandE, &st->enc);
 
    /* Pitch prediction */
    compute_pitch_gain(st->mode, X, P, gains, bandE);
@@ -339,7 +345,8 @@ int celt_encode(CELTEncoder *st, short *pcm)
    
    time_idct(X, N, B, C);
    if (C==2)
-      haar1(X, B*N*C, 1);
+      //haar1(X, B*N*C, 1);
+      stereo_mix(st->mode, X, bandE, -1);
 
    renormalise_bands(st->mode, X);
    /* Synthesis */
@@ -549,7 +556,8 @@ int celt_decode(CELTDecoder *st, char *data, int len, short *pcm)
    }
 
    if (C==2)
-      haar1(P, B*N*C, 1);
+      //haar1(P, B*N*C, 1);
+      stereo_mix(st->mode, P, bandE, 1);
    time_dct(P, N, B, C);
 
    /* Get the pitch gains */
@@ -563,7 +571,8 @@ int celt_decode(CELTDecoder *st, char *data, int len, short *pcm)
 
    time_idct(X, N, B, C);
    if (C==2)
-      haar1(X, B*N*C, 1);
+      //haar1(X, B*N*C, 1);
+      stereo_mix(st->mode, X, bandE, -1);
 
    renormalise_bands(st->mode, X);