shithub: opus

Download patch

ref: 269d40a5c0d99123c97499765024f469c28c3e38
parent: bb57fe44e2a152ed7539f60d4a705874b7576ba5
author: Jean-Marc Valin <[email protected]>
date: Fri Dec 7 06:29:45 EST 2007

Added decoder code (not working yet)

--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -41,7 +41,7 @@
 
 #define MAX_PERIOD 1024
 
-struct CELTState {
+struct CELTEncoder {
    const CELTMode *mode;
    int frame_size;
    int block_size;
@@ -67,12 +67,12 @@
 
 
 
-CELTState *celt_encoder_new(const CELTMode *mode)
+CELTEncoder *celt_encoder_new(const CELTMode *mode)
 {
    int i, N, B;
    N = mode->mdctSize;
    B = mode->nbMdctBlocks;
-   CELTState *st = celt_alloc(sizeof(CELTState));
+   CELTEncoder *st = celt_alloc(sizeof(CELTEncoder));
    
    st->mode = mode;
    st->frame_size = B*N;
@@ -97,7 +97,7 @@
    return st;
 }
 
-void celt_encoder_destroy(CELTState *st)
+void celt_encoder_destroy(CELTEncoder *st)
 {
    if (st == NULL)
    {
@@ -162,7 +162,7 @@
 
 }
 
-int celt_encode(CELTState *st, short *pcm)
+int celt_encode(CELTEncoder *st, short *pcm)
 {
    int i, N, B;
    N = st->block_size;
@@ -276,5 +276,138 @@
    ec_enc_done(&st->enc);
    //printf ("%d\n", ec_byte_bytes(&st->buf));
    return 0;
+}
+
+/****************************************************************************/
+/*                                Decoder                                   */
+/****************************************************************************/
+
+
+
+struct CELTDecoder {
+   const CELTMode *mode;
+   int frame_size;
+   int block_size;
+   int nb_blocks;
+   
+   ec_byte_buffer buf;
+   ec_enc         enc;
+
+   float preemph;
+   float preemph_memD;
+   
+   mdct_lookup mdct_lookup;
+   
+   float *window;
+   float *mdct_overlap;
+   float *out_mem;
+
+   float *oldBandE;
+};
+
+CELTDecoder *celt_decoder_new(const CELTMode *mode)
+{
+   int i, N, B;
+   N = mode->mdctSize;
+   B = mode->nbMdctBlocks;
+   CELTDecoder *st = celt_alloc(sizeof(CELTDecoder));
+   
+   st->mode = mode;
+   st->frame_size = B*N;
+   st->block_size = N;
+   st->nb_blocks  = B;
+   
+   ec_byte_writeinit(&st->buf);
+
+   mdct_init(&st->mdct_lookup, 2*N);
+   
+   st->window = celt_alloc(2*N*sizeof(float));
+   st->mdct_overlap = celt_alloc(N*sizeof(float));
+   st->out_mem = celt_alloc(MAX_PERIOD*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));
+   
+   st->oldBandE = celt_alloc(mode->nbEBands*sizeof(float));
+
+   st->preemph = 0.8;
+   return st;
+}
+
+void celt_decoder_destroy(CELTDecoder *st)
+{
+   if (st == NULL)
+   {
+      celt_warning("NULL passed to celt_encoder_destroy");
+      return;
+   }
+
+   mdct_clear(&st->mdct_lookup);
+
+   celt_free(st->window);
+   celt_free(st->mdct_overlap);
+   celt_free(st->out_mem);
+   
+   celt_free(st->oldBandE);
+   celt_free(st);
+}
+
+int celt_decode(CELTDecoder *st, short *pcm)
+{
+   int i, N, B;
+   N = st->block_size;
+   B = st->nb_blocks;
+   
+   float X[B*N];         /**< Interleaved signal MDCTs */
+   float P[B*N];         /**< Interleaved pitch MDCTs*/
+   float bandE[st->mode->nbEBands];
+   float gains[st->mode->nbPBands];
+   int pitch_index;
+
+   compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index, P, N, B);
+
+   //haar1(P, B*N);
+
+   {
+      float bandEp[st->mode->nbEBands];
+      compute_band_energies(st->mode, P, bandEp);
+      normalise_bands(st->mode, P, bandEp);
+   }
+
+   /* Apply pitch gains */
+   
+   /* Decode fixed codebook */
+   
+   /* Merge pitch and fixed codebook */
+   
+   /* Synthesis */
+   denormalise_bands(st->mode, X, bandE);
+
+   //inv_haar1(X, B*N);
+
+   CELT_MOVE(st->out_mem, st->out_mem+B*N, MAX_PERIOD-B*N);
+   /* Compute inverse MDCTs */
+   for (i=0;i<B;i++)
+   {
+      int j;
+      float x[2*N];
+      float tmp[N];
+      /* De-interleaving the sub-frames */
+      for (j=0;j<N;j++)
+         tmp[j] = X[B*j+i];
+      mdct_backward(&st->mdct_lookup, tmp, x);
+      for (j=0;j<2*N;j++)
+         x[j] = st->window[j]*x[j];
+      for (j=0;j<N;j++)
+         st->out_mem[MAX_PERIOD+(i-B)*N+j] = x[j]+st->mdct_overlap[j];
+      for (j=0;j<N;j++)
+         st->mdct_overlap[j] = x[N+j];
+      
+      for (j=0;j<N;j++)
+      {
+         float tmp = st->out_mem[MAX_PERIOD+(i-B)*N+j] + st->preemph*st->preemph_memD;
+         st->preemph_memD = tmp;
+         pcm[i*N+j] = (short)floor(.5+tmp);
+      }
+   }
 }
 
--- a/libcelt/celt.h
+++ b/libcelt/celt.h
@@ -32,18 +32,28 @@
 #ifndef CELT_H
 #define CELT_H
 
-typedef struct CELTState CELTState;
+typedef struct CELTEncoder CELTEncoder;
+typedef struct CELTDecoder CELTDecoder;
 
 typedef struct CELTMode CELTMode;
 
 extern const CELTMode const *celt_mode1;
 
-CELTState *celt_encoder_new(const CELTMode *mode);
+/* Encoder stuff */
 
-void celt_encoder_destroy(CELTState *st);
+CELTEncoder *celt_encoder_new(const CELTMode *mode);
 
-int celt_encode(CELTState *st, short *pcm);
+void celt_encoder_destroy(CELTEncoder *st);
 
+int celt_encode(CELTEncoder *st, short *pcm);
 
+
+/* Decoder stuff */
+
+CELTDecoder *celt_decoder_new(const CELTMode *mode);
+
+void celt_decoder_destroy(CELTDecoder *st);
+
+int celt_decode(CELTDecoder *st, short *pcm);
 
 #endif /*CELT_H */
--- a/libcelt/testcelt.c
+++ b/libcelt/testcelt.c
@@ -41,7 +41,7 @@
    char *inFile, *outFile;
    FILE *fin, *fout;
    short in[FRAME_SIZE];
-   CELTState *st;
+   CELTEncoder *st;
    
    inFile = argv[1];
    fin = fopen(inFile, "rb");