This code does a very naive reset of the state. It is possible (even likely)
[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 = SCALEIN(x);
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       case CELT_RESET_STATE:
870       {
871          const CELTMode *mode = st->mode;
872          int C = mode->nbChannels;
873
874          if (st->pitch_available > 0) st->pitch_available = 1;
875
876          CELT_MEMSET(st->in_mem, 0, st->overlap*C);
877          CELT_MEMSET(st->out_mem, 0, (MAX_PERIOD+st->overlap)*C);
878
879          CELT_MEMSET(st->oldBandE, 0, C*mode->nbEBands);
880
881          CELT_MEMSET(st->preemph_memE, 0, C);
882          CELT_MEMSET(st->preemph_memD, 0, C);
883          st->delayedIntra = 1;
884       }
885       break;
886       default:
887          goto bad_request;
888    }
889    va_end(ap);
890    return CELT_OK;
891 bad_arg:
892    va_end(ap);
893    return CELT_BAD_ARG;
894 bad_request:
895    va_end(ap);
896    return CELT_UNIMPLEMENTED;
897 }
898
899 /****************************************************************************/
900 /*                                                                          */
901 /*                                DECODER                                   */
902 /*                                                                          */
903 /****************************************************************************/
904 #ifdef NEW_PLC
905 #define DECODE_BUFFER_SIZE 2048
906 #else
907 #define DECODE_BUFFER_SIZE MAX_PERIOD
908 #endif
909
910 /** Decoder state 
911  @brief Decoder state
912  */
913 struct CELTDecoder {
914    const CELTMode *mode;
915    int frame_size;
916    int block_size;
917    int overlap;
918
919    ec_byte_buffer buf;
920    ec_enc         enc;
921
922    celt_sig_t * restrict preemph_memD;
923
924    celt_sig_t *out_mem;
925    celt_sig_t *decode_mem;
926
927    celt_word16_t *oldBandE;
928    
929    int last_pitch_index;
930 };
931
932 CELTDecoder *celt_decoder_create(const CELTMode *mode)
933 {
934    int N, C;
935    CELTDecoder *st;
936
937    if (check_mode(mode) != CELT_OK)
938       return NULL;
939
940    N = mode->mdctSize;
941    C = CHANNELS(mode);
942    st = celt_alloc(sizeof(CELTDecoder));
943    
944    st->mode = mode;
945    st->frame_size = N;
946    st->block_size = N;
947    st->overlap = mode->overlap;
948
949    st->decode_mem = celt_alloc((DECODE_BUFFER_SIZE+st->overlap)*C*sizeof(celt_sig_t));
950    st->out_mem = st->decode_mem+DECODE_BUFFER_SIZE-MAX_PERIOD;
951    
952    st->oldBandE = (celt_word16_t*)celt_alloc(C*mode->nbEBands*sizeof(celt_word16_t));
953
954    st->preemph_memD = (celt_sig_t*)celt_alloc(C*sizeof(celt_sig_t));
955
956    st->last_pitch_index = 0;
957    return st;
958 }
959
960 void celt_decoder_destroy(CELTDecoder *st)
961 {
962    if (st == NULL)
963    {
964       celt_warning("NULL passed to celt_encoder_destroy");
965       return;
966    }
967    if (check_mode(st->mode) != CELT_OK)
968       return;
969
970
971    celt_free(st->decode_mem);
972    
973    celt_free(st->oldBandE);
974    
975    celt_free(st->preemph_memD);
976
977    celt_free(st);
978 }
979
980 /** Handles lost packets by just copying past data with the same offset as the last
981     pitch period */
982 #ifdef NEW_PLC
983 #include "plc.c"
984 #else
985 static void celt_decode_lost(CELTDecoder * restrict st, celt_word16_t * restrict pcm)
986 {
987    int c, N;
988    int pitch_index;
989    int i, len;
990    VARDECL(celt_sig_t, freq);
991    const int C = CHANNELS(st->mode);
992    int offset;
993    SAVE_STACK;
994    N = st->block_size;
995    ALLOC(freq,C*N, celt_sig_t);         /**< Interleaved signal MDCTs */
996    
997    len = N+st->mode->overlap;
998 #if 0
999    pitch_index = st->last_pitch_index;
1000    
1001    /* Use the pitch MDCT as the "guessed" signal */
1002    compute_mdcts(st->mode, st->mode->window, st->out_mem+pitch_index*C, freq);
1003
1004 #else
1005    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);
1006    pitch_index = MAX_PERIOD-len-pitch_index;
1007    offset = MAX_PERIOD-pitch_index;
1008    while (offset+len >= MAX_PERIOD)
1009       offset -= pitch_index;
1010    compute_mdcts(st->mode, 0, st->out_mem+offset*C, freq);
1011    for (i=0;i<N;i++)
1012       freq[i] = ADD32(EPSILON, MULT16_32_Q15(QCONST16(.9f,15),freq[i]));
1013 #endif
1014    
1015    
1016    
1017    CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD+st->mode->overlap-N));
1018    /* Compute inverse MDCTs */
1019    compute_inv_mdcts(st->mode, 0, freq, -1, 0, st->out_mem);
1020
1021    for (c=0;c<C;c++)
1022    {
1023       int j;
1024       for (j=0;j<N;j++)
1025       {
1026          celt_sig_t tmp = MAC16_32_Q15(st->out_mem[C*(MAX_PERIOD-N)+C*j+c],
1027                                 preemph,st->preemph_memD[c]);
1028          st->preemph_memD[c] = tmp;
1029          pcm[C*j+c] = SCALEOUT(SIG2WORD16(tmp));
1030       }
1031    }
1032    RESTORE_STACK;
1033 }
1034 #endif
1035
1036 #ifdef FIXED_POINT
1037 int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, celt_int16_t * restrict pcm)
1038 {
1039 #else
1040 int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, celt_sig_t * restrict pcm)
1041 {
1042 #endif
1043    int i, c, N, N4;
1044    int has_pitch, has_fold;
1045    int pitch_index;
1046    int bits;
1047    ec_dec dec;
1048    ec_byte_buffer buf;
1049    VARDECL(celt_sig_t, freq);
1050    VARDECL(celt_norm_t, X);
1051    VARDECL(celt_norm_t, P);
1052    VARDECL(celt_ener_t, bandE);
1053    VARDECL(celt_pgain_t, gains);
1054    VARDECL(int, stereo_mode);
1055    VARDECL(int, fine_quant);
1056    VARDECL(int, pulses);
1057    VARDECL(int, offsets);
1058
1059    int shortBlocks;
1060    int intra_ener;
1061    int transient_time;
1062    int transient_shift;
1063    const int C = CHANNELS(st->mode);
1064    SAVE_STACK;
1065
1066    if (check_mode(st->mode) != CELT_OK)
1067       return CELT_INVALID_MODE;
1068
1069    N = st->block_size;
1070    N4 = (N-st->overlap)>>1;
1071
1072    ALLOC(freq, C*N, celt_sig_t); /**< Interleaved signal MDCTs */
1073    ALLOC(X, C*N, celt_norm_t);         /**< Interleaved normalised MDCTs */
1074    ALLOC(P, C*N, celt_norm_t);         /**< Interleaved normalised pitch MDCTs*/
1075    ALLOC(bandE, st->mode->nbEBands*C, celt_ener_t);
1076    ALLOC(gains, st->mode->nbPBands, celt_pgain_t);
1077    
1078    if (check_mode(st->mode) != CELT_OK)
1079    {
1080       RESTORE_STACK;
1081       return CELT_INVALID_MODE;
1082    }
1083    if (data == NULL)
1084    {
1085       celt_decode_lost(st, pcm);
1086       RESTORE_STACK;
1087       return 0;
1088    }
1089    if (len<0) {
1090      RESTORE_STACK;
1091      return CELT_BAD_ARG;
1092    }
1093    
1094    ec_byte_readinit(&buf,(unsigned char*)data,len);
1095    ec_dec_init(&dec,&buf);
1096    
1097    decode_flags(&dec, &intra_ener, &has_pitch, &shortBlocks, &has_fold);
1098    if (shortBlocks)
1099    {
1100       transient_shift = ec_dec_bits(&dec, 2);
1101       if (transient_shift)
1102          transient_time = ec_dec_uint(&dec, N+st->mode->overlap);
1103       else
1104          transient_time = 0;
1105    } else {
1106       transient_time = -1;
1107       transient_shift = 0;
1108    }
1109    
1110    if (has_pitch)
1111    {
1112       pitch_index = ec_dec_uint(&dec, MAX_PERIOD-(2*N-2*N4));
1113       st->last_pitch_index = pitch_index;
1114    } else {
1115       pitch_index = 0;
1116       for (i=0;i<st->mode->nbPBands;i++)
1117          gains[i] = 0;
1118    }
1119
1120    ALLOC(fine_quant, st->mode->nbEBands, int);
1121    /* Get band energies */
1122    unquant_coarse_energy(st->mode, bandE, st->oldBandE, len*8/3, intra_ener, st->mode->prob, &dec);
1123    
1124    ALLOC(pulses, st->mode->nbEBands, int);
1125    ALLOC(offsets, st->mode->nbEBands, int);
1126    ALLOC(stereo_mode, st->mode->nbEBands, int);
1127    stereo_decision(st->mode, X, stereo_mode, st->mode->nbEBands);
1128
1129    for (i=0;i<st->mode->nbEBands;i++)
1130       offsets[i] = 0;
1131
1132    bits = len*8 - ec_dec_tell(&dec, 0) - 1;
1133    if (has_pitch)
1134       bits -= st->mode->nbPBands;
1135    compute_allocation(st->mode, offsets, stereo_mode, bits, pulses, fine_quant);
1136    /*bits = ec_dec_tell(&dec, 0);
1137    compute_fine_allocation(st->mode, fine_quant, (20*C+len*8/5-(ec_dec_tell(&dec, 0)-bits))/C);*/
1138    
1139    unquant_fine_energy(st->mode, bandE, st->oldBandE, fine_quant, &dec);
1140
1141
1142    if (has_pitch) 
1143    {
1144       VARDECL(celt_ener_t, bandEp);
1145       
1146       /* Pitch MDCT */
1147       compute_mdcts(st->mode, 0, st->out_mem+pitch_index*C, freq);
1148       ALLOC(bandEp, st->mode->nbEBands*C, celt_ener_t);
1149       compute_band_energies(st->mode, freq, bandEp);
1150       normalise_bands(st->mode, freq, P, bandEp);
1151       /* Apply pitch gains */
1152    } else {
1153       for (i=0;i<C*N;i++)
1154          P[i] = 0;
1155    }
1156
1157    /* Decode fixed codebook and merge with pitch */
1158    if (C==1)
1159       unquant_bands(st->mode, X, P, has_pitch, gains, bandE, pulses, shortBlocks, has_fold, len*8, &dec);
1160    else
1161       unquant_bands_stereo(st->mode, X, P, has_pitch, gains, bandE, pulses, shortBlocks, has_fold, len*8, &dec);
1162
1163    /* Synthesis */
1164    denormalise_bands(st->mode, X, freq, bandE);
1165
1166
1167    CELT_MOVE(st->decode_mem, st->decode_mem+C*N, C*(DECODE_BUFFER_SIZE+st->overlap-N));
1168    /* Compute inverse MDCTs */
1169    compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem);
1170
1171    for (c=0;c<C;c++)
1172    {
1173       int j;
1174       for (j=0;j<N;j++)
1175       {
1176          celt_sig_t tmp = MAC16_32_Q15(st->out_mem[C*(MAX_PERIOD-N)+C*j+c],
1177                                 preemph,st->preemph_memD[c]);
1178          st->preemph_memD[c] = tmp;
1179          pcm[C*j+c] = SCALEOUT(SIG2WORD16(tmp));
1180       }
1181    }
1182
1183    {
1184       unsigned int val = 0;
1185       while (ec_dec_tell(&dec, 0) < len*8)
1186       {
1187          if (ec_dec_uint(&dec, 2) != val)
1188          {
1189             celt_warning("decode error");
1190             RESTORE_STACK;
1191             return CELT_CORRUPTED_DATA;
1192          }
1193          val = 1-val;
1194       }
1195    }
1196
1197    RESTORE_STACK;
1198    return 0;
1199    /*printf ("\n");*/
1200 }
1201
1202 #ifdef FIXED_POINT
1203 #ifndef DISABLE_FLOAT_API
1204 int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm)
1205 {
1206    int j, ret;
1207    const int C = CHANNELS(st->mode);
1208    const int N = st->block_size;
1209    VARDECL(celt_int16_t, out);
1210    SAVE_STACK;
1211    ALLOC(out, C*N, celt_int16_t);
1212
1213    ret=celt_decode(st, data, len, out);
1214
1215    for (j=0;j<C*N;j++)
1216      pcm[j]=out[j]*(1/32768.);
1217    RESTORE_STACK;
1218    return ret;
1219 }
1220 #endif /*DISABLE_FLOAT_API*/
1221 #else
1222 int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, celt_int16_t * restrict pcm)
1223 {
1224    int j, ret;
1225    VARDECL(celt_sig_t, out);
1226    const int C = CHANNELS(st->mode);
1227    const int N = st->block_size;
1228    SAVE_STACK;
1229    ALLOC(out, C*N, celt_sig_t);
1230
1231    ret=celt_decode_float(st, data, len, out);
1232
1233    for (j=0;j<C*N;j++)
1234      pcm[j] = FLOAT2INT16 (out[j]);
1235
1236    RESTORE_STACK;
1237    return ret;
1238 }
1239 #endif
1240
1241 int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
1242 {
1243    va_list ap;
1244    va_start(ap, request);
1245    switch (request)
1246    {
1247       case CELT_RESET_STATE:
1248       {
1249          const CELTMode *mode = st->mode;
1250          int C = mode->nbChannels;
1251
1252          CELT_MEMSET(st->decode_mem, 0, (DECODE_BUFFER_SIZE+st->overlap)*C);
1253          CELT_MEMSET(st->oldBandE, 0, C*mode->nbEBands);
1254
1255          CELT_MEMSET(st->preemph_memD, 0, C);
1256
1257          st->last_pitch_index = 0;
1258       }
1259       break;
1260       default:
1261          goto bad_request;
1262    }
1263    va_end(ap);
1264    return CELT_OK;
1265 #if 0    /* Put this back in if you ever need "bad_arg" */
1266 bad_arg:
1267    va_end(ap);
1268    return CELT_BAD_ARG;
1269 #endif
1270 bad_request:
1271       va_end(ap);
1272   return CELT_UNIMPLEMENTED;
1273 }