VBR support. VBR API and VBR support in celtenc.
[opus.git] / libcelt / celt.c
1 /* (C) 2007-2008 Jean-Marc Valin, CSIRO
2    (C) 2008 Gregory Maxwell */
3 /*
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions
6    are met:
7    
8    - Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10    
11    - Redistributions in binary form must reproduce the above copyright
12    notice, this list of conditions and the following disclaimer in the
13    documentation and/or other materials provided with the distribution.
14    
15    - Neither the name of the Xiph.org Foundation nor the names of its
16    contributors may be used to endorse or promote products derived from
17    this software without specific prior written permission.
18    
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #define CELT_C
37
38 #include "os_support.h"
39 #include "mdct.h"
40 #include <math.h>
41 #include "celt.h"
42 #include "pitch.h"
43 #include "kiss_fftr.h"
44 #include "bands.h"
45 #include "modes.h"
46 #include "entcode.h"
47 #include "quant_bands.h"
48 #include "psy.h"
49 #include "rate.h"
50 #include "stack_alloc.h"
51 #include "mathops.h"
52 #include "float_cast.h"
53 #include <stdarg.h>
54
55 static const celt_word16_t preemph = QCONST16(0.8f,15);
56
57 #ifdef FIXED_POINT
58 static const celt_word16_t transientWindow[16] = {
59      279,  1106,  2454,  4276,  6510,  9081, 11900, 14872,
60    17896, 20868, 23687, 26258, 28492, 30314, 31662, 32489};
61 #else
62 static const float transientWindow[16] = {
63    0.0085135, 0.0337639, 0.0748914, 0.1304955, 0.1986827, 0.2771308, 0.3631685, 0.4538658,
64    0.5461342, 0.6368315, 0.7228692, 0.8013173, 0.8695045, 0.9251086, 0.9662361, 0.9914865};
65 #endif
66
67    
68 /** Encoder state 
69  @brief Encoder state
70  */
71 struct CELTEncoder {
72    const CELTMode *mode;     /**< Mode used by the encoder */
73    int frame_size;
74    int block_size;
75    int overlap;
76    int channels;
77    
78    int pitch_enabled;
79    int pitch_available;
80    int delayedIntra;
81    int VBR_rate; /* Target number of 16th bits per frame */
82    celt_word16_t * restrict preemph_memE; /* Input is 16-bit, so why bother with 32 */
83    celt_sig_t    * restrict preemph_memD;
84
85    celt_sig_t *in_mem;
86    celt_sig_t *out_mem;
87
88    celt_word16_t *oldBandE;
89 #ifdef EXP_PSY
90    celt_word16_t *psy_mem;
91    struct PsyDecay psy;
92 #endif
93 };
94
95 CELTEncoder *celt_encoder_create(const CELTMode *mode)
96 {
97    int N, C;
98    CELTEncoder *st;
99
100    if (check_mode(mode) != CELT_OK)
101       return NULL;
102
103    N = mode->mdctSize;
104    C = mode->nbChannels;
105    st = celt_alloc(sizeof(CELTEncoder));
106    
107    st->mode = mode;
108    st->frame_size = N;
109    st->block_size = N;
110    st->overlap = mode->overlap;
111
112    st->VBR_rate = 0;
113    st->pitch_enabled = 1;
114    st->pitch_available = 1;
115    st->delayedIntra = 1;
116
117    st->in_mem = celt_alloc(st->overlap*C*sizeof(celt_sig_t));
118    st->out_mem = celt_alloc((MAX_PERIOD+st->overlap)*C*sizeof(celt_sig_t));
119
120    st->oldBandE = (celt_word16_t*)celt_alloc(C*mode->nbEBands*sizeof(celt_word16_t));
121
122    st->preemph_memE = (celt_word16_t*)celt_alloc(C*sizeof(celt_word16_t));
123    st->preemph_memD = (celt_sig_t*)celt_alloc(C*sizeof(celt_sig_t));
124
125 #ifdef EXP_PSY
126    st->psy_mem = celt_alloc(MAX_PERIOD*sizeof(celt_word16_t));
127    psydecay_init(&st->psy, MAX_PERIOD/2, st->mode->Fs);
128 #endif
129
130    return st;
131 }
132
133 void celt_encoder_destroy(CELTEncoder *st)
134 {
135    if (st == NULL)
136    {
137       celt_warning("NULL passed to celt_encoder_destroy");
138       return;
139    }
140    if (check_mode(st->mode) != CELT_OK)
141       return;
142
143    celt_free(st->in_mem);
144    celt_free(st->out_mem);
145    
146    celt_free(st->oldBandE);
147    
148    celt_free(st->preemph_memE);
149    celt_free(st->preemph_memD);
150    
151 #ifdef EXP_PSY
152    celt_free (st->psy_mem);
153    psydecay_clear(&st->psy);
154 #endif
155    
156    celt_free(st);
157 }
158
159 static inline celt_int16_t FLOAT2INT16(float x)
160 {
161    x = x*32768.;
162    x = MAX32(x, -32768);
163    x = MIN32(x, 32767);
164    return (celt_int16_t)float2int(x);
165 }
166
167 static inline celt_word16_t SIG2WORD16(celt_sig_t x)
168 {
169 #ifdef FIXED_POINT
170    x = PSHR32(x, SIG_SHIFT);
171    x = MAX32(x, -32768);
172    x = MIN32(x, 32767);
173    return EXTRACT16(x);
174 #else
175    return (celt_word16_t)x;
176 #endif
177 }
178
179 static int transient_analysis(celt_word32_t *in, int len, int C, int *transient_time, int *transient_shift)
180 {
181    int c, i, n;
182    celt_word32_t ratio;
183    /* FIXME: Remove the floats here */
184    VARDECL(celt_word32_t, begin);
185    SAVE_STACK;
186    ALLOC(begin, len, celt_word32_t);
187    for (i=0;i<len;i++)
188       begin[i] = ABS32(SHR32(in[C*i],SIG_SHIFT));
189    for (c=1;c<C;c++)
190    {
191       for (i=0;i<len;i++)
192          begin[i] = MAX32(begin[i], ABS32(SHR32(in[C*i+c],SIG_SHIFT)));
193    }
194    for (i=1;i<len;i++)
195       begin[i] = MAX32(begin[i-1],begin[i]);
196    n = -1;
197    for (i=8;i<len-8;i++)
198    {
199       if (begin[i] < MULT16_32_Q15(QCONST16(.2f,15),begin[len-1]))
200          n=i;
201    }
202    if (n<32)
203    {
204       n = -1;
205       ratio = 0;
206    } else {
207       ratio = DIV32(begin[len-1],1+begin[n-16]);
208    }
209    /*printf ("%d %f\n", n, ratio*ratio);*/
210    if (ratio < 0)
211       ratio = 0;
212    if (ratio > 1000)
213       ratio = 1000;
214    ratio *= ratio;
215    if (ratio < 50)
216       *transient_shift = 0;
217    else if (ratio < 256)
218       *transient_shift = 1;
219    else if (ratio < 4096)
220       *transient_shift = 2;
221    else
222       *transient_shift = 3;
223    *transient_time = n;
224    
225    RESTORE_STACK;
226    return ratio > 20;
227 }
228
229 /** Apply window and compute the MDCT for all sub-frames and all channels in a frame */
230 static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig_t * restrict in, celt_sig_t * restrict out)
231 {
232    const int C = CHANNELS(mode);
233    if (C==1 && !shortBlocks)
234    {
235       const mdct_lookup *lookup = MDCT(mode);
236       const int overlap = OVERLAP(mode);
237       mdct_forward(lookup, in, out, mode->window, overlap);
238    } else if (!shortBlocks) {
239       const mdct_lookup *lookup = MDCT(mode);
240       const int overlap = OVERLAP(mode);
241       const int N = FRAMESIZE(mode);
242       int c;
243       VARDECL(celt_word32_t, x);
244       VARDECL(celt_word32_t, tmp);
245       SAVE_STACK;
246       ALLOC(x, N+overlap, celt_word32_t);
247       ALLOC(tmp, N, celt_word32_t);
248       for (c=0;c<C;c++)
249       {
250          int j;
251          for (j=0;j<N+overlap;j++)
252             x[j] = in[C*j+c];
253          mdct_forward(lookup, x, tmp, mode->window, overlap);
254          /* Interleaving the sub-frames */
255          for (j=0;j<N;j++)
256             out[C*j+c] = tmp[j];
257       }
258       RESTORE_STACK;
259    } else {
260       const mdct_lookup *lookup = &mode->shortMdct;
261       const int overlap = mode->overlap;
262       const int N = mode->shortMdctSize;
263       int b, c;
264       VARDECL(celt_word32_t, x);
265       VARDECL(celt_word32_t, tmp);
266       SAVE_STACK;
267       ALLOC(x, N+overlap, celt_word32_t);
268       ALLOC(tmp, N, celt_word32_t);
269       for (c=0;c<C;c++)
270       {
271          int B = mode->nbShortMdcts;
272          for (b=0;b<B;b++)
273          {
274             int j;
275             for (j=0;j<N+overlap;j++)
276                x[j] = in[C*(b*N+j)+c];
277             mdct_forward(lookup, x, tmp, mode->window, overlap);
278             /* Interleaving the sub-frames */
279             for (j=0;j<N;j++)
280                out[C*(j*B+b)+c] = tmp[j];
281          }
282       }
283       RESTORE_STACK;
284    }
285 }
286
287 /** Compute the IMDCT and apply window for all sub-frames and all channels in a frame */
288 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)
289 {
290    int c, N4;
291    const int C = CHANNELS(mode);
292    const int N = FRAMESIZE(mode);
293    const int overlap = OVERLAP(mode);
294    N4 = (N-overlap)>>1;
295    for (c=0;c<C;c++)
296    {
297       int j;
298       if (transient_shift==0 && C==1 && !shortBlocks) {
299          const mdct_lookup *lookup = MDCT(mode);
300          mdct_backward(lookup, X, out_mem+C*(MAX_PERIOD-N-N4), mode->window, overlap);
301       } else if (!shortBlocks) {
302          const mdct_lookup *lookup = MDCT(mode);
303          VARDECL(celt_word32_t, x);
304          VARDECL(celt_word32_t, tmp);
305          SAVE_STACK;
306          ALLOC(x, 2*N, celt_word32_t);
307          ALLOC(tmp, N, celt_word32_t);
308          /* De-interleaving the sub-frames */
309          for (j=0;j<N;j++)
310             tmp[j] = X[C*j+c];
311          /* Prevents problems from the imdct doing the overlap-add */
312          CELT_MEMSET(x+N4, 0, N);
313          mdct_backward(lookup, tmp, x, mode->window, overlap);
314          celt_assert(transient_shift == 0);
315          /* The first and last part would need to be set to zero if we actually
316             wanted to use them. */
317          for (j=0;j<overlap;j++)
318             out_mem[C*(MAX_PERIOD-N)+C*j+c] += x[j+N4];
319          for (j=0;j<overlap;j++)
320             out_mem[C*(MAX_PERIOD)+C*(overlap-j-1)+c] = x[2*N-j-N4-1];
321          for (j=0;j<2*N4;j++)
322             out_mem[C*(MAX_PERIOD-N)+C*(j+overlap)+c] = x[j+N4+overlap];
323          RESTORE_STACK;
324       } else {
325          int b;
326          const int N2 = mode->shortMdctSize;
327          const int B = mode->nbShortMdcts;
328          const mdct_lookup *lookup = &mode->shortMdct;
329          VARDECL(celt_word32_t, x);
330          VARDECL(celt_word32_t, tmp);
331          SAVE_STACK;
332          ALLOC(x, 2*N, celt_word32_t);
333          ALLOC(tmp, N, celt_word32_t);
334          /* Prevents problems from the imdct doing the overlap-add */
335          CELT_MEMSET(x+N4, 0, N2);
336          for (b=0;b<B;b++)
337          {
338             /* De-interleaving the sub-frames */
339             for (j=0;j<N2;j++)
340                tmp[j] = X[C*(j*B+b)+c];
341             mdct_backward(lookup, tmp, x+N4+N2*b, mode->window, overlap);
342          }
343          if (transient_shift > 0)
344          {
345 #ifdef FIXED_POINT
346             for (j=0;j<16;j++)
347                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));
348             for (j=transient_time;j<N+overlap;j++)
349                x[N4+j] = SHL32(x[N4+j], transient_shift);
350 #else
351             for (j=0;j<16;j++)
352                x[N4+transient_time+j-16] *= 1+transientWindow[j]*((1<<transient_shift)-1);
353             for (j=transient_time;j<N+overlap;j++)
354                x[N4+j] *= 1<<transient_shift;
355 #endif
356          }
357          /* The first and last part would need to be set to zero if we actually
358          wanted to use them. */
359          for (j=0;j<overlap;j++)
360             out_mem[C*(MAX_PERIOD-N)+C*j+c] += x[j+N4];
361          for (j=0;j<overlap;j++)
362             out_mem[C*(MAX_PERIOD)+C*(overlap-j-1)+c] = x[2*N-j-N4-1];
363          for (j=0;j<2*N4;j++)
364             out_mem[C*(MAX_PERIOD-N)+C*(j+overlap)+c] = x[j+N4+overlap];
365          RESTORE_STACK;
366       }
367    }
368 }
369
370 #define FLAG_NONE        0
371 #define FLAG_INTRA       1U<<16
372 #define FLAG_PITCH       1U<<15
373 #define FLAG_SHORT       1U<<14
374 #define FLAG_FOLD        1U<<13
375 #define FLAG_MASK        (FLAG_INTRA|FLAG_PITCH|FLAG_SHORT|FLAG_FOLD)
376
377 celt_int32_t flaglist[8] = {
378       0 /*00  */ | FLAG_FOLD,
379       1 /*01  */ | FLAG_PITCH|FLAG_FOLD,
380       8 /*1000*/ | FLAG_NONE,
381       9 /*1001*/ | FLAG_SHORT|FLAG_FOLD,
382      10 /*1010*/ | FLAG_PITCH,
383      11 /*1011*/ | FLAG_INTRA,
384       6 /*110 */ | FLAG_INTRA|FLAG_FOLD,
385       7 /*111 */ | FLAG_INTRA|FLAG_SHORT|FLAG_FOLD
386 };
387
388 void encode_flags(ec_enc *enc, int intra_ener, int has_pitch, int shortBlocks, int has_fold)
389 {
390    int i;
391    int flags=FLAG_NONE;
392    int flag_bits;
393    flags |= intra_ener   ? FLAG_INTRA : 0;
394    flags |= has_pitch    ? FLAG_PITCH : 0;
395    flags |= shortBlocks  ? FLAG_SHORT : 0;
396    flags |= has_fold     ? FLAG_FOLD  : 0;
397    for (i=0;i<8;i++)
398       if (flags == (flaglist[i]&FLAG_MASK))
399          break;
400    celt_assert(i<8);
401    flag_bits = flaglist[i]&0xf;
402    /*printf ("enc %d: %d %d %d %d\n", flag_bits, intra_ener, has_pitch, shortBlocks, has_fold);*/
403    if (i<2)
404       ec_enc_bits(enc, flag_bits, 2);
405    else if (i<6)
406       ec_enc_bits(enc, flag_bits, 4);
407    else
408       ec_enc_bits(enc, flag_bits, 3);
409 }
410
411 void decode_flags(ec_dec *dec, int *intra_ener, int *has_pitch, int *shortBlocks, int *has_fold)
412 {
413    int i;
414    int flag_bits;
415    flag_bits = ec_dec_bits(dec, 2);
416    /*printf ("(%d) ", flag_bits);*/
417    if (flag_bits==2)
418       flag_bits = (flag_bits<<2) | ec_dec_bits(dec, 2);
419    else if (flag_bits==3)
420       flag_bits = (flag_bits<<1) | ec_dec_bits(dec, 1);
421    for (i=0;i<8;i++)
422       if (flag_bits == (flaglist[i]&0xf))
423          break;
424    celt_assert(i<8);
425    *intra_ener  = (flaglist[i]&FLAG_INTRA) != 0;
426    *has_pitch   = (flaglist[i]&FLAG_PITCH) != 0;
427    *shortBlocks = (flaglist[i]&FLAG_SHORT) != 0;
428    *has_fold    = (flaglist[i]&FLAG_FOLD ) != 0;
429    /*printf ("dec %d: %d %d %d %d\n", flag_bits, *intra_ener, *has_pitch, *shortBlocks, *has_fold);*/
430 }
431
432 #ifdef FIXED_POINT
433 int celt_encode(CELTEncoder * restrict st, const celt_int16_t * pcm, celt_int16_t * optional_synthesis, unsigned char *compressed, int nbCompressedBytes)
434 {
435 #else
436 int celt_encode_float(CELTEncoder * restrict st, const celt_sig_t * pcm, celt_sig_t * optional_synthesis, unsigned char *compressed, int nbCompressedBytes)
437 {
438 #endif
439    int i, c, N, N4;
440    int has_pitch;
441    int pitch_index;
442    int bits;
443    int has_fold=1;
444    unsigned coarse_needed;
445    ec_byte_buffer buf;
446    ec_enc         enc;
447    VARDECL(celt_sig_t, in);
448    VARDECL(celt_sig_t, freq);
449    VARDECL(celt_norm_t, X);
450    VARDECL(celt_norm_t, P);
451    VARDECL(celt_ener_t, bandE);
452    VARDECL(celt_pgain_t, gains);
453    VARDECL(int, stereo_mode);
454    VARDECL(int, fine_quant);
455    VARDECL(celt_word16_t, error);
456    VARDECL(int, pulses);
457    VARDECL(int, offsets);
458 #ifdef EXP_PSY
459    VARDECL(celt_word32_t, mask);
460    VARDECL(celt_word32_t, tonality);
461    VARDECL(celt_word32_t, bandM);
462    VARDECL(celt_ener_t, bandN);
463 #endif
464    int intra_ener = 0;
465    int shortBlocks=0;
466    int transient_time;
467    int transient_shift;
468    const int C = CHANNELS(st->mode);
469    SAVE_STACK;
470
471    if (check_mode(st->mode) != CELT_OK)
472       return CELT_INVALID_MODE;
473
474    if (nbCompressedBytes<0)
475      return CELT_BAD_ARG; 
476
477    /* The memset is important for now in case the encoder doesn't fill up all the bytes */
478    CELT_MEMSET(compressed, 0, nbCompressedBytes);
479    ec_byte_writeinit_buffer(&buf, compressed, nbCompressedBytes);
480    ec_enc_init(&enc,&buf);
481
482    N = st->block_size;
483    N4 = (N-st->overlap)>>1;
484    ALLOC(in, 2*C*N-2*C*N4, celt_sig_t);
485
486    CELT_COPY(in, st->in_mem, C*st->overlap);
487    for (c=0;c<C;c++)
488    {
489       const celt_word16_t * restrict pcmp = pcm+c;
490       celt_sig_t * restrict inp = in+C*st->overlap+c;
491       for (i=0;i<N;i++)
492       {
493          /* Apply pre-emphasis */
494          celt_sig_t tmp = SCALEIN(SHL32(EXTEND32(*pcmp), SIG_SHIFT));
495          *inp = SUB32(tmp, SHR32(MULT16_16(preemph,st->preemph_memE[c]),3));
496          st->preemph_memE[c] = SCALEIN(*pcmp);
497          inp += C;
498          pcmp += C;
499       }
500    }
501    CELT_COPY(st->in_mem, in+C*(2*N-2*N4-st->overlap), C*st->overlap);
502    
503    /* Transient handling */
504    if (st->mode->nbShortMdcts > 1)
505    {
506       if (transient_analysis(in, N+st->overlap, C, &transient_time, &transient_shift))
507       {
508 #ifndef FIXED_POINT
509          float gain_1;
510 #endif
511          /* Apply the inverse shaping window */
512          if (transient_shift)
513          {
514 #ifdef FIXED_POINT
515             for (c=0;c<C;c++)
516                for (i=0;i<16;i++)
517                   in[C*(transient_time+i-16)+c] = MULT16_32_Q15(EXTRACT16(SHR32(celt_rcp(Q15ONE+MULT16_16(transientWindow[i],((1<<transient_shift)-1))),1)), in[C*(transient_time+i-16)+c]);
518             for (c=0;c<C;c++)
519                for (i=transient_time;i<N+st->overlap;i++)
520                   in[C*i+c] = SHR32(in[C*i+c], transient_shift);
521 #else
522             for (c=0;c<C;c++)
523                for (i=0;i<16;i++)
524                   in[C*(transient_time+i-16)+c] /= 1+transientWindow[i]*((1<<transient_shift)-1);
525             gain_1 = 1./(1<<transient_shift);
526             for (c=0;c<C;c++)
527                for (i=transient_time;i<N+st->overlap;i++)
528                   in[C*i+c] *= gain_1;
529 #endif
530          }
531          shortBlocks = 1;
532       } else {
533          transient_time = -1;
534          transient_shift = 0;
535          shortBlocks = 0;
536       }
537    } else {
538       transient_time = -1;
539       transient_shift = 0;
540       shortBlocks = 0;
541    }
542
543    ALLOC(freq, C*N, celt_sig_t); /**< Interleaved signal MDCTs */
544    ALLOC(bandE,st->mode->nbEBands*C, celt_ener_t);
545    /* Compute MDCTs */
546    compute_mdcts(st->mode, shortBlocks, in, freq);
547    compute_band_energies(st->mode, freq, bandE);
548
549    intra_ener = st->delayedIntra;
550    if (intra_decision(bandE, st->oldBandE, st->mode->nbEBands) || shortBlocks)
551       st->delayedIntra = 1;
552    else
553       st->delayedIntra = 0;
554    /* Pitch analysis: we do it early to save on the peak stack space */
555    /* Don't use pitch if there isn't enough data available yet, or if we're using shortBlocks */
556    has_pitch = st->pitch_enabled && (st->pitch_available >= MAX_PERIOD) && (!shortBlocks) && !intra_ener;
557 #ifdef EXP_PSY
558    ALLOC(tonality, MAX_PERIOD/4, celt_word16_t);
559    {
560       VARDECL(celt_word16_t, X);
561       ALLOC(X, MAX_PERIOD/2, celt_word16_t);
562       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);
563       compute_tonality(st->mode, X, st->psy_mem, MAX_PERIOD, tonality, MAX_PERIOD/4);
564    }
565 #else
566    if (has_pitch)
567    {
568       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);
569    }
570 #endif
571
572 #ifdef EXP_PSY
573    ALLOC(mask, N, celt_sig_t);
574    compute_mdct_masking(&st->psy, freq, tonality, st->psy_mem, mask, C*N);
575    /*for (i=0;i<256;i++)
576       printf ("%f %f %f ", freq[i], tonality[i], mask[i]);
577    printf ("\n");*/
578 #endif
579
580    /* Deferred allocation after find_spectral_pitch() to reduce the peak memory usage */
581    ALLOC(X, C*N, celt_norm_t);         /**< Interleaved normalised MDCTs */
582    ALLOC(P, C*N, celt_norm_t);         /**< Interleaved normalised pitch MDCTs*/
583    ALLOC(gains,st->mode->nbPBands, celt_pgain_t);
584
585
586    /* Band normalisation */
587    normalise_bands(st->mode, freq, X, bandE);
588
589 #ifdef EXP_PSY
590    ALLOC(bandN,C*st->mode->nbEBands, celt_ener_t);
591    ALLOC(bandM,st->mode->nbEBands, celt_ener_t);
592    compute_noise_energies(st->mode, freq, tonality, bandN);
593
594    /*for (i=0;i<st->mode->nbEBands;i++)
595       printf ("%f ", (.1+bandN[i])/(.1+bandE[i]));
596    printf ("\n");*/
597    has_fold = 0;
598    for (i=st->mode->nbPBands;i<st->mode->nbEBands;i++)
599       if (bandN[i] < .4*bandE[i])
600          has_fold++;
601    /*printf ("%d\n", has_fold);*/
602    if (has_fold>=2)
603       has_fold = 0;
604    else
605       has_fold = 1;
606    for (i=0;i<N;i++)
607       mask[i] = sqrt(mask[i]);
608    compute_band_energies(st->mode, mask, bandM);
609    /*for (i=0;i<st->mode->nbEBands;i++)
610       printf ("%f %f ", bandE[i], bandM[i]);
611    printf ("\n");*/
612 #endif
613
614    /* Compute MDCTs of the pitch part */
615    if (has_pitch)
616    {
617       celt_word32_t curr_power, pitch_power=0;
618       /* Normalise the pitch vector as well (discard the energies) */
619       VARDECL(celt_ener_t, bandEp);
620       
621       compute_mdcts(st->mode, 0, st->out_mem+pitch_index*C, freq);
622       ALLOC(bandEp, st->mode->nbEBands*st->mode->nbChannels, celt_ener_t);
623       compute_band_energies(st->mode, freq, bandEp);
624       normalise_bands(st->mode, freq, P, bandEp);
625       pitch_power = bandEp[0]+bandEp[1]+bandEp[2];
626       /* Check if we can safely use the pitch (i.e. effective gain isn't too high) */
627       curr_power = bandE[0]+bandE[1]+bandE[2];
628       if ((MULT16_32_Q15(QCONST16(.1f, 15),curr_power) + QCONST32(10.f,ENER_SHIFT) < pitch_power))
629       {
630          /* Pitch prediction */
631          has_pitch = compute_pitch_gain(st->mode, X, P, gains);
632       } else {
633          has_pitch = 0;
634       }
635    }
636    
637    encode_flags(&enc, intra_ener, has_pitch, shortBlocks, has_fold);
638    if (has_pitch)
639    {
640       ec_enc_uint(&enc, pitch_index, MAX_PERIOD-(2*N-2*N4));
641    } else {
642       for (i=0;i<st->mode->nbPBands;i++)
643          gains[i] = 0;
644       for (i=0;i<C*N;i++)
645          P[i] = 0;
646    }
647    if (shortBlocks)
648    {
649       ec_enc_bits(&enc, transient_shift, 2);
650       if (transient_shift)
651          ec_enc_uint(&enc, transient_time, N+st->overlap);
652    }
653
654 #ifdef STDIN_TUNING2
655    static int fine_quant[30];
656    static int pulses[30];
657    static int init=0;
658    if (!init)
659    {
660       for (i=0;i<st->mode->nbEBands;i++)
661          scanf("%d ", &fine_quant[i]);
662       for (i=0;i<st->mode->nbEBands;i++)
663          scanf("%d ", &pulses[i]);
664       init = 1;
665    }
666 #else
667    ALLOC(fine_quant, st->mode->nbEBands, int);
668    ALLOC(pulses, st->mode->nbEBands, int);
669 #endif
670
671    /* Bit allocation */
672    ALLOC(error, C*st->mode->nbEBands, celt_word16_t);
673    coarse_needed = quant_coarse_energy(st->mode, bandE, st->oldBandE, nbCompressedBytes*8/3, intra_ener, st->mode->prob, error, &enc);
674    coarse_needed = ((coarse_needed*3-1)>>3)+1;
675
676    /* Variable bitrate */
677    if (st->VBR_rate>0)
678    {
679      /* The target rate in 16th bits per frame */
680      int target=st->VBR_rate;
681    
682      /* Shortblocks get a large boost in bitrate, but since they are uncommon long blocks are not greatly effected */
683      if (shortBlocks)
684        target*=2;
685      else if (st->mode->nbShortMdcts > 1)
686        target-=(target+14)/28;     
687
688      /*The average energy is removed from the target and the actual energy added*/
689      target=target-588+ec_enc_tell(&enc, 4);
690
691      /* In VBR mode the frame size must not be reduced so much that it would result in the coarse energy busting its budget */
692      target=IMAX(coarse_needed,(target+64)/128);
693      nbCompressedBytes=IMIN(nbCompressedBytes,target);
694    }
695
696    ALLOC(offsets, st->mode->nbEBands, int);
697    ALLOC(stereo_mode, st->mode->nbEBands, int);
698    stereo_decision(st->mode, X, stereo_mode, st->mode->nbEBands);
699
700    for (i=0;i<st->mode->nbEBands;i++)
701       offsets[i] = 0;
702    bits = nbCompressedBytes*8 - ec_enc_tell(&enc, 0) - 1;
703    if (has_pitch)
704       bits -= st->mode->nbPBands;
705 #ifndef STDIN_TUNING
706    compute_allocation(st->mode, offsets, stereo_mode, bits, pulses, fine_quant);
707 #endif
708
709    quant_fine_energy(st->mode, bandE, st->oldBandE, error, fine_quant, &enc);
710
711    /* Residual quantisation */
712    if (C==1)
713       quant_bands(st->mode, X, P, NULL, has_pitch, gains, bandE, pulses, shortBlocks, has_fold, nbCompressedBytes*8, &enc);
714    else
715       quant_bands_stereo(st->mode, X, P, NULL, has_pitch, gains, bandE, pulses, shortBlocks, has_fold, nbCompressedBytes*8, &enc);
716
717    /* Re-synthesis of the coded audio if required */
718    if (st->pitch_available>0 || optional_synthesis!=NULL)
719    {
720       if (st->pitch_available>0 && st->pitch_available<MAX_PERIOD)
721         st->pitch_available+=st->frame_size;
722
723       /* Synthesis */
724       denormalise_bands(st->mode, X, freq, bandE);
725       
726       
727       CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD+st->overlap-N));
728       
729       compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem);
730       /* De-emphasis and put everything back at the right place in the synthesis history */
731       if (optional_synthesis != NULL) {
732          for (c=0;c<C;c++)
733          {
734             int j;
735             for (j=0;j<N;j++)
736             {
737                celt_sig_t tmp = MAC16_32_Q15(st->out_mem[C*(MAX_PERIOD-N)+C*j+c],
738                                    preemph,st->preemph_memD[c]);
739                st->preemph_memD[c] = tmp;
740                optional_synthesis[C*j+c] = SCALEOUT(SIG2WORD16(tmp));
741             }
742          }
743       }
744    }
745
746    /*fprintf (stderr, "remaining bits after encode = %d\n", nbCompressedBytes*8-ec_enc_tell(&enc, 0));*/
747    /*if (ec_enc_tell(&enc, 0) < nbCompressedBytes*8 - 7)
748       celt_warning_int ("many unused bits: ", nbCompressedBytes*8-ec_enc_tell(&enc, 0));*/
749
750    /* Finishing the stream with a 0101... pattern so that the decoder can check is everything's right */
751    {
752       int val = 0;
753       while (ec_enc_tell(&enc, 0) < nbCompressedBytes*8)
754       {
755          ec_enc_uint(&enc, val, 2);
756          val = 1-val;
757       }
758    }
759    ec_enc_done(&enc);
760    {
761       /*unsigned char *data;*/
762       int nbBytes = ec_byte_bytes(&buf);
763       if (nbBytes > nbCompressedBytes)
764       {
765          celt_warning_int ("got too many bytes:", nbBytes);
766          RESTORE_STACK;
767          return CELT_INTERNAL_ERROR;
768       }
769    }
770
771    RESTORE_STACK;
772    return nbCompressedBytes;
773 }
774
775 #ifdef FIXED_POINT
776 #ifndef DISABLE_FLOAT_API
777 int celt_encode_float(CELTEncoder * restrict st, const float * pcm, float * optional_synthesis, unsigned char *compressed, int nbCompressedBytes)
778 {
779    int j, ret;
780    const int C = CHANNELS(st->mode);
781    const int N = st->block_size;
782    VARDECL(celt_int16_t, in);
783    SAVE_STACK;
784    ALLOC(in, C*N, celt_int16_t);
785
786    for (j=0;j<C*N;j++)
787      in[j] = FLOAT2INT16(pcm[j]);
788
789    if (optional_synthesis != NULL) {
790      ret=celt_encode(st,in,in,compressed,nbCompressedBytes);
791       for (j=0;j<C*N;j++)
792          optional_synthesis[j]=in[j]*(1/32768.);
793    } else {
794      ret=celt_encode(st,in,NULL,compressed,nbCompressedBytes);
795    }
796    RESTORE_STACK;
797    return ret;
798
799 }
800 #endif /*DISABLE_FLOAT_API*/
801 #else
802 int celt_encode(CELTEncoder * restrict st, const celt_int16_t * pcm, celt_int16_t * optional_synthesis, unsigned char *compressed, int nbCompressedBytes)
803 {
804    int j, ret;
805    VARDECL(celt_sig_t, in);
806    const int C = CHANNELS(st->mode);
807    const int N = st->block_size;
808    SAVE_STACK;
809    ALLOC(in, C*N, celt_sig_t);
810    for (j=0;j<C*N;j++) {
811      in[j] = SCALEOUT(pcm[j]);
812    }
813
814    if (optional_synthesis != NULL) {
815       ret = celt_encode_float(st,in,in,compressed,nbCompressedBytes);
816       for (j=0;j<C*N;j++)
817          optional_synthesis[j] = FLOAT2INT16(in[j]);
818    } else {
819       ret = celt_encode_float(st,in,NULL,compressed,nbCompressedBytes);
820    }
821    RESTORE_STACK;
822    return ret;
823 }
824 #endif
825
826 int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...)
827 {
828    va_list ap;
829    va_start(ap, request);
830    switch (request)
831    {
832       case CELT_SET_COMPLEXITY_REQUEST:
833       {
834          int value = va_arg(ap, celt_int32_t);
835          if (value<0 || value>10)
836             goto bad_arg;
837          if (value<=2) {
838             st->pitch_enabled = 0; 
839             st->pitch_available = 0;
840          } else {
841               st->pitch_enabled = 1;
842               if (st->pitch_available<1)
843                 st->pitch_available = 1;
844          }   
845       }
846       break;
847       case CELT_SET_LTP_REQUEST:
848       {
849          int value = va_arg(ap, celt_int32_t);
850          if (value<0 || value>1 || (value==1 && st->pitch_available==0))
851             goto bad_arg;
852          if (value==0)
853             st->pitch_enabled = 0;
854          else
855             st->pitch_enabled = 1;
856       }
857       break;
858       case CELT_SET_VBR_RATE_REQUEST:
859       {
860          int value = va_arg(ap, celt_int32_t);
861          if (value<0)
862             goto bad_arg;
863          if (value>3072000)
864             value = 3072000;
865          st->VBR_rate = ((st->mode->Fs<<3)+(st->block_size>>1))/st->block_size;
866          st->VBR_rate = ((value<<7)+(st->VBR_rate>>1))/st->VBR_rate;
867       }
868       break;
869       default:
870          goto bad_request;
871    }
872    va_end(ap);
873    return CELT_OK;
874 bad_arg:
875    va_end(ap);
876    return CELT_BAD_ARG;
877 bad_request:
878    va_end(ap);
879    return CELT_UNIMPLEMENTED;
880 }
881
882 /****************************************************************************/
883 /*                                                                          */
884 /*                                DECODER                                   */
885 /*                                                                          */
886 /****************************************************************************/
887 #ifdef NEW_PLC
888 #define DECODE_BUFFER_SIZE 2048
889 #else
890 #define DECODE_BUFFER_SIZE MAX_PERIOD
891 #endif
892
893 /** Decoder state 
894  @brief Decoder state
895  */
896 struct CELTDecoder {
897    const CELTMode *mode;
898    int frame_size;
899    int block_size;
900    int overlap;
901
902    ec_byte_buffer buf;
903    ec_enc         enc;
904
905    celt_sig_t * restrict preemph_memD;
906
907    celt_sig_t *out_mem;
908    celt_sig_t *decode_mem;
909
910    celt_word16_t *oldBandE;
911    
912    int last_pitch_index;
913 };
914
915 CELTDecoder *celt_decoder_create(const CELTMode *mode)
916 {
917    int N, C;
918    CELTDecoder *st;
919
920    if (check_mode(mode) != CELT_OK)
921       return NULL;
922
923    N = mode->mdctSize;
924    C = CHANNELS(mode);
925    st = celt_alloc(sizeof(CELTDecoder));
926    
927    st->mode = mode;
928    st->frame_size = N;
929    st->block_size = N;
930    st->overlap = mode->overlap;
931
932    st->decode_mem = celt_alloc((DECODE_BUFFER_SIZE+st->overlap)*C*sizeof(celt_sig_t));
933    st->out_mem = st->decode_mem+DECODE_BUFFER_SIZE-MAX_PERIOD;
934    
935    st->oldBandE = (celt_word16_t*)celt_alloc(C*mode->nbEBands*sizeof(celt_word16_t));
936
937    st->preemph_memD = (celt_sig_t*)celt_alloc(C*sizeof(celt_sig_t));
938
939    st->last_pitch_index = 0;
940    return st;
941 }
942
943 void celt_decoder_destroy(CELTDecoder *st)
944 {
945    if (st == NULL)
946    {
947       celt_warning("NULL passed to celt_encoder_destroy");
948       return;
949    }
950    if (check_mode(st->mode) != CELT_OK)
951       return;
952
953
954    celt_free(st->decode_mem);
955    
956    celt_free(st->oldBandE);
957    
958    celt_free(st->preemph_memD);
959
960    celt_free(st);
961 }
962
963 /** Handles lost packets by just copying past data with the same offset as the last
964     pitch period */
965 #ifdef NEW_PLC
966 #include "plc.c"
967 #else
968 static void celt_decode_lost(CELTDecoder * restrict st, celt_word16_t * restrict pcm)
969 {
970    int c, N;
971    int pitch_index;
972    int i, len;
973    VARDECL(celt_sig_t, freq);
974    const int C = CHANNELS(st->mode);
975    int offset;
976    SAVE_STACK;
977    N = st->block_size;
978    ALLOC(freq,C*N, celt_sig_t);         /**< Interleaved signal MDCTs */
979    
980    len = N+st->mode->overlap;
981 #if 0
982    pitch_index = st->last_pitch_index;
983    
984    /* Use the pitch MDCT as the "guessed" signal */
985    compute_mdcts(st->mode, st->mode->window, st->out_mem+pitch_index*C, freq);
986
987 #else
988    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);
989    pitch_index = MAX_PERIOD-len-pitch_index;
990    offset = MAX_PERIOD-pitch_index;
991    while (offset+len >= MAX_PERIOD)
992       offset -= pitch_index;
993    compute_mdcts(st->mode, 0, st->out_mem+offset*C, freq);
994    for (i=0;i<N;i++)
995       freq[i] = ADD32(EPSILON, MULT16_32_Q15(QCONST16(.9f,15),freq[i]));
996 #endif
997    
998    
999    
1000    CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD+st->mode->overlap-N));
1001    /* Compute inverse MDCTs */
1002    compute_inv_mdcts(st->mode, 0, freq, -1, 0, st->out_mem);
1003
1004    for (c=0;c<C;c++)
1005    {
1006       int j;
1007       for (j=0;j<N;j++)
1008       {
1009          celt_sig_t tmp = MAC16_32_Q15(st->out_mem[C*(MAX_PERIOD-N)+C*j+c],
1010                                 preemph,st->preemph_memD[c]);
1011          st->preemph_memD[c] = tmp;
1012          pcm[C*j+c] = SCALEOUT(SIG2WORD16(tmp));
1013       }
1014    }
1015    RESTORE_STACK;
1016 }
1017 #endif
1018
1019 #ifdef FIXED_POINT
1020 int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, celt_int16_t * restrict pcm)
1021 {
1022 #else
1023 int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, celt_sig_t * restrict pcm)
1024 {
1025 #endif
1026    int i, c, N, N4;
1027    int has_pitch, has_fold;
1028    int pitch_index;
1029    int bits;
1030    ec_dec dec;
1031    ec_byte_buffer buf;
1032    VARDECL(celt_sig_t, freq);
1033    VARDECL(celt_norm_t, X);
1034    VARDECL(celt_norm_t, P);
1035    VARDECL(celt_ener_t, bandE);
1036    VARDECL(celt_pgain_t, gains);
1037    VARDECL(int, stereo_mode);
1038    VARDECL(int, fine_quant);
1039    VARDECL(int, pulses);
1040    VARDECL(int, offsets);
1041
1042    int shortBlocks;
1043    int intra_ener;
1044    int transient_time;
1045    int transient_shift;
1046    const int C = CHANNELS(st->mode);
1047    SAVE_STACK;
1048
1049    if (check_mode(st->mode) != CELT_OK)
1050       return CELT_INVALID_MODE;
1051
1052    N = st->block_size;
1053    N4 = (N-st->overlap)>>1;
1054
1055    ALLOC(freq, C*N, celt_sig_t); /**< Interleaved signal MDCTs */
1056    ALLOC(X, C*N, celt_norm_t);         /**< Interleaved normalised MDCTs */
1057    ALLOC(P, C*N, celt_norm_t);         /**< Interleaved normalised pitch MDCTs*/
1058    ALLOC(bandE, st->mode->nbEBands*C, celt_ener_t);
1059    ALLOC(gains, st->mode->nbPBands, celt_pgain_t);
1060    
1061    if (check_mode(st->mode) != CELT_OK)
1062    {
1063       RESTORE_STACK;
1064       return CELT_INVALID_MODE;
1065    }
1066    if (data == NULL)
1067    {
1068       celt_decode_lost(st, pcm);
1069       RESTORE_STACK;
1070       return 0;
1071    }
1072    if (len<0) {
1073      RESTORE_STACK;
1074      return CELT_BAD_ARG;
1075    }
1076    
1077    ec_byte_readinit(&buf,(unsigned char*)data,len);
1078    ec_dec_init(&dec,&buf);
1079    
1080    decode_flags(&dec, &intra_ener, &has_pitch, &shortBlocks, &has_fold);
1081    if (shortBlocks)
1082    {
1083       transient_shift = ec_dec_bits(&dec, 2);
1084       if (transient_shift)
1085          transient_time = ec_dec_uint(&dec, N+st->mode->overlap);
1086       else
1087          transient_time = 0;
1088    } else {
1089       transient_time = -1;
1090       transient_shift = 0;
1091    }
1092    
1093    if (has_pitch)
1094    {
1095       pitch_index = ec_dec_uint(&dec, MAX_PERIOD-(2*N-2*N4));
1096       st->last_pitch_index = pitch_index;
1097    } else {
1098       pitch_index = 0;
1099       for (i=0;i<st->mode->nbPBands;i++)
1100          gains[i] = 0;
1101    }
1102
1103    ALLOC(fine_quant, st->mode->nbEBands, int);
1104    /* Get band energies */
1105    unquant_coarse_energy(st->mode, bandE, st->oldBandE, len*8/3, intra_ener, st->mode->prob, &dec);
1106    
1107    ALLOC(pulses, st->mode->nbEBands, int);
1108    ALLOC(offsets, st->mode->nbEBands, int);
1109    ALLOC(stereo_mode, st->mode->nbEBands, int);
1110    stereo_decision(st->mode, X, stereo_mode, st->mode->nbEBands);
1111
1112    for (i=0;i<st->mode->nbEBands;i++)
1113       offsets[i] = 0;
1114
1115    bits = len*8 - ec_dec_tell(&dec, 0) - 1;
1116    if (has_pitch)
1117       bits -= st->mode->nbPBands;
1118    compute_allocation(st->mode, offsets, stereo_mode, bits, pulses, fine_quant);
1119    /*bits = ec_dec_tell(&dec, 0);
1120    compute_fine_allocation(st->mode, fine_quant, (20*C+len*8/5-(ec_dec_tell(&dec, 0)-bits))/C);*/
1121    
1122    unquant_fine_energy(st->mode, bandE, st->oldBandE, fine_quant, &dec);
1123
1124
1125    if (has_pitch) 
1126    {
1127       VARDECL(celt_ener_t, bandEp);
1128       
1129       /* Pitch MDCT */
1130       compute_mdcts(st->mode, 0, st->out_mem+pitch_index*C, freq);
1131       ALLOC(bandEp, st->mode->nbEBands*C, celt_ener_t);
1132       compute_band_energies(st->mode, freq, bandEp);
1133       normalise_bands(st->mode, freq, P, bandEp);
1134       /* Apply pitch gains */
1135    } else {
1136       for (i=0;i<C*N;i++)
1137          P[i] = 0;
1138    }
1139
1140    /* Decode fixed codebook and merge with pitch */
1141    if (C==1)
1142       unquant_bands(st->mode, X, P, has_pitch, gains, bandE, pulses, shortBlocks, has_fold, len*8, &dec);
1143    else
1144       unquant_bands_stereo(st->mode, X, P, has_pitch, gains, bandE, pulses, shortBlocks, has_fold, len*8, &dec);
1145
1146    /* Synthesis */
1147    denormalise_bands(st->mode, X, freq, bandE);
1148
1149
1150    CELT_MOVE(st->decode_mem, st->decode_mem+C*N, C*(DECODE_BUFFER_SIZE+st->overlap-N));
1151    /* Compute inverse MDCTs */
1152    compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem);
1153
1154    for (c=0;c<C;c++)
1155    {
1156       int j;
1157       for (j=0;j<N;j++)
1158       {
1159          celt_sig_t tmp = MAC16_32_Q15(st->out_mem[C*(MAX_PERIOD-N)+C*j+c],
1160                                 preemph,st->preemph_memD[c]);
1161          st->preemph_memD[c] = tmp;
1162          pcm[C*j+c] = SCALEOUT(SIG2WORD16(tmp));
1163       }
1164    }
1165
1166    {
1167       unsigned int val = 0;
1168       while (ec_dec_tell(&dec, 0) < len*8)
1169       {
1170          if (ec_dec_uint(&dec, 2) != val)
1171          {
1172             celt_warning("decode error");
1173             RESTORE_STACK;
1174             return CELT_CORRUPTED_DATA;
1175          }
1176          val = 1-val;
1177       }
1178    }
1179
1180    RESTORE_STACK;
1181    return 0;
1182    /*printf ("\n");*/
1183 }
1184
1185 #ifdef FIXED_POINT
1186 #ifndef DISABLE_FLOAT_API
1187 int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm)
1188 {
1189    int j, ret;
1190    const int C = CHANNELS(st->mode);
1191    const int N = st->block_size;
1192    VARDECL(celt_int16_t, out);
1193    SAVE_STACK;
1194    ALLOC(out, C*N, celt_int16_t);
1195
1196    ret=celt_decode(st, data, len, out);
1197
1198    for (j=0;j<C*N;j++)
1199      pcm[j]=out[j]*(1/32768.);
1200    RESTORE_STACK;
1201    return ret;
1202 }
1203 #endif /*DISABLE_FLOAT_API*/
1204 #else
1205 int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, celt_int16_t * restrict pcm)
1206 {
1207    int j, ret;
1208    VARDECL(celt_sig_t, out);
1209    const int C = CHANNELS(st->mode);
1210    const int N = st->block_size;
1211    SAVE_STACK;
1212    ALLOC(out, C*N, celt_sig_t);
1213
1214    ret=celt_decode_float(st, data, len, out);
1215
1216    for (j=0;j<C*N;j++)
1217      pcm[j] = FLOAT2INT16 (out[j]);
1218
1219    RESTORE_STACK;
1220    return ret;
1221 }
1222 #endif