Blame libcelt/celt.c

Packit 664db3
/* (C) 2007-2008 Jean-Marc Valin, CSIRO
Packit 664db3
*/
Packit 664db3
/*
Packit 664db3
   Redistribution and use in source and binary forms, with or without
Packit 664db3
   modification, are permitted provided that the following conditions
Packit 664db3
   are met:
Packit 664db3
   
Packit 664db3
   - Redistributions of source code must retain the above copyright
Packit 664db3
   notice, this list of conditions and the following disclaimer.
Packit 664db3
   
Packit 664db3
   - Redistributions in binary form must reproduce the above copyright
Packit 664db3
   notice, this list of conditions and the following disclaimer in the
Packit 664db3
   documentation and/or other materials provided with the distribution.
Packit 664db3
   
Packit 664db3
   - Neither the name of the Xiph.org Foundation nor the names of its
Packit 664db3
   contributors may be used to endorse or promote products derived from
Packit 664db3
   this software without specific prior written permission.
Packit 664db3
   
Packit 664db3
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit 664db3
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit 664db3
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit 664db3
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
Packit 664db3
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Packit 664db3
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
Packit 664db3
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Packit 664db3
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
Packit 664db3
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
Packit 664db3
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Packit 664db3
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 664db3
*/
Packit 664db3
Packit 664db3
#ifdef HAVE_CONFIG_H
Packit 664db3
#include "config.h"
Packit 664db3
#endif
Packit 664db3
Packit 664db3
#define CELT_C
Packit 664db3
Packit 664db3
#include "os_support.h"
Packit 664db3
#include "float_cast.h"
Packit 664db3
#include "mdct.h"
Packit 664db3
#include <math.h>
Packit 664db3
#include "celt.h"
Packit 664db3
#include "pitch.h"
Packit 664db3
#include "kiss_fftr.h"
Packit 664db3
#include "bands.h"
Packit 664db3
#include "modes.h"
Packit 664db3
#include "entcode.h"
Packit 664db3
#include "quant_pitch.h"
Packit 664db3
#include "quant_bands.h"
Packit 664db3
#include "psy.h"
Packit 664db3
#include "rate.h"
Packit 664db3
#include "stack_alloc.h"
Packit 664db3
#include "mathops.h"
Packit 664db3
#include <stdarg.h>
Packit 664db3
Packit 664db3
static const celt_word16_t preemph = QCONST16(0.8f,15);
Packit 664db3
Packit 664db3
#ifdef FIXED_POINT
Packit 664db3
static const celt_word16_t transientWindow[16] = {
Packit 664db3
     279,  1106,  2454,  4276,  6510,  9081, 11900, 14872,
Packit 664db3
   17896, 20868, 23687, 26258, 28492, 30314, 31662, 32489};
Packit 664db3
#else
Packit 664db3
static const float transientWindow[16] = {
Packit 664db3
   0.0085135, 0.0337639, 0.0748914, 0.1304955, 0.1986827, 0.2771308, 0.3631685, 0.4538658,
Packit 664db3
   0.5461342, 0.6368315, 0.7228692, 0.8013173, 0.8695045, 0.9251086, 0.9662361, 0.9914865};
Packit 664db3
#endif
Packit 664db3
Packit 664db3
   
Packit 664db3
/** Encoder state 
Packit 664db3
 @brief Encoder state
Packit 664db3
 */
Packit 664db3
struct CELTEncoder {
Packit 664db3
   const CELTMode *mode;     /**< Mode used by the encoder */
Packit 664db3
   int frame_size;
Packit 664db3
   int block_size;
Packit 664db3
   int overlap;
Packit 664db3
   int channels;
Packit 664db3
   
Packit 664db3
   int pitch_enabled;
Packit 664db3
   int pitch_available;
Packit 664db3
Packit 664db3
   celt_word16_t * restrict preemph_memE; /* Input is 16-bit, so why bother with 32 */
Packit 664db3
   celt_sig_t    * restrict preemph_memD;
Packit 664db3
Packit 664db3
   celt_sig_t *in_mem;
Packit 664db3
   celt_sig_t *out_mem;
Packit 664db3
Packit 664db3
   celt_word16_t *oldBandE;
Packit 664db3
#ifdef EXP_PSY
Packit 664db3
   celt_word16_t *psy_mem;
Packit 664db3
   struct PsyDecay psy;
Packit 664db3
#endif
Packit 664db3
};
Packit 664db3
Packit 664db3
CELTEncoder *celt051_encoder_create(const CELTMode *mode)
Packit 664db3
{
Packit 664db3
   int N, C;
Packit 664db3
   CELTEncoder *st;
Packit 664db3
Packit 664db3
   if (check_mode(mode) != CELT_OK)
Packit 664db3
      return NULL;
Packit 664db3
Packit 664db3
   N = mode->mdctSize;
Packit 664db3
   C = mode->nbChannels;
Packit 664db3
   st = celt_alloc(sizeof(CELTEncoder));
Packit 664db3
   
Packit 664db3
   st->mode = mode;
Packit 664db3
   st->frame_size = N;
Packit 664db3
   st->block_size = N;
Packit 664db3
   st->overlap = mode->overlap;
Packit 664db3
Packit 664db3
   st->pitch_enabled = 1;
Packit 664db3
   st->pitch_available = 1;
Packit 664db3
Packit 664db3
   st->in_mem = celt_alloc(st->overlap*C*sizeof(celt_sig_t));
Packit 664db3
   st->out_mem = celt_alloc((MAX_PERIOD+st->overlap)*C*sizeof(celt_sig_t));
Packit 664db3
Packit 664db3
   st->oldBandE = (celt_word16_t*)celt_alloc(C*mode->nbEBands*sizeof(celt_word16_t));
Packit 664db3
Packit 664db3
   st->preemph_memE = (celt_word16_t*)celt_alloc(C*sizeof(celt_word16_t));
Packit 664db3
   st->preemph_memD = (celt_sig_t*)celt_alloc(C*sizeof(celt_sig_t));
Packit 664db3
Packit 664db3
#ifdef EXP_PSY
Packit 664db3
   st->psy_mem = celt_alloc(MAX_PERIOD*sizeof(celt_word16_t));
Packit 664db3
   psydecay_init(&st->psy, MAX_PERIOD/2, st->mode->Fs);
Packit 664db3
#endif
Packit 664db3
Packit 664db3
   return st;
Packit 664db3
}
Packit 664db3
Packit 664db3
void celt051_encoder_destroy(CELTEncoder *st)
Packit 664db3
{
Packit 664db3
   if (st == NULL)
Packit 664db3
   {
Packit 664db3
      celt_warning("NULL passed to celt051_encoder_destroy");
Packit 664db3
      return;
Packit 664db3
   }
Packit 664db3
   if (check_mode(st->mode) != CELT_OK)
Packit 664db3
      return;
Packit 664db3
Packit 664db3
   celt_free(st->in_mem);
Packit 664db3
   celt_free(st->out_mem);
Packit 664db3
   
Packit 664db3
   celt_free(st->oldBandE);
Packit 664db3
   
Packit 664db3
   celt_free(st->preemph_memE);
Packit 664db3
   celt_free(st->preemph_memD);
Packit 664db3
   
Packit 664db3
#ifdef EXP_PSY
Packit 664db3
   celt_free (st->psy_mem);
Packit 664db3
   psydecay_clear(&st->psy);
Packit 664db3
#endif
Packit 664db3
   
Packit 664db3
   celt_free(st);
Packit 664db3
}
Packit 664db3
Packit 664db3
static inline celt_int16_t FLOAT2INT16(float x)
Packit 664db3
{
Packit 664db3
   x = x*32768.;
Packit 664db3
   x = MAX32(x, -32768);
Packit 664db3
   x = MIN32(x, 32767);
Packit 664db3
   return (celt_int16_t)float2int(x);
Packit 664db3
}
Packit 664db3
Packit 664db3
static inline celt_word16_t SIG2WORD16(celt_sig_t x)
Packit 664db3
{
Packit 664db3
#ifdef FIXED_POINT
Packit 664db3
   x = PSHR32(x, SIG_SHIFT);
Packit 664db3
   x = MAX32(x, -32768);
Packit 664db3
   x = MIN32(x, 32767);
Packit 664db3
   return EXTRACT16(x);
Packit 664db3
#else
Packit 664db3
   return (celt_word16_t)x;
Packit 664db3
#endif
Packit 664db3
}
Packit 664db3
Packit 664db3
static int transient_analysis(celt_word32_t *in, int len, int C, int *transient_time, int *transient_shift)
Packit 664db3
{
Packit 664db3
   int c, i, n;
Packit 664db3
   celt_word32_t ratio;
Packit 664db3
   /* FIXME: Remove the floats here */
Packit 664db3
   VARDECL(celt_word32_t, begin);
Packit 664db3
   SAVE_STACK;
Packit 664db3
   ALLOC(begin, len, celt_word32_t);
Packit 664db3
   for (i=0;i
Packit 664db3
      begin[i] = ABS32(SHR32(in[C*i],SIG_SHIFT));
Packit 664db3
   for (c=1;c
Packit 664db3
   {
Packit 664db3
      for (i=0;i
Packit 664db3
         begin[i] = MAX32(begin[i], ABS32(SHR32(in[C*i+c],SIG_SHIFT)));
Packit 664db3
   }
Packit 664db3
   for (i=1;i
Packit 664db3
      begin[i] = MAX32(begin[i-1],begin[i]);
Packit 664db3
   n = -1;
Packit 664db3
   for (i=8;i
Packit 664db3
   {
Packit 664db3
      if (begin[i] < MULT16_32_Q15(QCONST16(.2f,15),begin[len-1]))
Packit 664db3
         n=i;
Packit 664db3
   }
Packit 664db3
   if (n<32)
Packit 664db3
   {
Packit 664db3
      n = -1;
Packit 664db3
      ratio = 0;
Packit 664db3
   } else {
Packit 664db3
      ratio = DIV32(begin[len-1],1+begin[n-16]);
Packit 664db3
   }
Packit 664db3
   /*printf ("%d %f\n", n, ratio*ratio);*/
Packit 664db3
   if (ratio < 0)
Packit 664db3
      ratio = 0;
Packit 664db3
   if (ratio > 1000)
Packit 664db3
      ratio = 1000;
Packit 664db3
   ratio *= ratio;
Packit 664db3
   if (ratio < 50)
Packit 664db3
      *transient_shift = 0;
Packit 664db3
   else if (ratio < 256)
Packit 664db3
      *transient_shift = 1;
Packit 664db3
   else if (ratio < 4096)
Packit 664db3
      *transient_shift = 2;
Packit 664db3
   else
Packit 664db3
      *transient_shift = 3;
Packit 664db3
   *transient_time = n;
Packit 664db3
   
Packit 664db3
   RESTORE_STACK;
Packit 664db3
   return ratio > 20;
Packit 664db3
}
Packit 664db3
Packit 664db3
/** Apply window and compute the MDCT for all sub-frames and all channels in a frame */
Packit 664db3
static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig_t * restrict in, celt_sig_t * restrict out)
Packit 664db3
{
Packit 664db3
   const int C = CHANNELS(mode);
Packit 664db3
   if (C==1 && !shortBlocks)
Packit 664db3
   {
Packit 664db3
      const mdct_lookup *lookup = MDCT(mode);
Packit 664db3
      const int overlap = OVERLAP(mode);
Packit 664db3
      mdct_forward(lookup, in, out, mode->window, overlap);
Packit 664db3
   } else if (!shortBlocks) {
Packit 664db3
      const mdct_lookup *lookup = MDCT(mode);
Packit 664db3
      const int overlap = OVERLAP(mode);
Packit 664db3
      const int N = FRAMESIZE(mode);
Packit 664db3
      int c;
Packit 664db3
      VARDECL(celt_word32_t, x);
Packit 664db3
      VARDECL(celt_word32_t, tmp);
Packit 664db3
      SAVE_STACK;
Packit 664db3
      ALLOC(x, N+overlap, celt_word32_t);
Packit 664db3
      ALLOC(tmp, N, celt_word32_t);
Packit 664db3
      for (c=0;c
Packit 664db3
      {
Packit 664db3
         int j;
Packit 664db3
         for (j=0;j
Packit 664db3
            x[j] = in[C*j+c];
Packit 664db3
         mdct_forward(lookup, x, tmp, mode->window, overlap);
Packit 664db3
         /* Interleaving the sub-frames */
Packit 664db3
         for (j=0;j
Packit 664db3
            out[C*j+c] = tmp[j];
Packit 664db3
      }
Packit 664db3
      RESTORE_STACK;
Packit 664db3
   } else {
Packit 664db3
      const mdct_lookup *lookup = &mode->shortMdct;
Packit 664db3
      const int overlap = mode->overlap;
Packit 664db3
      const int N = mode->shortMdctSize;
Packit 664db3
      int b, c;
Packit 664db3
      VARDECL(celt_word32_t, x);
Packit 664db3
      VARDECL(celt_word32_t, tmp);
Packit 664db3
      SAVE_STACK;
Packit 664db3
      ALLOC(x, N+overlap, celt_word32_t);
Packit 664db3
      ALLOC(tmp, N, celt_word32_t);
Packit 664db3
      for (c=0;c
Packit 664db3
      {
Packit 664db3
         int B = mode->nbShortMdcts;
Packit 664db3
         for (b=0;b
Packit 664db3
         {
Packit 664db3
            int j;
Packit 664db3
            for (j=0;j
Packit 664db3
               x[j] = in[C*(b*N+j)+c];
Packit 664db3
            mdct_forward(lookup, x, tmp, mode->window, overlap);
Packit 664db3
            /* Interleaving the sub-frames */
Packit 664db3
            for (j=0;j
Packit 664db3
               out[C*(j*B+b)+c] = tmp[j];
Packit 664db3
         }
Packit 664db3
      }
Packit 664db3
      RESTORE_STACK;
Packit 664db3
   }
Packit 664db3
}
Packit 664db3
Packit 664db3
/** Compute the IMDCT and apply window for all sub-frames and all channels in a frame */
Packit 664db3
static void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig_t *X, int transient_time, int transient_shift, celt_sig_t * restrict out_mem)
Packit 664db3
{
Packit 664db3
   int c, N4;
Packit 664db3
   const int C = CHANNELS(mode);
Packit 664db3
   const int N = FRAMESIZE(mode);
Packit 664db3
   const int overlap = OVERLAP(mode);
Packit 664db3
   N4 = (N-overlap)>>1;
Packit 664db3
   for (c=0;c
Packit 664db3
   {
Packit 664db3
      int j;
Packit 664db3
      if (transient_shift==0 && C==1 && !shortBlocks) {
Packit 664db3
         const mdct_lookup *lookup = MDCT(mode);
Packit 664db3
         mdct_backward(lookup, X, out_mem+C*(MAX_PERIOD-N-N4), mode->window, overlap);
Packit 664db3
      } else if (!shortBlocks) {
Packit 664db3
         const mdct_lookup *lookup = MDCT(mode);
Packit 664db3
         VARDECL(celt_word32_t, x);
Packit 664db3
         VARDECL(celt_word32_t, tmp);
Packit 664db3
         SAVE_STACK;
Packit 664db3
         ALLOC(x, 2*N, celt_word32_t);
Packit 664db3
         ALLOC(tmp, N, celt_word32_t);
Packit 664db3
         /* De-interleaving the sub-frames */
Packit 664db3
         for (j=0;j
Packit 664db3
            tmp[j] = X[C*j+c];
Packit 664db3
         /* Prevents problems from the imdct doing the overlap-add */
Packit 664db3
         CELT_MEMSET(x+N4, 0, N);
Packit 664db3
         mdct_backward(lookup, tmp, x, mode->window, overlap);
Packit 664db3
         celt_assert(transient_shift == 0);
Packit 664db3
         /* The first and last part would need to be set to zero if we actually
Packit 664db3
            wanted to use them. */
Packit 664db3
         for (j=0;j
Packit 664db3
            out_mem[C*(MAX_PERIOD-N)+C*j+c] += x[j+N4];
Packit 664db3
         for (j=0;j
Packit 664db3
            out_mem[C*(MAX_PERIOD)+C*(overlap-j-1)+c] = x[2*N-j-N4-1];
Packit 664db3
         for (j=0;j<2*N4;j++)
Packit 664db3
            out_mem[C*(MAX_PERIOD-N)+C*(j+overlap)+c] = x[j+N4+overlap];
Packit 664db3
         RESTORE_STACK;
Packit 664db3
      } else {
Packit 664db3
         int b;
Packit 664db3
         const int N2 = mode->shortMdctSize;
Packit 664db3
         const int B = mode->nbShortMdcts;
Packit 664db3
         const mdct_lookup *lookup = &mode->shortMdct;
Packit 664db3
         VARDECL(celt_word32_t, x);
Packit 664db3
         VARDECL(celt_word32_t, tmp);
Packit 664db3
         SAVE_STACK;
Packit 664db3
         ALLOC(x, 2*N, celt_word32_t);
Packit 664db3
         ALLOC(tmp, N, celt_word32_t);
Packit 664db3
         /* Prevents problems from the imdct doing the overlap-add */
Packit 664db3
         CELT_MEMSET(x+N4, 0, N2);
Packit 664db3
         for (b=0;b
Packit 664db3
         {
Packit 664db3
            /* De-interleaving the sub-frames */
Packit 664db3
            for (j=0;j
Packit 664db3
               tmp[j] = X[C*(j*B+b)+c];
Packit 664db3
            mdct_backward(lookup, tmp, x+N4+N2*b, mode->window, overlap);
Packit 664db3
         }
Packit 664db3
         if (transient_shift > 0)
Packit 664db3
         {
Packit 664db3
#ifdef FIXED_POINT
Packit 664db3
            for (j=0;j<16;j++)
Packit 664db3
               x[N4+transient_time+j-16] = MULT16_32_Q15(SHR16(Q15_ONE-transientWindow[j],transient_shift)+transientWindow[j], SHL32(x[N4+transient_time+j-16],transient_shift));
Packit 664db3
            for (j=transient_time;j
Packit 664db3
               x[N4+j] = SHL32(x[N4+j], transient_shift);
Packit 664db3
#else
Packit 664db3
            for (j=0;j<16;j++)
Packit 664db3
               x[N4+transient_time+j-16] *= 1+transientWindow[j]*((1<
Packit 664db3
            for (j=transient_time;j
Packit 664db3
               x[N4+j] *= 1<
Packit 664db3
#endif
Packit 664db3
         }
Packit 664db3
         /* The first and last part would need to be set to zero if we actually
Packit 664db3
         wanted to use them. */
Packit 664db3
         for (j=0;j
Packit 664db3
            out_mem[C*(MAX_PERIOD-N)+C*j+c] += x[j+N4];
Packit 664db3
         for (j=0;j
Packit 664db3
            out_mem[C*(MAX_PERIOD)+C*(overlap-j-1)+c] = x[2*N-j-N4-1];
Packit 664db3
         for (j=0;j<2*N4;j++)
Packit 664db3
            out_mem[C*(MAX_PERIOD-N)+C*(j+overlap)+c] = x[j+N4+overlap];
Packit 664db3
         RESTORE_STACK;
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
}
Packit 664db3
Packit 664db3
#ifdef FIXED_POINT
Packit 664db3
int celt051_encode(CELTEncoder * restrict st, const celt_int16_t * pcm, celt_int16_t * optional_synthesis, unsigned char *compressed, int nbCompressedBytes)
Packit 664db3
{
Packit 664db3
#else
Packit 664db3
int celt051_encode_float(CELTEncoder * restrict st, const celt_sig_t * pcm, celt_sig_t * optional_synthesis, unsigned char *compressed, int nbCompressedBytes)
Packit 664db3
{
Packit 664db3
#endif
Packit 664db3
   int i, c, N, N4;
Packit 664db3
   int has_pitch;
Packit 664db3
   int id;
Packit 664db3
   int pitch_index;
Packit 664db3
   int bits;
Packit 664db3
   int has_fold=1;
Packit 664db3
   ec_byte_buffer buf;
Packit 664db3
   ec_enc         enc;
Packit 664db3
   VARDECL(celt_sig_t, in);
Packit 664db3
   VARDECL(celt_sig_t, freq);
Packit 664db3
   VARDECL(celt_norm_t, X);
Packit 664db3
   VARDECL(celt_norm_t, P);
Packit 664db3
   VARDECL(celt_ener_t, bandE);
Packit 664db3
   VARDECL(celt_pgain_t, gains);
Packit 664db3
   VARDECL(int, stereo_mode);
Packit 664db3
   VARDECL(int, fine_quant);
Packit 664db3
   VARDECL(celt_word16_t, error);
Packit 664db3
   VARDECL(int, pulses);
Packit 664db3
   VARDECL(int, offsets);
Packit 664db3
#ifdef EXP_PSY
Packit 664db3
   VARDECL(celt_word32_t, mask);
Packit 664db3
   VARDECL(celt_word32_t, tonality);
Packit 664db3
   VARDECL(celt_word32_t, bandM);
Packit 664db3
   VARDECL(celt_ener_t, bandN);
Packit 664db3
#endif
Packit 664db3
   int shortBlocks=0;
Packit 664db3
   int transient_time;
Packit 664db3
   int transient_shift;
Packit 664db3
   const int C = CHANNELS(st->mode);
Packit 664db3
   SAVE_STACK;
Packit 664db3
Packit 664db3
   if (check_mode(st->mode) != CELT_OK)
Packit 664db3
      return CELT_INVALID_MODE;
Packit 664db3
Packit 664db3
   /* The memset is important for now in case the encoder doesn't fill up all the bytes */
Packit 664db3
   CELT_MEMSET(compressed, 0, nbCompressedBytes);
Packit 664db3
   ec_byte_writeinit_buffer(&buf, compressed, nbCompressedBytes);
Packit 664db3
   ec_enc_init(&enc,&buf;;
Packit 664db3
Packit 664db3
   N = st->block_size;
Packit 664db3
   N4 = (N-st->overlap)>>1;
Packit 664db3
   ALLOC(in, 2*C*N-2*C*N4, celt_sig_t);
Packit 664db3
Packit 664db3
   CELT_COPY(in, st->in_mem, C*st->overlap);
Packit 664db3
   for (c=0;c
Packit 664db3
   {
Packit 664db3
      const celt_word16_t * restrict pcmp = pcm+c;
Packit 664db3
      celt_sig_t * restrict inp = in+C*st->overlap+c;
Packit 664db3
      for (i=0;i
Packit 664db3
      {
Packit 664db3
         /* Apply pre-emphasis */
Packit 664db3
         celt_sig_t tmp = SCALEIN(SHL32(EXTEND32(*pcmp), SIG_SHIFT));
Packit 664db3
         *inp = SUB32(tmp, SHR32(MULT16_16(preemph,st->preemph_memE[c]),3));
Packit 664db3
         st->preemph_memE[c] = SCALEIN(*pcmp);
Packit 664db3
         inp += C;
Packit 664db3
         pcmp += C;
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
   CELT_COPY(st->in_mem, in+C*(2*N-2*N4-st->overlap), C*st->overlap);
Packit 664db3
   
Packit 664db3
   /* Transient handling */
Packit 664db3
   if (st->mode->nbShortMdcts > 1)
Packit 664db3
   {
Packit 664db3
      if (transient_analysis(in, N+st->overlap, C, &transient_time, &transient_shift))
Packit 664db3
      {
Packit 664db3
#ifndef FIXED_POINT
Packit 664db3
         float gain_1;
Packit 664db3
#endif
Packit 664db3
         ec_enc_bits(&enc, 0, 1); //Pitch off
Packit 664db3
         ec_enc_bits(&enc, 1, 1); //Transient on
Packit 664db3
         ec_enc_bits(&enc, transient_shift, 2);
Packit 664db3
         if (transient_shift)
Packit 664db3
            ec_enc_uint(&enc, transient_time, N+st->overlap);
Packit 664db3
         /* Apply the inverse shaping window */
Packit 664db3
         if (transient_shift)
Packit 664db3
         {
Packit 664db3
#ifdef FIXED_POINT
Packit 664db3
            for (c=0;c
Packit 664db3
               for (i=0;i<16;i++)
Packit 664db3
                  in[C*(transient_time+i-16)+c] = MULT16_32_Q15(EXTRACT16(SHR32(celt_rcp(Q15ONE+MULT16_16(transientWindow[i],((1<
Packit 664db3
            for (c=0;c
Packit 664db3
               for (i=transient_time;i<N+st->overlap;i++)
Packit 664db3
                  in[C*i+c] = SHR32(in[C*i+c], transient_shift);
Packit 664db3
#else
Packit 664db3
            for (c=0;c
Packit 664db3
               for (i=0;i<16;i++)
Packit 664db3
                  in[C*(transient_time+i-16)+c] /= 1+transientWindow[i]*((1<
Packit 664db3
            gain_1 = 1./(1<
Packit 664db3
            for (c=0;c
Packit 664db3
               for (i=transient_time;i<N+st->overlap;i++)
Packit 664db3
                  in[C*i+c] *= gain_1;
Packit 664db3
#endif
Packit 664db3
         }
Packit 664db3
         shortBlocks = 1;
Packit 664db3
      } else {
Packit 664db3
         transient_time = -1;
Packit 664db3
         transient_shift = 0;
Packit 664db3
         shortBlocks = 0;
Packit 664db3
      }
Packit 664db3
   } else {
Packit 664db3
      transient_time = -1;
Packit 664db3
      transient_shift = 0;
Packit 664db3
      shortBlocks = 0;
Packit 664db3
   }
Packit 664db3
Packit 664db3
   /* Pitch analysis: we do it early to save on the peak stack space */
Packit 664db3
   /* Don't use pitch if there isn't enough data available yet, or if we're using shortBlocks */
Packit 664db3
   has_pitch = st->pitch_enabled && (st->pitch_available >= MAX_PERIOD) && (!shortBlocks);
Packit 664db3
#ifdef EXP_PSY
Packit 664db3
   ALLOC(tonality, MAX_PERIOD/4, celt_word16_t);
Packit 664db3
   {
Packit 664db3
      VARDECL(celt_word16_t, X);
Packit 664db3
      ALLOC(X, MAX_PERIOD/2, celt_word16_t);
Packit 664db3
      find_spectral_pitch(st->mode, st->mode->fft, &st->mode->psy, in, st->out_mem, st->mode->window, X, 2*N-2*N4, MAX_PERIOD-(2*N-2*N4), &pitch_index);
Packit 664db3
      compute_tonality(st->mode, X, st->psy_mem, MAX_PERIOD, tonality, MAX_PERIOD/4);
Packit 664db3
   }
Packit 664db3
#else
Packit 664db3
   if (has_pitch)
Packit 664db3
   {
Packit 664db3
      find_spectral_pitch(st->mode, st->mode->fft, &st->mode->psy, in, st->out_mem, st->mode->window, NULL, 2*N-2*N4, MAX_PERIOD-(2*N-2*N4), &pitch_index);
Packit 664db3
   }
Packit 664db3
#endif
Packit 664db3
   ALLOC(freq, C*N, celt_sig_t); /**< Interleaved signal MDCTs */
Packit 664db3
   
Packit 664db3
   /* Compute MDCTs */
Packit 664db3
   compute_mdcts(st->mode, shortBlocks, in, freq);
Packit 664db3
Packit 664db3
#ifdef EXP_PSY
Packit 664db3
   ALLOC(mask, N, celt_sig_t);
Packit 664db3
   compute_mdct_masking(&st->psy, freq, tonality, st->psy_mem, mask, C*N);
Packit 664db3
   /*for (i=0;i<256;i++)
Packit 664db3
      printf ("%f %f %f ", freq[i], tonality[i], mask[i]);
Packit 664db3
   printf ("\n");*/
Packit 664db3
#endif
Packit 664db3
Packit 664db3
   /* Deferred allocation after find_spectral_pitch() to reduce the peak memory usage */
Packit 664db3
   ALLOC(X, C*N, celt_norm_t);         /**< Interleaved normalised MDCTs */
Packit 664db3
   ALLOC(P, C*N, celt_norm_t);         /**< Interleaved normalised pitch MDCTs*/
Packit 664db3
   ALLOC(bandE,st->mode->nbEBands*C, celt_ener_t);
Packit 664db3
   ALLOC(gains,st->mode->nbPBands, celt_pgain_t);
Packit 664db3
Packit 664db3
Packit 664db3
   /* Band normalisation */
Packit 664db3
   compute_band_energies(st->mode, freq, bandE);
Packit 664db3
   normalise_bands(st->mode, freq, X, bandE);
Packit 664db3
Packit 664db3
#ifdef EXP_PSY
Packit 664db3
   ALLOC(bandN,C*st->mode->nbEBands, celt_ener_t);
Packit 664db3
   ALLOC(bandM,st->mode->nbEBands, celt_ener_t);
Packit 664db3
   compute_noise_energies(st->mode, freq, tonality, bandN);
Packit 664db3
Packit 664db3
   /*for (i=0;i<st->mode->nbEBands;i++)
Packit 664db3
      printf ("%f ", (.1+bandN[i])/(.1+bandE[i]));
Packit 664db3
   printf ("\n");*/
Packit 664db3
   has_fold = 0;
Packit 664db3
   for (i=st->mode->nbPBands;i<st->mode->nbEBands;i++)
Packit 664db3
      if (bandN[i] < .4*bandE[i])
Packit 664db3
         has_fold++;
Packit 664db3
   /*printf ("%d\n", has_fold);*/
Packit 664db3
   if (has_fold>=2)
Packit 664db3
      has_fold = 0;
Packit 664db3
   else
Packit 664db3
      has_fold = 1;
Packit 664db3
   for (i=0;i
Packit 664db3
      mask[i] = sqrt(mask[i]);
Packit 664db3
   compute_band_energies(st->mode, mask, bandM);
Packit 664db3
   /*for (i=0;i<st->mode->nbEBands;i++)
Packit 664db3
      printf ("%f %f ", bandE[i], bandM[i]);
Packit 664db3
   printf ("\n");*/
Packit 664db3
#endif
Packit 664db3
Packit 664db3
   /* Compute MDCTs of the pitch part */
Packit 664db3
   if (has_pitch)
Packit 664db3
   {
Packit 664db3
      celt_word32_t curr_power, pitch_power=0;
Packit 664db3
      /* Normalise the pitch vector as well (discard the energies) */
Packit 664db3
      VARDECL(celt_ener_t, bandEp);
Packit 664db3
      
Packit 664db3
      compute_mdcts(st->mode, 0, st->out_mem+pitch_index*C, freq);
Packit 664db3
      ALLOC(bandEp, st->mode->nbEBands*st->mode->nbChannels, celt_ener_t);
Packit 664db3
      compute_band_energies(st->mode, freq, bandEp);
Packit 664db3
      normalise_bands(st->mode, freq, P, bandEp);
Packit 664db3
      pitch_power = bandEp[0]+bandEp[1]+bandEp[2];
Packit 664db3
      /* Check if we can safely use the pitch (i.e. effective gain isn't too high) */
Packit 664db3
      curr_power = bandE[0]+bandE[1]+bandE[2];
Packit 664db3
      id=-1;
Packit 664db3
      if ((MULT16_32_Q15(QCONST16(.1f, 15),curr_power) + QCONST32(10.f,ENER_SHIFT) < pitch_power))
Packit 664db3
      {
Packit 664db3
         /* Pitch prediction */
Packit 664db3
         compute_pitch_gain(st->mode, X, P, gains);
Packit 664db3
         id = quant_pitch(gains, st->mode->nbPBands);
Packit 664db3
      } 
Packit 664db3
      if (id == -1)
Packit 664db3
         has_pitch = 0;
Packit 664db3
   }
Packit 664db3
   
Packit 664db3
   if (has_pitch) 
Packit 664db3
   {  
Packit 664db3
      unquant_pitch(id, gains, st->mode->nbPBands);
Packit 664db3
      ec_enc_bits(&enc, has_pitch, 1); /* Pitch flag */
Packit 664db3
      ec_enc_bits(&enc, has_fold, 1); /* Folding flag */
Packit 664db3
      ec_enc_bits(&enc, id, 7);
Packit 664db3
      ec_enc_uint(&enc, pitch_index, MAX_PERIOD-(2*N-2*N4));
Packit 664db3
      pitch_quant_bands(st->mode, P, gains);
Packit 664db3
   } else {
Packit 664db3
      if (!shortBlocks)
Packit 664db3
      {
Packit 664db3
         ec_enc_bits(&enc, 0, 1); /* Pitch off */
Packit 664db3
         if (st->mode->nbShortMdcts > 1)
Packit 664db3
           ec_enc_bits(&enc, 0, 1); /* Transient off */
Packit 664db3
      }
Packit 664db3
      has_fold = 1;
Packit 664db3
      /* No pitch, so we just pretend we found a gain of zero */
Packit 664db3
      for (i=0;i<st->mode->nbPBands;i++)
Packit 664db3
         gains[i] = 0;
Packit 664db3
      for (i=0;i
Packit 664db3
         P[i] = 0;
Packit 664db3
   }
Packit 664db3
Packit 664db3
#ifdef STDIN_TUNING2
Packit 664db3
   static int fine_quant[30];
Packit 664db3
   static int pulses[30];
Packit 664db3
   static int init=0;
Packit 664db3
   if (!init)
Packit 664db3
   {
Packit 664db3
      for (i=0;i<st->mode->nbEBands;i++)
Packit 664db3
         scanf("%d ", &fine_quant[i]);
Packit 664db3
      for (i=0;i<st->mode->nbEBands;i++)
Packit 664db3
         scanf("%d ", &pulses[i]);
Packit 664db3
      init = 1;
Packit 664db3
   }
Packit 664db3
#else
Packit 664db3
   ALLOC(fine_quant, st->mode->nbEBands, int);
Packit 664db3
   ALLOC(pulses, st->mode->nbEBands, int);
Packit 664db3
#endif
Packit 664db3
Packit 664db3
   /* Bit allocation */
Packit 664db3
   ALLOC(error, C*st->mode->nbEBands, celt_word16_t);
Packit 664db3
   quant_coarse_energy(st->mode, bandE, st->oldBandE, nbCompressedBytes*8/3, st->mode->prob, error, &enc;;
Packit 664db3
   
Packit 664db3
   ALLOC(offsets, st->mode->nbEBands, int);
Packit 664db3
   ALLOC(stereo_mode, st->mode->nbEBands, int);
Packit 664db3
   stereo_decision(st->mode, X, stereo_mode, st->mode->nbEBands);
Packit 664db3
Packit 664db3
   for (i=0;i<st->mode->nbEBands;i++)
Packit 664db3
      offsets[i] = 0;
Packit 664db3
   bits = nbCompressedBytes*8 - ec_enc_tell(&enc, 0) - 1;
Packit 664db3
#ifndef STDIN_TUNING
Packit 664db3
   compute_allocation(st->mode, offsets, stereo_mode, bits, pulses, fine_quant);
Packit 664db3
#endif
Packit 664db3
Packit 664db3
   quant_fine_energy(st->mode, bandE, st->oldBandE, error, fine_quant, &enc;;
Packit 664db3
Packit 664db3
   /* Residual quantisation */
Packit 664db3
   quant_bands(st->mode, X, P, NULL, bandE, stereo_mode, pulses, shortBlocks, has_fold, nbCompressedBytes*8, &enc;;
Packit 664db3
Packit 664db3
   /* Re-synthesis of the coded audio if required */
Packit 664db3
   if (st->pitch_available>0 || optional_synthesis!=NULL)
Packit 664db3
   {
Packit 664db3
      if (st->pitch_available>0 && st->pitch_available
Packit 664db3
        st->pitch_available+=st->frame_size;
Packit 664db3
Packit 664db3
      if (C==2)
Packit 664db3
         renormalise_bands(st->mode, X);
Packit 664db3
      /* Synthesis */
Packit 664db3
      denormalise_bands(st->mode, X, freq, bandE);
Packit 664db3
      
Packit 664db3
      
Packit 664db3
      CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD+st->overlap-N));
Packit 664db3
      
Packit 664db3
      compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem);
Packit 664db3
      /* De-emphasis and put everything back at the right place in the synthesis history */
Packit 664db3
      if (optional_synthesis != NULL) {
Packit 664db3
         for (c=0;c
Packit 664db3
         {
Packit 664db3
            int j;
Packit 664db3
            for (j=0;j
Packit 664db3
            {
Packit 664db3
               celt_sig_t tmp = MAC16_32_Q15(st->out_mem[C*(MAX_PERIOD-N)+C*j+c],
Packit 664db3
                                   preemph,st->preemph_memD[c]);
Packit 664db3
               st->preemph_memD[c] = tmp;
Packit 664db3
               optional_synthesis[C*j+c] = SCALEOUT(SIG2WORD16(tmp));
Packit 664db3
            }
Packit 664db3
         }
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
   /*fprintf (stderr, "remaining bits after encode = %d\n", nbCompressedBytes*8-ec_enc_tell(&st->enc, 0));*/
Packit 664db3
   /*if (ec_enc_tell(&st->enc, 0) < nbCompressedBytes*8 - 7)
Packit 664db3
      celt_warning_int ("many unused bits: ", nbCompressedBytes*8-ec_enc_tell(&st->enc, 0));*/
Packit 664db3
   /*printf ("%d\n", ec_enc_tell(&st->enc, 0)-8*nbCompressedBytes);*/
Packit 664db3
   /* Finishing the stream with a 0101... pattern so that the decoder can check is everything's right */
Packit 664db3
   {
Packit 664db3
      int val = 0;
Packit 664db3
      while (ec_enc_tell(&enc, 0) < nbCompressedBytes*8)
Packit 664db3
      {
Packit 664db3
         ec_enc_uint(&enc, val, 2);
Packit 664db3
         val = 1-val;
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
   ec_enc_done(&enc;;
Packit 664db3
   {
Packit 664db3
      /*unsigned char *data;*/
Packit 664db3
      int nbBytes = ec_byte_bytes(&buf;;
Packit 664db3
      if (nbBytes > nbCompressedBytes)
Packit 664db3
      {
Packit 664db3
         celt_warning_int ("got too many bytes:", nbBytes);
Packit 664db3
         RESTORE_STACK;
Packit 664db3
         return CELT_INTERNAL_ERROR;
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
Packit 664db3
   RESTORE_STACK;
Packit 664db3
   return nbCompressedBytes;
Packit 664db3
}
Packit 664db3
Packit 664db3
#ifdef FIXED_POINT
Packit 664db3
#ifndef DISABLE_FLOAT_API
Packit 664db3
int celt051_encode_float(CELTEncoder * restrict st, const float * pcm, float * optional_synthesis, unsigned char *compressed, int nbCompressedBytes)
Packit 664db3
{
Packit 664db3
   int j, ret;
Packit 664db3
   const int C = CHANNELS(st->mode);
Packit 664db3
   const int N = st->block_size;
Packit 664db3
   VARDECL(celt_int16_t, in);
Packit 664db3
   SAVE_STACK;
Packit 664db3
   ALLOC(in, C*N, celt_int16_t);
Packit 664db3
Packit 664db3
   for (j=0;j
Packit 664db3
     in[j] = FLOAT2INT16(pcm[j]);
Packit 664db3
Packit 664db3
   if (optional_synthesis != NULL) {
Packit 664db3
     ret=celt051_encode(st,in,in,compressed,nbCompressedBytes);
Packit 664db3
      for (j=0;j
Packit 664db3
         optional_synthesis[j]=in[j]*(1/32768.);
Packit 664db3
   } else {
Packit 664db3
     ret=celt051_encode(st,in,NULL,compressed,nbCompressedBytes);
Packit 664db3
   }
Packit 664db3
   RESTORE_STACK;
Packit 664db3
   return ret;
Packit 664db3
Packit 664db3
}
Packit 664db3
#endif /*DISABLE_FLOAT_API*/
Packit 664db3
#else
Packit 664db3
int celt051_encode(CELTEncoder * restrict st, const celt_int16_t * pcm, celt_int16_t * optional_synthesis, unsigned char *compressed, int nbCompressedBytes)
Packit 664db3
{
Packit 664db3
   int j, ret;
Packit 664db3
   VARDECL(celt_sig_t, in);
Packit 664db3
   const int C = CHANNELS(st->mode);
Packit 664db3
   const int N = st->block_size;
Packit 664db3
   SAVE_STACK;
Packit 664db3
   ALLOC(in, C*N, celt_sig_t);
Packit 664db3
   for (j=0;j
Packit 664db3
     in[j] = SCALEOUT(pcm[j]);
Packit 664db3
   }
Packit 664db3
Packit 664db3
   if (optional_synthesis != NULL) {
Packit 664db3
      ret = celt051_encode_float(st,in,in,compressed,nbCompressedBytes);
Packit 664db3
      for (j=0;j
Packit 664db3
         optional_synthesis[j] = FLOAT2INT16(in[j]);
Packit 664db3
   } else {
Packit 664db3
      ret = celt051_encode_float(st,in,NULL,compressed,nbCompressedBytes);
Packit 664db3
   }
Packit 664db3
   RESTORE_STACK;
Packit 664db3
   return ret;
Packit 664db3
}
Packit 664db3
#endif
Packit 664db3
Packit 664db3
int celt051_encoder_ctl(CELTEncoder * restrict st, int request, ...)
Packit 664db3
{
Packit 664db3
   va_list ap;
Packit 664db3
   va_start(ap, request);
Packit 664db3
   switch (request)
Packit 664db3
   {
Packit 664db3
      case CELT_SET_COMPLEXITY_REQUEST:
Packit 664db3
      {
Packit 664db3
         int value = va_arg(ap, int);
Packit 664db3
         if (value<0 || value>10)
Packit 664db3
            goto bad_arg;
Packit 664db3
         if (value<=2) {
Packit 664db3
            st->pitch_enabled = 0; 
Packit 664db3
            st->pitch_available = 0;
Packit 664db3
         } else {
Packit 664db3
              st->pitch_enabled = 1;
Packit 664db3
              if (st->pitch_available<1)
Packit 664db3
                st->pitch_available = 1;
Packit 664db3
         }   
Packit 664db3
      }
Packit 664db3
      break;
Packit 664db3
      case CELT_SET_LTP_REQUEST:
Packit 664db3
      {
Packit 664db3
         int value = va_arg(ap, int);
Packit 664db3
         if (value<0 || value>1 || (value==1 && st->pitch_available==0))
Packit 664db3
            goto bad_arg;
Packit 664db3
         if (value==0)
Packit 664db3
            st->pitch_enabled = 0;
Packit 664db3
         else
Packit 664db3
            st->pitch_enabled = 1;
Packit 664db3
      }
Packit 664db3
      break;
Packit 664db3
      default:
Packit 664db3
         goto bad_request;
Packit 664db3
   }
Packit 664db3
   va_end(ap);
Packit 664db3
   return CELT_OK;
Packit 664db3
bad_arg:
Packit 664db3
   va_end(ap);
Packit 664db3
   return CELT_BAD_ARG;
Packit 664db3
bad_request:
Packit 664db3
   va_end(ap);
Packit 664db3
   return CELT_UNIMPLEMENTED;
Packit 664db3
}
Packit 664db3
Packit 664db3
/****************************************************************************/
Packit 664db3
/*                                                                          */
Packit 664db3
/*                                DECODER                                   */
Packit 664db3
/*                                                                          */
Packit 664db3
/****************************************************************************/
Packit 664db3
Packit 664db3
Packit 664db3
/** Decoder state 
Packit 664db3
 @brief Decoder state
Packit 664db3
 */
Packit 664db3
struct CELTDecoder {
Packit 664db3
   const CELTMode *mode;
Packit 664db3
   int frame_size;
Packit 664db3
   int block_size;
Packit 664db3
   int overlap;
Packit 664db3
Packit 664db3
   ec_byte_buffer buf;
Packit 664db3
   ec_enc         enc;
Packit 664db3
Packit 664db3
   celt_sig_t * restrict preemph_memD;
Packit 664db3
Packit 664db3
   celt_sig_t *out_mem;
Packit 664db3
Packit 664db3
   celt_word16_t *oldBandE;
Packit 664db3
   
Packit 664db3
   int last_pitch_index;
Packit 664db3
};
Packit 664db3
Packit 664db3
CELTDecoder *celt051_decoder_create(const CELTMode *mode)
Packit 664db3
{
Packit 664db3
   int N, C;
Packit 664db3
   CELTDecoder *st;
Packit 664db3
Packit 664db3
   if (check_mode(mode) != CELT_OK)
Packit 664db3
      return NULL;
Packit 664db3
Packit 664db3
   N = mode->mdctSize;
Packit 664db3
   C = CHANNELS(mode);
Packit 664db3
   st = celt_alloc(sizeof(CELTDecoder));
Packit 664db3
   
Packit 664db3
   st->mode = mode;
Packit 664db3
   st->frame_size = N;
Packit 664db3
   st->block_size = N;
Packit 664db3
   st->overlap = mode->overlap;
Packit 664db3
Packit 664db3
   st->out_mem = celt_alloc((MAX_PERIOD+st->overlap)*C*sizeof(celt_sig_t));
Packit 664db3
   
Packit 664db3
   st->oldBandE = (celt_word16_t*)celt_alloc(C*mode->nbEBands*sizeof(celt_word16_t));
Packit 664db3
Packit 664db3
   st->preemph_memD = (celt_sig_t*)celt_alloc(C*sizeof(celt_sig_t));
Packit 664db3
Packit 664db3
   st->last_pitch_index = 0;
Packit 664db3
   return st;
Packit 664db3
}
Packit 664db3
Packit 664db3
void celt051_decoder_destroy(CELTDecoder *st)
Packit 664db3
{
Packit 664db3
   if (st == NULL)
Packit 664db3
   {
Packit 664db3
      celt_warning("NULL passed to celt051_encoder_destroy");
Packit 664db3
      return;
Packit 664db3
   }
Packit 664db3
   if (check_mode(st->mode) != CELT_OK)
Packit 664db3
      return;
Packit 664db3
Packit 664db3
Packit 664db3
   celt_free(st->out_mem);
Packit 664db3
   
Packit 664db3
   celt_free(st->oldBandE);
Packit 664db3
   
Packit 664db3
   celt_free(st->preemph_memD);
Packit 664db3
Packit 664db3
   celt_free(st);
Packit 664db3
}
Packit 664db3
Packit 664db3
/** Handles lost packets by just copying past data with the same offset as the last
Packit 664db3
    pitch period */
Packit 664db3
static void celt_decode_lost(CELTDecoder * restrict st, celt_word16_t * restrict pcm)
Packit 664db3
{
Packit 664db3
   int c, N;
Packit 664db3
   int pitch_index;
Packit 664db3
   int i, len;
Packit 664db3
   VARDECL(celt_sig_t, freq);
Packit 664db3
   const int C = CHANNELS(st->mode);
Packit 664db3
   int offset;
Packit 664db3
   SAVE_STACK;
Packit 664db3
   N = st->block_size;
Packit 664db3
   ALLOC(freq,C*N, celt_sig_t);         /**< Interleaved signal MDCTs */
Packit 664db3
   
Packit 664db3
   len = N+st->mode->overlap;
Packit 664db3
#if 0
Packit 664db3
   pitch_index = st->last_pitch_index;
Packit 664db3
   
Packit 664db3
   /* Use the pitch MDCT as the "guessed" signal */
Packit 664db3
   compute_mdcts(st->mode, st->mode->window, st->out_mem+pitch_index*C, freq);
Packit 664db3
Packit 664db3
#else
Packit 664db3
   find_spectral_pitch(st->mode, st->mode->fft, &st->mode->psy, st->out_mem+MAX_PERIOD-len, st->out_mem, st->mode->window, NULL, len, MAX_PERIOD-len-100, &pitch_index);
Packit 664db3
   pitch_index = MAX_PERIOD-len-pitch_index;
Packit 664db3
   offset = MAX_PERIOD-pitch_index;
Packit 664db3
   while (offset+len >= MAX_PERIOD)
Packit 664db3
      offset -= pitch_index;
Packit 664db3
   compute_mdcts(st->mode, 0, st->out_mem+offset*C, freq);
Packit 664db3
   for (i=0;i
Packit 664db3
      freq[i] = ADD32(EPSILON, MULT16_32_Q15(QCONST16(.9f,15),freq[i]));
Packit 664db3
#endif
Packit 664db3
   
Packit 664db3
   
Packit 664db3
   
Packit 664db3
   CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD+st->mode->overlap-N));
Packit 664db3
   /* Compute inverse MDCTs */
Packit 664db3
   compute_inv_mdcts(st->mode, 0, freq, -1, 1, st->out_mem);
Packit 664db3
Packit 664db3
   for (c=0;c
Packit 664db3
   {
Packit 664db3
      int j;
Packit 664db3
      for (j=0;j
Packit 664db3
      {
Packit 664db3
         celt_sig_t tmp = MAC16_32_Q15(st->out_mem[C*(MAX_PERIOD-N)+C*j+c],
Packit 664db3
                                preemph,st->preemph_memD[c]);
Packit 664db3
         st->preemph_memD[c] = tmp;
Packit 664db3
         pcm[C*j+c] = SCALEOUT(SIG2WORD16(tmp));
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
   RESTORE_STACK;
Packit 664db3
}
Packit 664db3
Packit 664db3
#ifdef FIXED_POINT
Packit 664db3
int celt051_decode(CELTDecoder * restrict st, unsigned char *data, int len, celt_int16_t * restrict pcm)
Packit 664db3
{
Packit 664db3
#else
Packit 664db3
int celt051_decode_float(CELTDecoder * restrict st, unsigned char *data, int len, celt_sig_t * restrict pcm)
Packit 664db3
{
Packit 664db3
#endif
Packit 664db3
   int i, c, N, N4;
Packit 664db3
   int has_pitch, has_fold;
Packit 664db3
   int pitch_index;
Packit 664db3
   int bits;
Packit 664db3
   ec_dec dec;
Packit 664db3
   ec_byte_buffer buf;
Packit 664db3
   VARDECL(celt_sig_t, freq);
Packit 664db3
   VARDECL(celt_norm_t, X);
Packit 664db3
   VARDECL(celt_norm_t, P);
Packit 664db3
   VARDECL(celt_ener_t, bandE);
Packit 664db3
   VARDECL(celt_pgain_t, gains);
Packit 664db3
   VARDECL(int, stereo_mode);
Packit 664db3
   VARDECL(int, fine_quant);
Packit 664db3
   VARDECL(int, pulses);
Packit 664db3
   VARDECL(int, offsets);
Packit 664db3
Packit 664db3
   int shortBlocks;
Packit 664db3
   int transient_time;
Packit 664db3
   int transient_shift;
Packit 664db3
   const int C = CHANNELS(st->mode);
Packit 664db3
   SAVE_STACK;
Packit 664db3
Packit 664db3
   if (check_mode(st->mode) != CELT_OK)
Packit 664db3
      return CELT_INVALID_MODE;
Packit 664db3
Packit 664db3
   N = st->block_size;
Packit 664db3
   N4 = (N-st->overlap)>>1;
Packit 664db3
Packit 664db3
   ALLOC(freq, C*N, celt_sig_t); /**< Interleaved signal MDCTs */
Packit 664db3
   ALLOC(X, C*N, celt_norm_t);         /**< Interleaved normalised MDCTs */
Packit 664db3
   ALLOC(P, C*N, celt_norm_t);         /**< Interleaved normalised pitch MDCTs*/
Packit 664db3
   ALLOC(bandE, st->mode->nbEBands*C, celt_ener_t);
Packit 664db3
   ALLOC(gains, st->mode->nbPBands, celt_pgain_t);
Packit 664db3
   
Packit 664db3
   if (check_mode(st->mode) != CELT_OK)
Packit 664db3
   {
Packit 664db3
      RESTORE_STACK;
Packit 664db3
      return CELT_INVALID_MODE;
Packit 664db3
   }
Packit 664db3
   if (data == NULL)
Packit 664db3
   {
Packit 664db3
      celt_decode_lost(st, pcm);
Packit 664db3
      RESTORE_STACK;
Packit 664db3
      return 0;
Packit 664db3
   }
Packit 664db3
   
Packit 664db3
   ec_byte_readinit(&buf,data,len);
Packit 664db3
   ec_dec_init(&dec,&buf;;
Packit 664db3
   
Packit 664db3
   has_pitch = ec_dec_bits(&dec, 1);
Packit 664db3
   if (has_pitch)
Packit 664db3
   {
Packit 664db3
      has_fold = ec_dec_bits(&dec, 1);
Packit 664db3
      shortBlocks = 0;
Packit 664db3
   } else if (st->mode->nbShortMdcts > 1){
Packit 664db3
      shortBlocks = ec_dec_bits(&dec, 1);
Packit 664db3
      has_fold = 1;
Packit 664db3
   } else {
Packit 664db3
      shortBlocks = 0;
Packit 664db3
      has_fold = 1;
Packit 664db3
   }
Packit 664db3
   if (shortBlocks)
Packit 664db3
   {
Packit 664db3
      transient_shift = ec_dec_bits(&dec, 2);
Packit 664db3
      if (transient_shift)
Packit 664db3
         transient_time = ec_dec_uint(&dec, N+st->mode->overlap);
Packit 664db3
      else
Packit 664db3
         transient_time = 0;
Packit 664db3
   } else {
Packit 664db3
      transient_time = -1;
Packit 664db3
      transient_shift = 0;
Packit 664db3
   }
Packit 664db3
   
Packit 664db3
   if (has_pitch)
Packit 664db3
   {
Packit 664db3
      int id;
Packit 664db3
      /* Get the pitch gains and index */
Packit 664db3
      id = ec_dec_bits(&dec, 7);
Packit 664db3
      unquant_pitch(id, gains, st->mode->nbPBands);
Packit 664db3
      pitch_index = ec_dec_uint(&dec, MAX_PERIOD-(2*N-2*N4));
Packit 664db3
      st->last_pitch_index = pitch_index;
Packit 664db3
   } else {
Packit 664db3
      pitch_index = 0;
Packit 664db3
      for (i=0;i<st->mode->nbPBands;i++)
Packit 664db3
         gains[i] = 0;
Packit 664db3
   }
Packit 664db3
Packit 664db3
   ALLOC(fine_quant, st->mode->nbEBands, int);
Packit 664db3
   /* Get band energies */
Packit 664db3
   unquant_coarse_energy(st->mode, bandE, st->oldBandE, len*8/3, st->mode->prob, &dec;;
Packit 664db3
   
Packit 664db3
   ALLOC(pulses, st->mode->nbEBands, int);
Packit 664db3
   ALLOC(offsets, st->mode->nbEBands, int);
Packit 664db3
   ALLOC(stereo_mode, st->mode->nbEBands, int);
Packit 664db3
   stereo_decision(st->mode, X, stereo_mode, st->mode->nbEBands);
Packit 664db3
Packit 664db3
   for (i=0;i<st->mode->nbEBands;i++)
Packit 664db3
      offsets[i] = 0;
Packit 664db3
Packit 664db3
   bits = len*8 - ec_dec_tell(&dec, 0) - 1;
Packit 664db3
   compute_allocation(st->mode, offsets, stereo_mode, bits, pulses, fine_quant);
Packit 664db3
   /*bits = ec_dec_tell(&dec, 0);
Packit 664db3
   compute_fine_allocation(st->mode, fine_quant, (20*C+len*8/5-(ec_dec_tell(&dec, 0)-bits))/C);*/
Packit 664db3
   
Packit 664db3
   unquant_fine_energy(st->mode, bandE, st->oldBandE, fine_quant, &dec;;
Packit 664db3
Packit 664db3
Packit 664db3
   if (has_pitch) 
Packit 664db3
   {
Packit 664db3
      VARDECL(celt_ener_t, bandEp);
Packit 664db3
      
Packit 664db3
      /* Pitch MDCT */
Packit 664db3
      compute_mdcts(st->mode, 0, st->out_mem+pitch_index*C, freq);
Packit 664db3
      ALLOC(bandEp, st->mode->nbEBands*C, celt_ener_t);
Packit 664db3
      compute_band_energies(st->mode, freq, bandEp);
Packit 664db3
      normalise_bands(st->mode, freq, P, bandEp);
Packit 664db3
      /* Apply pitch gains */
Packit 664db3
      pitch_quant_bands(st->mode, P, gains);
Packit 664db3
   } else {
Packit 664db3
      for (i=0;i
Packit 664db3
         P[i] = 0;
Packit 664db3
   }
Packit 664db3
Packit 664db3
   /* Decode fixed codebook and merge with pitch */
Packit 664db3
   unquant_bands(st->mode, X, P, bandE, stereo_mode, pulses, shortBlocks, has_fold, len*8, &dec;;
Packit 664db3
Packit 664db3
   if (C==2)
Packit 664db3
   {
Packit 664db3
      renormalise_bands(st->mode, X);
Packit 664db3
   }
Packit 664db3
   /* Synthesis */
Packit 664db3
   denormalise_bands(st->mode, X, freq, bandE);
Packit 664db3
Packit 664db3
Packit 664db3
   CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD+st->overlap-N));
Packit 664db3
   /* Compute inverse MDCTs */
Packit 664db3
   compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem);
Packit 664db3
Packit 664db3
   for (c=0;c
Packit 664db3
   {
Packit 664db3
      int j;
Packit 664db3
      for (j=0;j
Packit 664db3
      {
Packit 664db3
         celt_sig_t tmp = MAC16_32_Q15(st->out_mem[C*(MAX_PERIOD-N)+C*j+c],
Packit 664db3
                                preemph,st->preemph_memD[c]);
Packit 664db3
         st->preemph_memD[c] = tmp;
Packit 664db3
         pcm[C*j+c] = SCALEOUT(SIG2WORD16(tmp));
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
Packit 664db3
   {
Packit 664db3
      unsigned int val = 0;
Packit 664db3
      while (ec_dec_tell(&dec, 0) < len*8)
Packit 664db3
      {
Packit 664db3
         if (ec_dec_uint(&dec, 2) != val)
Packit 664db3
         {
Packit 664db3
            celt_warning("decode error");
Packit 664db3
            RESTORE_STACK;
Packit 664db3
            return CELT_CORRUPTED_DATA;
Packit 664db3
         }
Packit 664db3
         val = 1-val;
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
Packit 664db3
   RESTORE_STACK;
Packit 664db3
   return 0;
Packit 664db3
   /*printf ("\n");*/
Packit 664db3
}
Packit 664db3
Packit 664db3
#ifdef FIXED_POINT
Packit 664db3
#ifndef DISABLE_FLOAT_API
Packit 664db3
int celt051_decode_float(CELTDecoder * restrict st, unsigned char *data, int len, float * restrict pcm)
Packit 664db3
{
Packit 664db3
   int j, ret;
Packit 664db3
   const int C = CHANNELS(st->mode);
Packit 664db3
   const int N = st->block_size;
Packit 664db3
   VARDECL(celt_int16_t, out);
Packit 664db3
   SAVE_STACK;
Packit 664db3
   ALLOC(out, C*N, celt_int16_t);
Packit 664db3
Packit 664db3
   ret=celt051_decode(st, data, len, out);
Packit 664db3
Packit 664db3
   for (j=0;j
Packit 664db3
     pcm[j]=out[j]*(1/32768.);
Packit 664db3
   RESTORE_STACK;
Packit 664db3
   return ret;
Packit 664db3
}
Packit 664db3
#endif /*DISABLE_FLOAT_API*/
Packit 664db3
#else
Packit 664db3
int celt051_decode(CELTDecoder * restrict st, unsigned char *data, int len, celt_int16_t * restrict pcm)
Packit 664db3
{
Packit 664db3
   int j, ret;
Packit 664db3
   VARDECL(celt_sig_t, out);
Packit 664db3
   const int C = CHANNELS(st->mode);
Packit 664db3
   const int N = st->block_size;
Packit 664db3
   SAVE_STACK;
Packit 664db3
   ALLOC(out, C*N, celt_sig_t);
Packit 664db3
Packit 664db3
   ret=celt051_decode_float(st, data, len, out);
Packit 664db3
Packit 664db3
   for (j=0;j
Packit 664db3
     pcm[j] = FLOAT2INT16 (out[j]);
Packit 664db3
Packit 664db3
   RESTORE_STACK;
Packit 664db3
   return ret;
Packit 664db3
}
Packit 664db3
#endif