Allowing reduced overlap MDCTs as an alternative
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Thu, 3 Jan 2008 09:53:01 +0000 (20:53 +1100)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Thu, 3 Jan 2008 09:53:01 +0000 (20:53 +1100)
to multiple MDCTs per frame. Not complete yet.

libcelt/celt.c
libcelt/modes.c
libcelt/modes.h

index 501af36..557695c 100644 (file)
@@ -50,6 +50,7 @@ struct CELTEncoder {
    int frame_size;
    int block_size;
    int nb_blocks;
+   int overlap;
    int channels;
    int Fs;
    
@@ -75,7 +76,7 @@ struct CELTEncoder {
 
 CELTEncoder *celt_encoder_new(const CELTMode *mode)
 {
-   int i, N, B, C;
+   int i, N, B, C, N4;
    N = mode->mdctSize;
    B = mode->nbMdctBlocks;
    C = mode->nbChannels;
@@ -85,8 +86,10 @@ CELTEncoder *celt_encoder_new(const CELTMode *mode)
    st->frame_size = B*N;
    st->block_size = N;
    st->nb_blocks  = B;
+   st->overlap = mode->overlap;
    st->Fs = 44100;
-   
+
+   N4 = (N-st->overlap)/2;
    ec_byte_writeinit(&st->buf);
    ec_enc_init(&st->enc,&st->buf);
 
@@ -97,9 +100,13 @@ CELTEncoder *celt_encoder_new(const CELTMode *mode)
    st->in_mem = celt_alloc(N*C*sizeof(float));
    st->mdct_overlap = celt_alloc(N*C*sizeof(float));
    st->out_mem = celt_alloc(MAX_PERIOD*C*sizeof(float));
-   for (i=0;i<N;i++)
-      st->window[i] = st->window[2*N-i-1] = sin(.5*M_PI* sin(.5*M_PI*(i+.5)/N) * sin(.5*M_PI*(i+.5)/N));
-   
+   for (i=0;i<2*N;i++)
+      st->window[i] = 0;
+   for (i=0;i<st->overlap;i++)
+      st->window[N4+i] = st->window[2*N-N4-i-1] 
+            = 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->preemph = 0.8;
@@ -220,31 +227,37 @@ static void compute_inv_mdcts(mdct_lookup *mdct_lookup, float *window, float *X,
 
 int celt_encode(CELTEncoder *st, short *pcm)
 {
-   int i, c, N, B, C;
+   int i, c, N, B, C, N4;
    N = st->block_size;
    B = st->nb_blocks;
    C = st->mode->nbChannels;
    float in[(B+1)*C*N];
-   
+
    float X[B*C*N];         /**< Interleaved signal MDCTs */
    float P[B*C*N];         /**< Interleaved pitch MDCTs*/
    float mask[B*C*N];      /**< Masking curve */
    float bandE[st->mode->nbEBands];
    float gains[st->mode->nbPBands];
    int pitch_index;
-   
+
+   N4 = (N-st->overlap)/2;
+
    for (c=0;c<C;c++)
    {
-      for (i=0;i<N;i++)
-         in[C*i+c] = st->in_mem[C*i+c];
-      for (;i<(B+1)*N;i++)
+      for (i=0;i<N4;i++)
+         in[C*i+c] = 0;
+      for (i=0;i<st->overlap;i++)
+         in[C*(i+N4)+c] = st->in_mem[C*i+c];
+      for (i=0;i<B*N;i++)
       {
-         float tmp = pcm[C*(i-N)+c];
-         in[C*i+c] = tmp - st->preemph*st->preemph_memE[c];
+         float tmp = pcm[C*i+c];
+         in[C*(i+st->overlap+N4)+c] = tmp - st->preemph*st->preemph_memE[c];
          st->preemph_memE[c] = tmp;
       }
-      for (i=0;i<N;i++)
-         st->in_mem[C*i+c] = in[C*(B*N+i)+c];
+      for (i=N*(B+1)-N4;i<N*(B+1);i++)
+         in[C*i+c] = 0;
+      for (i=0;i<st->overlap;i++)
+         st->in_mem[C*i+c] = in[C*(N*(B+1)-N4-st->overlap+i)+c];
    }
    //for (i=0;i<(B+1)*C*N;i++) printf ("%f(%d) ", in[i], i); printf ("\n");
    /* Compute MDCTs */
@@ -375,7 +388,8 @@ struct CELTDecoder {
    int frame_size;
    int block_size;
    int nb_blocks;
-   
+   int overlap;
+
    ec_byte_buffer buf;
    ec_enc         enc;
 
@@ -395,7 +409,7 @@ struct CELTDecoder {
 
 CELTDecoder *celt_decoder_new(const CELTMode *mode)
 {
-   int i, N, B, C;
+   int i, N, B, C, N4;
    N = mode->mdctSize;
    B = mode->nbMdctBlocks;
    C = mode->nbChannels;
@@ -405,14 +419,23 @@ CELTDecoder *celt_decoder_new(const CELTMode *mode)
    st->frame_size = B*N;
    st->block_size = N;
    st->nb_blocks  = B;
+   st->overlap = mode->overlap;
+
+   N4 = (N-st->overlap)/2;
    
    mdct_init(&st->mdct_lookup, 2*N);
    
    st->window = celt_alloc(2*N*sizeof(float));
    st->mdct_overlap = celt_alloc(N*C*sizeof(float));
    st->out_mem = celt_alloc(MAX_PERIOD*C*sizeof(float));
-   for (i=0;i<N;i++)
-      st->window[i] = st->window[2*N-i-1] = sin(.5*M_PI* sin(.5*M_PI*(i+.5)/N) * sin(.5*M_PI*(i+.5)/N));
+
+   for (i=0;i<2*N;i++)
+      st->window[i] = 0;
+   for (i=0;i<st->overlap;i++)
+      st->window[N4+i] = st->window[2*N-N4-i-1] 
+            = 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));
 
index 685ef78..48303d4 100644 (file)
@@ -71,12 +71,15 @@ const int qpulses2s[NBANDS128] ={38,30,24,20,24,20, 18, 16, 14, 20,-20,-14, -8,
 
 const int pbank1[PBANDS128+2] = {0, 4, 8, 12, 20, PITCH_END128, 128};
 
-const int qbank3[NBANDS128+2] = {0, 4, 8, 12, 16, 24, 32, 40, 48, 56, 72, 88, 104, 126, 168, 232, 256};
+
+#define NBANDS256 15
+#define PBANDS256 5
 #define PITCH_END256 72
-const int pbank3[PBANDS128+2] = {0, 8, 16, 24, 40, PITCH_END256, 256};
+const int qbank3[NBANDS256+2] = {0, 4, 8, 12, 16, 24, 32, 40, 48, 56, 72, 88, 104, 126, 168, 232, 256};
+const int pbank3[PBANDS256+2] = {0, 8, 16, 24, 40, PITCH_END256, 256};
 
 const CELTMode mode0 = {
-   256,         /**< frameSize */
+   128,         /**< overlap */
    128,         /**< mdctSize */
    2,           /**< nbMdctBlocks */
    1,           /**< channels */
@@ -97,7 +100,7 @@ const CELTMode mode0 = {
 
 /* Approx 38 kbps @ 44.1 kHz */
 const CELTMode mode1 = {
-   256,         /**< frameSize */
+   128,         /**< overlap */
    128,         /**< mdctSize */
    2,           /**< nbMdctBlocks */
    1,           /**< channels */
@@ -117,7 +120,7 @@ const CELTMode mode1 = {
 
 /* Approx 58 kbps @ 44.1 kHz */
 const CELTMode mode2 = {
-   256,         /**< frameSize */
+   128,         /**< overlap */
    128,         /**< mdctSize */
    2,           /**< nbMdctBlocks */
    1,           /**< channels */
@@ -136,18 +139,18 @@ const CELTMode mode2 = {
 };
 
 const CELTMode mode3 = {
-   512,         /**< frameSize */
+   128,         /**< overlap */
    256,         /**< mdctSize */
-   2,           /**< nbMdctBlocks */
+   1,           /**< nbMdctBlocks */
    1,           /**< channels */
    
-   NBANDS128,   /**< nbEBands */
-   PBANDS128,   /**< nbPBands */
+   NBANDS256,   /**< nbEBands */
+   PBANDS256,   /**< nbPBands */
    PITCH_END256,/**< pitchEnd */
    
    qbank3,      /**< eBands */
    pbank3,      /**< pBands*/
-   qpulses2,    /**< nbPulses */
+   qpulses1,    /**< nbPulses */
    
    0.7,         /**< ePredCoef */
    means,       /**< eMeans */
@@ -156,7 +159,7 @@ const CELTMode mode3 = {
 
 /* Stereo mode around 120 kbps */
 const CELTMode mode4 = {
-   256,         /**< frameSize */
+   128,         /**< overlap */
    128,         /**< mdctSize */
    2,           /**< nbMdctBlocks */
    2,           /**< channels */
index 63cd818..8dd743e 100644 (file)
@@ -35,7 +35,7 @@
 #include "celt.h"
 
 struct CELTMode {
-   int          frameSize;
+   int          overlap;
    int          mdctSize;
    int          nbMdctBlocks;
    int          nbChannels;