blob: 4bfe206fe0fdff7a9fa86ad1bcaa0b1278f3cb48 [file] [log] [blame]
Jean-Marc Valin8b2ff0d2009-10-17 21:40:10 -04001/* Copyright (c) 2007-2008 CSIRO
2 Copyright (c) 2007-2009 Xiph.Org Foundation
3 Copyright (c) 2008 Gregory Maxwell
4 Written by Jean-Marc Valin and Gregory Maxwell */
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11005/*
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 - Neither the name of the Xiph.org Foundation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*/
33
Jean-Marc Valin02fa9132008-02-20 12:09:29 +110034#ifdef HAVE_CONFIG_H
35#include "config.h"
36#endif
37
Jean-Marc Valin8600f692008-02-29 15:14:12 +110038#define CELT_C
39
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +110040#include "os_support.h"
Jean-Marc Valinf02ba112007-11-30 01:10:42 +110041#include "mdct.h"
42#include <math.h>
Jean-Marc Valin013c31d2007-11-30 11:36:46 +110043#include "celt.h"
Jean-Marc Valin14191b32007-11-30 12:15:49 +110044#include "pitch.h"
Jean-Marc Valin991c0f02007-11-30 16:07:46 +110045#include "bands.h"
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110046#include "modes.h"
Jean-Marc Valin6238bc02008-01-28 22:28:54 +110047#include "entcode.h"
Jean-Marc Valin98d2a492007-12-07 22:46:47 +110048#include "quant_bands.h"
Jean-Marc Valin4fbd18d2008-01-17 14:07:55 +110049#include "rate.h"
Jean-Marc Valinc7e0b762008-03-16 07:55:29 +110050#include "stack_alloc.h"
Jean-Marc Valine4aeb472008-06-29 12:06:05 +100051#include "mathops.h"
Jean-Marc Valind9b95652008-08-31 23:34:47 -040052#include "float_cast.h"
Jean-Marc Valinb6f90612008-10-05 22:39:13 -040053#include <stdarg.h>
Jean-Marc Valin6c3788c2010-06-20 22:48:50 -040054#include "plc.h"
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -050055
Jean-Marc Valin528f4b82008-06-29 03:46:39 +100056#ifdef FIXED_POINT
Jean-Marc Valin234969c2009-10-17 22:12:42 -040057static const celt_word16 transientWindow[16] = {
Jean-Marc Valin528f4b82008-06-29 03:46:39 +100058 279, 1106, 2454, 4276, 6510, 9081, 11900, 14872,
59 17896, 20868, 23687, 26258, 28492, 30314, 31662, 32489};
60#else
61static const float transientWindow[16] = {
Jean-Marc Valinae01e112010-08-03 21:43:41 -040062 0.0085135f, 0.0337639f, 0.0748914f, 0.1304955f,
63 0.1986827f, 0.2771308f, 0.3631685f, 0.4538658f,
64 0.5461342f, 0.6368315f, 0.7228692f, 0.8013173f,
65 0.8695045f, 0.9251086f, 0.9662361f, 0.9914865f};
Jean-Marc Valin528f4b82008-06-29 03:46:39 +100066#endif
67
Gregory Maxwell17169992009-06-04 15:15:34 -040068#define ENCODERVALID 0x4c434554
69#define ENCODERPARTIAL 0x5445434c
70#define ENCODERFREED 0x4c004500
Jean-Marc Valinc9943942008-08-30 00:55:07 -040071
Jean-Marc Valin276de722008-02-20 17:45:51 +110072/** Encoder state
73 @brief Encoder state
74 */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +110075struct CELTEncoder {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -040076 celt_uint32 marker;
Jean-Marc Valin276de722008-02-20 17:45:51 +110077 const CELTMode *mode; /**< Mode used by the encoder */
Jean-Marc Valina5431bf2008-01-03 20:53:01 +110078 int overlap;
Jean-Marc Valinffa13472007-12-10 16:54:17 +110079 int channels;
80
Gregory Maxwell2dd3d322009-06-05 14:05:51 -040081 int force_intra;
Jean-Marc Valin74f4e9f2009-05-02 09:57:50 -040082 int delayedIntra;
Jean-Marc Valin234969c2009-10-17 22:12:42 -040083 celt_word16 tonal_average;
Jean-Marc Valin527db5c2009-06-02 07:56:19 -040084 int fold_decision;
Jean-Marc Valin234969c2009-10-17 22:12:42 -040085 celt_word16 gain_prod;
Jean-Marc Valin9c30de52010-04-19 13:32:15 -040086 celt_word32 frame_max;
Jean-Marc Valin5f961462010-05-19 13:38:10 -040087 int start, end;
Jean-Marc Valin527db5c2009-06-02 07:56:19 -040088
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -040089 /* VBR-related parameters */
90 celt_int32 vbr_reservoir;
91 celt_int32 vbr_drift;
92 celt_int32 vbr_offset;
93 celt_int32 vbr_count;
94
Jean-Marc Valin8cc945c2010-05-29 08:07:18 -040095 celt_int32 vbr_rate_norm; /* Target number of 16th bits per frame */
Jean-Marc Valinac1da4f2010-07-24 11:48:10 -040096 celt_word32 preemph_memE[2];
97 celt_word32 preemph_memD[2];
Jean-Marc Valin81b38c22008-02-29 21:08:49 +110098
Jean-Marc Valin234969c2009-10-17 22:12:42 -040099 celt_sig *in_mem;
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400100 celt_sig *out_mem[2];
Jean-Marc Valin991c0f02007-11-30 16:07:46 +1100101
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400102 celt_word16 *oldBandE;
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100103};
104
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400105static int check_encoder(const CELTEncoder *st)
Gregory Maxwell17169992009-06-04 15:15:34 -0400106{
107 if (st==NULL)
108 {
109 celt_warning("NULL passed as an encoder structure");
110 return CELT_INVALID_STATE;
111 }
112 if (st->marker == ENCODERVALID)
113 return CELT_OK;
114 if (st->marker == ENCODERFREED)
115 celt_warning("Referencing an encoder that has already been freed");
116 else
117 celt_warning("This is not a valid CELT encoder structure");
118 return CELT_INVALID_STATE;
119}
120
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400121CELTEncoder *celt_encoder_create(const CELTMode *mode, int channels, int *error)
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100122{
Jean-Marc Valin04752672010-05-05 07:21:21 -0400123 int C;
Jean-Marc Valin02fa9132008-02-20 12:09:29 +1100124 CELTEncoder *st;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100125
126 if (check_mode(mode) != CELT_OK)
Jean-Marc Valinece94a02009-10-16 07:30:14 -0400127 {
128 if (error)
129 *error = CELT_INVALID_MODE;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100130 return NULL;
Jean-Marc Valinece94a02009-10-16 07:30:14 -0400131 }
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400132
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400133 if (channels < 0 || channels > 2)
134 {
135 celt_warning("Only mono and stereo supported");
136 if (error)
137 *error = CELT_BAD_ARG;
138 return NULL;
139 }
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100140
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400141 C = channels;
Jean-Marc Valin02fa9132008-02-20 12:09:29 +1100142 st = celt_alloc(sizeof(CELTEncoder));
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100143
Jean-Marc Valinece94a02009-10-16 07:30:14 -0400144 if (st==NULL)
145 {
146 if (error)
147 *error = CELT_ALLOC_FAIL;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400148 return NULL;
Jean-Marc Valinece94a02009-10-16 07:30:14 -0400149 }
Gregory Maxwell17169992009-06-04 15:15:34 -0400150 st->marker = ENCODERPARTIAL;
Jean-Marc Valin73e51b32007-12-05 17:48:24 +1100151 st->mode = mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100152 st->overlap = mode->overlap;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400153 st->channels = channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100154
Jean-Marc Valin5f961462010-05-19 13:38:10 -0400155 st->start = 0;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400156 st->end = st->mode->effEBands;
Jean-Marc Valin5f961462010-05-19 13:38:10 -0400157
Jean-Marc Valin8cc945c2010-05-29 08:07:18 -0400158 st->vbr_rate_norm = 0;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -0400159 st->force_intra = 0;
Gregory Maxwell8842fde2009-05-04 15:58:40 -0400160 st->delayedIntra = 1;
Jean-Marc Valin628c0252010-04-16 20:57:56 -0400161 st->tonal_average = QCONST16(1.f,8);
Jean-Marc Valin527db5c2009-06-02 07:56:19 -0400162 st->fold_decision = 1;
Jean-Marc Valina76a0b22008-01-17 22:43:05 +1100163
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400164 st->in_mem = celt_alloc(st->overlap*C*sizeof(celt_sig));
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400165 st->out_mem[0] = celt_alloc((MAX_PERIOD+st->overlap)*C*sizeof(celt_sig));
166 if (C==2)
167 st->out_mem[1] = st->out_mem[0] + MAX_PERIOD+st->overlap;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100168
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400169 st->oldBandE = (celt_word16*)celt_alloc(C*mode->nbEBands*sizeof(celt_word16));
Jean-Marc Valinfa248732007-12-06 07:51:27 +1100170
Jean-Marc Valinac1da4f2010-07-24 11:48:10 -0400171 if ((st->in_mem!=NULL) && (st->out_mem!=NULL) && (st->oldBandE!=NULL))
Gregory Maxwell17169992009-06-04 15:15:34 -0400172 {
Jean-Marc Valinece94a02009-10-16 07:30:14 -0400173 if (error)
174 *error = CELT_OK;
Gregory Maxwell17169992009-06-04 15:15:34 -0400175 st->marker = ENCODERVALID;
176 return st;
177 }
178 /* If the setup fails for some reason deallocate it. */
179 celt_encoder_destroy(st);
Jean-Marc Valinece94a02009-10-16 07:30:14 -0400180 if (error)
181 *error = CELT_ALLOC_FAIL;
Gregory Maxwell17169992009-06-04 15:15:34 -0400182 return NULL;
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100183}
184
Peter Kirk19f9dc92008-06-06 14:38:38 +0200185void celt_encoder_destroy(CELTEncoder *st)
Jean-Marc Valin14191b32007-11-30 12:15:49 +1100186{
187 if (st == NULL)
188 {
189 celt_warning("NULL passed to celt_encoder_destroy");
190 return;
191 }
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100192
Gregory Maxwell17169992009-06-04 15:15:34 -0400193 if (st->marker == ENCODERFREED)
194 {
Gregory Maxwell17169992009-06-04 15:15:34 -0400195 celt_warning("Freeing an encoder which has already been freed");
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400196 return;
Gregory Maxwell17169992009-06-04 15:15:34 -0400197 }
198
199 if (st->marker != ENCODERVALID && st->marker != ENCODERPARTIAL)
200 {
201 celt_warning("This is not a valid CELT encoder structure");
202 return;
203 }
204 /*Check_mode is non-fatal here because we can still free
205 the encoder memory even if the mode is bad, although calling
206 the free functions in this order is a violation of the API.*/
207 check_mode(st->mode);
208
Jean-Marc Valin14191b32007-11-30 12:15:49 +1100209 celt_free(st->in_mem);
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400210 celt_free(st->out_mem[0]);
Jean-Marc Valinc245a222007-12-06 19:14:20 +1100211 celt_free(st->oldBandE);
Jean-Marc Valin7351e282008-02-08 15:09:45 +1100212
Gregory Maxwell17169992009-06-04 15:15:34 -0400213 st->marker = ENCODERFREED;
Jean-Marc Valinc6ca4992008-06-01 23:19:16 +1000214
Jean-Marc Valin14191b32007-11-30 12:15:49 +1100215 celt_free(st);
216}
217
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400218static inline celt_int16 FLOAT2INT16(float x)
Jean-Marc Valin42074382008-02-27 11:08:53 +1100219{
Gregory Maxwell0ac2b2f2009-05-21 23:08:46 -0400220 x = x*CELT_SIG_SCALE;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400221 x = MAX32(x, -32768);
222 x = MIN32(x, 32767);
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400223 return (celt_int16)float2int(x);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400224}
225
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400226static inline celt_word16 SIG2WORD16(celt_sig x)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400227{
228#ifdef FIXED_POINT
Jean-Marc Valin42074382008-02-27 11:08:53 +1100229 x = PSHR32(x, SIG_SHIFT);
Jean-Marc Valinabdfc382008-04-18 15:57:18 +1000230 x = MAX32(x, -32768);
231 x = MIN32(x, 32767);
Jean-Marc Valin42074382008-02-27 11:08:53 +1100232 return EXTRACT16(x);
233#else
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400234 return (celt_word16)x;
Jean-Marc Valin42074382008-02-27 11:08:53 +1100235#endif
236}
237
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400238static int transient_analysis(const celt_word32 * restrict in, int len, int C,
239 int *transient_time, int *transient_shift,
Jean-Marc Valinbdb58712010-05-28 18:58:42 -0400240 celt_word32 *frame_max, int overlap)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000241{
Jean-Marc Valinbdb58712010-05-28 18:58:42 -0400242 int i, n;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400243 celt_word32 ratio;
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400244 celt_word32 threshold;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400245 VARDECL(celt_word32, begin);
Jean-Marc Valin0ceccb22008-07-03 20:41:06 -0400246 SAVE_STACK;
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400247 ALLOC(begin, len+1, celt_word32);
248 begin[0] = 0;
249 if (C==1)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000250 {
251 for (i=0;i<len;i++)
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400252 begin[i+1] = MAX32(begin[i], ABS32(in[i]));
253 } else {
254 for (i=0;i<len;i++)
255 begin[i+1] = MAX32(begin[i], MAX32(ABS32(in[C*i]),
256 ABS32(in[C*i+1])));
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000257 }
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000258 n = -1;
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400259
Jean-Marc Valine34c85a2010-07-15 17:57:50 -0400260 threshold = MULT16_32_Q15(QCONST16(.4f,15),begin[len]);
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400261 /* If the following condition isn't met, there's just no way
262 we'll have a transient*/
263 if (*frame_max < threshold)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000264 {
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400265 /* It's likely we have a transient, now find it */
266 for (i=8;i<len-8;i++)
267 {
268 if (begin[i+1] < threshold)
269 n=i;
270 }
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000271 }
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000272 if (n<32)
273 {
274 n = -1;
275 ratio = 0;
Jean-Marc Valinbd7de0a2008-07-06 10:57:26 -0400276 } else {
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400277 ratio = DIV32(begin[len],1+MAX32(*frame_max, begin[n-16]));
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000278 }
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400279
Jean-Marc Valin816f8932010-05-31 21:35:40 -0400280 if (ratio > 45)
Jean-Marc Valinbd7de0a2008-07-06 10:57:26 -0400281 *transient_shift = 3;
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400282 else
283 *transient_shift = 0;
284
Jean-Marc Valinbd7de0a2008-07-06 10:57:26 -0400285 *transient_time = n;
Jean-Marc Valinbdb58712010-05-28 18:58:42 -0400286 *frame_max = begin[len-overlap];
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400287
Jean-Marc Valin0ceccb22008-07-03 20:41:06 -0400288 RESTORE_STACK;
Jean-Marc Valine34c85a2010-07-15 17:57:50 -0400289 return ratio > 0;
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000290}
291
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400292/** Apply window and compute the MDCT for all sub-frames and
293 all channels in a frame */
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400294static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * restrict in, celt_sig * restrict out, int _C, int LM)
Jean-Marc Valinda721882007-11-30 15:17:42 +1100295{
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400296 const int C = CHANNELS(_C);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000297 if (C==1 && !shortBlocks)
Jean-Marc Valinda721882007-11-30 15:17:42 +1100298 {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000299 const int overlap = OVERLAP(mode);
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400300 clt_mdct_forward(&mode->mdct, in, out, mode->window, overlap, mode->maxLM-LM);
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400301 } else {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000302 const int overlap = OVERLAP(mode);
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400303 int N = mode->shortMdctSize<<LM;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400304 int B = 1;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000305 int b, c;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400306 VARDECL(celt_word32, x);
307 VARDECL(celt_word32, tmp);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000308 SAVE_STACK;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400309 if (shortBlocks)
310 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400311 /*lookup = &mode->mdct[0];*/
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400312 N = mode->shortMdctSize;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400313 B = shortBlocks;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400314 }
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400315 ALLOC(x, N+overlap, celt_word32);
316 ALLOC(tmp, N, celt_word32);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000317 for (c=0;c<C;c++)
318 {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000319 for (b=0;b<B;b++)
320 {
321 int j;
322 for (j=0;j<N+overlap;j++)
323 x[j] = in[C*(b*N+j)+c];
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400324 clt_mdct_forward(&mode->mdct, x, tmp, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000325 /* Interleaving the sub-frames */
326 for (j=0;j<N;j++)
Jean-Marc Valin08a82ff2009-06-14 14:05:19 -0400327 out[(j*B+b)+c*N*B] = tmp[j];
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000328 }
329 }
330 RESTORE_STACK;
Jean-Marc Valinda721882007-11-30 15:17:42 +1100331 }
Jean-Marc Valinda721882007-11-30 15:17:42 +1100332}
333
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400334/** Compute the IMDCT and apply window for all sub-frames and
335 all channels in a frame */
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400336static void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig *X, int transient_time, int transient_shift, celt_sig * restrict out_mem[], int _C, int LM)
Jean-Marc Valin1677aa92007-12-08 01:13:34 +1100337{
Jean-Marc Valinb886ddc2008-03-25 14:38:55 +1100338 int c, N4;
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400339 const int C = CHANNELS(_C);
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400340 const int N = mode->shortMdctSize<<LM;
Jean-Marc Valinb18ec0b2008-04-11 04:07:52 +1000341 const int overlap = OVERLAP(mode);
Jean-Marc Valina536f772008-03-22 09:01:50 +1100342 N4 = (N-overlap)>>1;
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100343 for (c=0;c<C;c++)
Jean-Marc Valin1677aa92007-12-08 01:13:34 +1100344 {
Jean-Marc Valinb886ddc2008-03-25 14:38:55 +1100345 int j;
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000346 if (transient_shift==0 && C==1 && !shortBlocks) {
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400347 clt_mdct_backward(&mode->mdct, X, out_mem[0]+(MAX_PERIOD-N-N4), mode->window, overlap, mode->maxLM-LM);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000348 } else {
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400349 VARDECL(celt_word32, x);
350 VARDECL(celt_word32, tmp);
Jean-Marc Valinde678582009-10-03 10:36:27 -0400351 int b;
352 int N2 = N;
353 int B = 1;
354 int n4offset=0;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000355 SAVE_STACK;
Jean-Marc Valinde678582009-10-03 10:36:27 -0400356
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400357 ALLOC(x, 2*N, celt_word32);
358 ALLOC(tmp, N, celt_word32);
Jean-Marc Valinde678582009-10-03 10:36:27 -0400359
360 if (shortBlocks)
361 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400362 /*lookup = &mode->mdct[0];*/
Jean-Marc Valinde678582009-10-03 10:36:27 -0400363 N2 = mode->shortMdctSize;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400364 B = shortBlocks;
Jean-Marc Valinde678582009-10-03 10:36:27 -0400365 n4offset = N4;
366 }
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000367 /* Prevents problems from the imdct doing the overlap-add */
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400368 CELT_MEMSET(x+N4, 0, N2);
Jean-Marc Valinde678582009-10-03 10:36:27 -0400369
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000370 for (b=0;b<B;b++)
371 {
372 /* De-interleaving the sub-frames */
373 for (j=0;j<N2;j++)
Jean-Marc Valin08a82ff2009-06-14 14:05:19 -0400374 tmp[j] = X[(j*B+b)+c*N2*B];
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400375 clt_mdct_backward(&mode->mdct, tmp, x+n4offset+N2*b, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000376 }
Jean-Marc Valinde678582009-10-03 10:36:27 -0400377
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000378 if (transient_shift > 0)
Jean-Marc Valin12b22482008-06-16 14:13:05 +1000379 {
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000380#ifdef FIXED_POINT
Jean-Marc Valin12b22482008-06-16 14:13:05 +1000381 for (j=0;j<16;j++)
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000382 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));
Jean-Marc Valin12b22482008-06-16 14:13:05 +1000383 for (j=transient_time;j<N+overlap;j++)
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000384 x[N4+j] = SHL32(x[N4+j], transient_shift);
385#else
386 for (j=0;j<16;j++)
Jean-Marc Valine4aeb472008-06-29 12:06:05 +1000387 x[N4+transient_time+j-16] *= 1+transientWindow[j]*((1<<transient_shift)-1);
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000388 for (j=transient_time;j<N+overlap;j++)
389 x[N4+j] *= 1<<transient_shift;
390#endif
Jean-Marc Valin12b22482008-06-16 14:13:05 +1000391 }
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400392 /* The first and last part would need to be set to zero
393 if we actually wanted to use them. */
Jean-Marc Valin8ddd7f42008-04-22 13:37:16 +1000394 for (j=0;j<overlap;j++)
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400395 out_mem[c][MAX_PERIOD-N+j] += x[j+N4];
Jean-Marc Valinab3784e2010-08-26 18:08:44 -0400396 for (;j<overlap+N;j++)
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400397 out_mem[c][MAX_PERIOD-N+j] = x[j+N4];
Jean-Marc Valin8ddd7f42008-04-22 13:37:16 +1000398 RESTORE_STACK;
399 }
Jean-Marc Valin1677aa92007-12-08 01:13:34 +1100400 }
401}
402
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400403static void deemphasis(celt_sig *in[], celt_word16 *pcm, int N, int _C, const celt_word16 *coef, celt_sig *mem)
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400404{
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400405 const int C = CHANNELS(_C);
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400406 int c;
407 for (c=0;c<C;c++)
408 {
409 int j;
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400410 celt_sig * restrict x;
411 celt_word16 * restrict y;
412 celt_sig m = mem[c];
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400413 x = &in[c][MAX_PERIOD-N];
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400414 y = pcm+c;
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400415 for (j=0;j<N;j++)
416 {
Jean-Marc Valinaf1fce92010-07-16 11:05:06 -0400417 celt_sig tmp = *x + m;
418 m = MULT16_32_Q15(coef[0], tmp)
419 - MULT16_32_Q15(coef[1], *x);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400420 tmp = SHL32(MULT16_32_Q15(coef[3], tmp), 2);
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400421 *y = SCALEOUT(SIG2WORD16(tmp));
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400422 x++;
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400423 y+=C;
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400424 }
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400425 mem[c] = m;
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400426 }
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400427}
428
Jean-Marc Valind6b79ee2010-04-20 17:31:45 -0400429static void mdct_shape(const CELTMode *mode, celt_norm *X, int start,
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400430 int end, int N,
Jean-Marc Valin69921c42010-07-16 15:25:30 -0400431 int mdct_weight_shift, int end_band, int _C, int renorm, int M)
Jean-Marc Valin88619552009-10-04 21:35:36 -0400432{
433 int m, i, c;
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400434 const int C = CHANNELS(_C);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400435 for (c=0;c<C;c++)
436 for (m=start;m<end;m++)
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400437 for (i=m+c*N;i<(c+1)*N;i+=M)
Jean-Marc Valin88619552009-10-04 21:35:36 -0400438#ifdef FIXED_POINT
439 X[i] = SHR16(X[i], mdct_weight_shift);
440#else
441 X[i] = (1.f/(1<<mdct_weight_shift))*X[i];
442#endif
Jean-Marc Valind6b79ee2010-04-20 17:31:45 -0400443 if (renorm)
Jean-Marc Valin69921c42010-07-16 15:25:30 -0400444 renormalise_bands(mode, X, end_band, C, M);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400445}
446
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400447static signed char tf_select_table[4][8] = {
448 {0, -1, 0, -1, 0,-1, 0,-1},
449 {0, -1, 0, -2, 1, 0, 1 -1},
450 {0, -2, 0, -3, 2, 0, 1 -1},
451 {0, -2, 0, -3, 2, 0, 1 -1},
452};
453
454static int tf_analysis(celt_word16 *bandLogE, celt_word16 *oldBandE, int len, int C, int isTransient, int *tf_res, int nbCompressedBytes)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400455{
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400456 int i;
Jean-Marc Valin0ef39c92010-05-28 17:50:34 -0400457 celt_word16 threshold;
Jean-Marc Valinb6a5f9d2010-07-06 17:54:33 -0400458 VARDECL(celt_word16, metric);
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400459 celt_word32 average=0;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400460 celt_word32 cost0;
461 celt_word32 cost1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400462 VARDECL(int, path0);
463 VARDECL(int, path1);
Jean-Marc Valin73319772010-05-28 21:12:39 -0400464 celt_word16 lambda;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400465 int tf_select=0;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400466 SAVE_STACK;
467
Jean-Marc Valin6bf3b0a2010-07-19 14:32:40 -0400468 /* FIXME: Should check number of bytes *left* */
469 if (nbCompressedBytes<15*C)
470 {
471 for (i=0;i<len;i++)
472 tf_res[i] = 0;
473 return 0;
474 }
Jean-Marc Valin73319772010-05-28 21:12:39 -0400475 if (nbCompressedBytes<40)
476 lambda = QCONST16(5.f, DB_SHIFT);
477 else if (nbCompressedBytes<60)
478 lambda = QCONST16(2.f, DB_SHIFT);
479 else if (nbCompressedBytes<100)
480 lambda = QCONST16(1.f, DB_SHIFT);
481 else
482 lambda = QCONST16(.5f, DB_SHIFT);
483
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400484 ALLOC(metric, len, celt_word16);
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400485 ALLOC(path0, len, int);
486 ALLOC(path1, len, int);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400487 for (i=0;i<len;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400488 {
Jean-Marc Valin73319772010-05-28 21:12:39 -0400489 metric[i] = SUB16(bandLogE[i], oldBandE[i]);
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400490 average += metric[i];
491 }
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400492 if (C==2)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400493 {
494 average = 0;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400495 for (i=0;i<len;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400496 {
Jean-Marc Valin73319772010-05-28 21:12:39 -0400497 metric[i] = HALF32(metric[i]) + HALF32(SUB16(bandLogE[i+len], oldBandE[i+len]));
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400498 average += metric[i];
499 }
500 }
501 average = DIV32(average, len);
502 /*if (!isTransient)
503 printf ("%f\n", average);*/
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400504 if (isTransient)
505 {
Jean-Marc Valin0ef39c92010-05-28 17:50:34 -0400506 threshold = QCONST16(1.f,DB_SHIFT);
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400507 tf_select = average > QCONST16(3.f,DB_SHIFT);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400508 } else {
Jean-Marc Valin0ef39c92010-05-28 17:50:34 -0400509 threshold = QCONST16(.5f,DB_SHIFT);
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400510 tf_select = average > QCONST16(1.f,DB_SHIFT);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400511 }
Jean-Marc Valin88232612010-05-28 18:01:02 -0400512 cost0 = 0;
513 cost1 = lambda;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400514 /* Viterbi forward pass */
515 for (i=1;i<len;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400516 {
Jean-Marc Valinb6a5f9d2010-07-06 17:54:33 -0400517 celt_word32 curr0, curr1;
518 celt_word32 from0, from1;
Jean-Marc Valin581fdba2010-05-28 06:56:23 -0400519
Jean-Marc Valin88232612010-05-28 18:01:02 -0400520 from0 = cost0;
521 from1 = cost1 + lambda;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400522 if (from0 < from1)
523 {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400524 curr0 = from0;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400525 path0[i]= 0;
526 } else {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400527 curr0 = from1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400528 path0[i]= 1;
529 }
530
Jean-Marc Valin88232612010-05-28 18:01:02 -0400531 from0 = cost0 + lambda;
532 from1 = cost1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400533 if (from0 < from1)
534 {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400535 curr1 = from0;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400536 path1[i]= 0;
537 } else {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400538 curr1 = from1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400539 path1[i]= 1;
540 }
Jean-Marc Valin88232612010-05-28 18:01:02 -0400541 cost0 = curr0 + (metric[i]-threshold);
542 cost1 = curr1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400543 }
Jean-Marc Valin88232612010-05-28 18:01:02 -0400544 tf_res[len-1] = cost0 < cost1 ? 0 : 1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400545 /* Viterbi backward pass to check the decisions */
546 for (i=len-2;i>=0;i--)
547 {
548 if (tf_res[i+1] == 1)
549 tf_res[i] = path1[i+1];
550 else
551 tf_res[i] = path0[i+1];
552 }
Jean-Marc Valin71ae6d42010-06-27 21:55:08 -0400553 RESTORE_STACK;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400554 return tf_select;
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400555}
556
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400557static void tf_encode(int start, int end, int isTransient, int *tf_res, int nbCompressedBytes, int LM, int tf_select, ec_enc *enc)
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400558{
559 int curr, i;
Jean-Marc Valine2d5b332010-06-06 23:16:40 -0400560 if (8*nbCompressedBytes - ec_enc_tell(enc, 0) < 100)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400561 {
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400562 for (i=start;i<end;i++)
Jean-Marc Valine2d5b332010-06-06 23:16:40 -0400563 tf_res[i] = isTransient;
564 } else {
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400565 ec_enc_bit_prob(enc, tf_res[start], isTransient ? 16384 : 4096);
566 curr = tf_res[start];
567 for (i=start+1;i<end;i++)
Jean-Marc Valine2d5b332010-06-06 23:16:40 -0400568 {
569 ec_enc_bit_prob(enc, tf_res[i] ^ curr, isTransient ? 4096 : 2048);
570 curr = tf_res[i];
571 }
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400572 }
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400573 ec_enc_bits(enc, tf_select, 1);
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400574 for (i=start;i<end;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400575 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400576}
577
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400578static void tf_decode(int start, int end, int C, int isTransient, int *tf_res, int nbCompressedBytes, int LM, ec_dec *dec)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400579{
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400580 int i, curr, tf_select;
Jean-Marc Valine2d5b332010-06-06 23:16:40 -0400581 if (8*nbCompressedBytes - ec_dec_tell(dec, 0) < 100)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400582 {
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400583 for (i=start;i<end;i++)
Jean-Marc Valine2d5b332010-06-06 23:16:40 -0400584 tf_res[i] = isTransient;
585 } else {
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400586 tf_res[start] = ec_dec_bit_prob(dec, isTransient ? 16384 : 4096);
587 curr = tf_res[start];
588 for (i=start+1;i<end;i++)
Jean-Marc Valine2d5b332010-06-06 23:16:40 -0400589 {
590 tf_res[i] = ec_dec_bit_prob(dec, isTransient ? 4096 : 2048) ^ curr;
591 curr = tf_res[i];
592 }
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400593 }
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400594 tf_select = ec_dec_bits(dec, 1);
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400595 for (i=start;i<end;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400596 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400597}
598
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400599#ifdef FIXED_POINT
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400600int celt_encode_with_ec(CELTEncoder * restrict st, const celt_int16 * pcm, celt_int16 * optional_resynthesis, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100601{
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400602#else
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400603int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, celt_sig * optional_resynthesis, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400604{
605#endif
Jean-Marc Valin88619552009-10-04 21:35:36 -0400606 int i, c, N, NN, N4;
Jean-Marc Valinc890b582008-08-01 22:26:49 -0400607 int bits;
Jean-Marc Valinbc799912008-11-07 22:53:13 -0500608 int has_fold=1;
Jean-Marc Valin8679a802008-10-18 07:44:35 -0400609 ec_byte_buffer buf;
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400610 ec_enc _enc;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400611 VARDECL(celt_sig, in);
612 VARDECL(celt_sig, freq);
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400613 VARDECL(celt_norm, X);
614 VARDECL(celt_ener, bandE);
615 VARDECL(celt_word16, bandLogE);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400616 VARDECL(int, fine_quant);
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400617 VARDECL(celt_word16, error);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400618 VARDECL(int, pulses);
619 VARDECL(int, offsets);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -0400620 VARDECL(int, fine_priority);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400621 VARDECL(int, tf_res);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000622 int shortBlocks=0;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400623 int isTransient=0;
Jean-Marc Valin0be05b02010-07-16 14:23:03 -0400624 int transient_time, transient_time_quant;
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000625 int transient_shift;
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -0400626 int resynth;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400627 const int C = CHANNELS(st->channels);
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400628 int mdct_weight_shift = 0;
629 int mdct_weight_pos=0;
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400630 int LM, M;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400631 int tf_select;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400632 int nbFilledBytes, nbAvailableBytes;
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400633 int effEnd;
Jean-Marc Valin8600f692008-02-29 15:14:12 +1100634 SAVE_STACK;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100635
Gregory Maxwell17169992009-06-04 15:15:34 -0400636 if (check_encoder(st) != CELT_OK)
637 return CELT_INVALID_STATE;
638
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100639 if (check_mode(st->mode) != CELT_OK)
640 return CELT_INVALID_MODE;
641
Gregory Maxwell0719f6f2009-07-09 17:07:24 -0400642 if (nbCompressedBytes<0 || pcm==NULL)
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400643 return CELT_BAD_ARG;
Gregory Maxwell520eeae2009-02-09 01:33:21 -0500644
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400645 for (LM=0;LM<4;LM++)
646 if (st->mode->shortMdctSize<<LM==frame_size)
647 break;
648 if (LM>=MAX_CONFIG_SIZES)
649 return CELT_BAD_ARG;
650 M=1<<LM;
Jean-Marc Valin8679a802008-10-18 07:44:35 -0400651
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400652 if (enc==NULL)
653 {
654 ec_byte_writeinit_buffer(&buf, compressed, nbCompressedBytes);
655 ec_enc_init(&_enc,&buf);
656 enc = &_enc;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400657 nbFilledBytes=0;
658 } else {
Jean-Marc Valinbdcaaf72010-07-05 13:52:41 -0400659 nbFilledBytes=(ec_enc_tell(enc, 0)+4)>>3;
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400660 }
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400661 nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
662
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400663 effEnd = st->end;
664 if (effEnd > st->mode->effEBands)
665 effEnd = st->mode->effEBands;
666
Jean-Marc Valin04752672010-05-05 07:21:21 -0400667 N = M*st->mode->shortMdctSize;
Jean-Marc Valina536f772008-03-22 09:01:50 +1100668 N4 = (N-st->overlap)>>1;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400669 ALLOC(in, 2*C*N-2*C*N4, celt_sig);
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100670
Jean-Marc Valinbdb58832008-04-20 17:42:10 +1000671 CELT_COPY(in, st->in_mem, C*st->overlap);
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100672 for (c=0;c<C;c++)
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +1100673 {
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400674 const celt_word16 * restrict pcmp = pcm+c;
675 celt_sig * restrict inp = in+C*st->overlap+c;
Jean-Marc Valinb886ddc2008-03-25 14:38:55 +1100676 for (i=0;i<N;i++)
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100677 {
Jean-Marc Valin62290062008-04-20 22:16:02 +1000678 /* Apply pre-emphasis */
Jean-Marc Valinaf1fce92010-07-16 11:05:06 -0400679 celt_sig tmp = MULT16_16(st->mode->preemph[2], SCALEIN(*pcmp));
680 *inp = tmp + st->preemph_memE[c];
681 st->preemph_memE[c] = MULT16_32_Q15(st->mode->preemph[1], *inp)
682 - MULT16_32_Q15(st->mode->preemph[0], tmp);
Jean-Marc Valin62290062008-04-20 22:16:02 +1000683 inp += C;
684 pcmp += C;
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100685 }
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +1100686 }
Jean-Marc Valinbdb58832008-04-20 17:42:10 +1000687 CELT_COPY(st->in_mem, in+C*(2*N-2*N4-st->overlap), C*st->overlap);
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400688
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -0500689 /* Transient handling */
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400690 transient_time = -1;
Jean-Marc Valin0be05b02010-07-16 14:23:03 -0400691 transient_time_quant = -1;
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400692 transient_shift = 0;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400693 isTransient = 0;
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400694
Jean-Marc Valin8cbea172010-08-05 15:22:57 -0400695 resynth = optional_resynthesis!=NULL;
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -0400696
Jean-Marc Valinbdb58712010-05-28 18:58:42 -0400697 if (M > 1 && transient_analysis(in, N+st->overlap, C, &transient_time, &transient_shift, &st->frame_max, st->overlap))
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000698 {
Jean-Marc Valin7028d622008-07-10 23:06:58 -0400699#ifndef FIXED_POINT
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400700 float gain_1;
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000701#endif
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400702 /* Apply the inverse shaping window */
703 if (transient_shift)
704 {
Jean-Marc Valin0be05b02010-07-16 14:23:03 -0400705 transient_time_quant = transient_time*(celt_int32)8000/st->mode->Fs;
706 transient_time = transient_time_quant*(celt_int32)st->mode->Fs/8000;
Jean-Marc Valin7028d622008-07-10 23:06:58 -0400707#ifdef FIXED_POINT
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400708 for (c=0;c<C;c++)
709 for (i=0;i<16;i++)
710 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]);
711 for (c=0;c<C;c++)
712 for (i=transient_time;i<N+st->overlap;i++)
713 in[C*i+c] = SHR32(in[C*i+c], transient_shift);
Jean-Marc Valin7028d622008-07-10 23:06:58 -0400714#else
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400715 for (c=0;c<C;c++)
716 for (i=0;i<16;i++)
717 in[C*(transient_time+i-16)+c] /= 1+transientWindow[i]*((1<<transient_shift)-1);
Jean-Marc Valin12996402010-08-04 09:13:24 -0400718 gain_1 = 1.f/(1<<transient_shift);
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400719 for (c=0;c<C;c++)
720 for (i=transient_time;i<N+st->overlap;i++)
721 in[C*i+c] *= gain_1;
Jean-Marc Valin7028d622008-07-10 23:06:58 -0400722#endif
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000723 }
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400724 isTransient = 1;
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400725 has_fold = 1;
Jean-Marc Valin12b22482008-06-16 14:13:05 +1000726 }
Jean-Marc Valinc5f2a9d2008-10-26 22:00:26 -0400727
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400728 if (isTransient)
729 shortBlocks = M;
730 else
731 shortBlocks = 0;
732
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400733 ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
734 ALLOC(bandE,st->mode->nbEBands*C, celt_ener);
735 ALLOC(bandLogE,st->mode->nbEBands*C, celt_word16);
Jean-Marc Valin32ec58c2009-05-01 21:28:58 -0400736 /* Compute MDCTs */
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400737 compute_mdcts(st->mode, shortBlocks, in, freq, C, LM);
Jean-Marc Valin08a82ff2009-06-14 14:05:19 -0400738
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400739 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
Jean-Marc Valin8d4ac152008-02-29 17:24:02 +1100740
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400741 compute_band_energies(st->mode, freq, bandE, effEnd, C, M);
Jean-Marc Valin504fb3c2010-08-06 15:56:22 -0400742
743 amp2Log2(st->mode, effEnd, st->end, bandE, bandLogE, C);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400744
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100745 /* Band normalisation */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400746 normalise_bands(st->mode, freq, X, bandE, effEnd, C, M);
Jean-Marc Valin4c77ea92009-09-14 22:50:41 -0400747
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400748 NN = M*st->mode->eBands[effEnd];
Jean-Marc Valin9f89cab2010-05-21 14:18:38 -0400749 if (shortBlocks && !transient_shift)
Jean-Marc Valin88619552009-10-04 21:35:36 -0400750 {
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400751 celt_word32 sum[8]={1,1,1,1,1,1,1,1};
Jean-Marc Valin88619552009-10-04 21:35:36 -0400752 int m;
753 for (c=0;c<C;c++)
754 {
755 m=0;
756 do {
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400757 celt_word32 tmp=0;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400758 for (i=m+c*N;i<c*N+NN;i+=M)
Jean-Marc Valin88619552009-10-04 21:35:36 -0400759 tmp += ABS32(X[i]);
760 sum[m++] += tmp;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400761 } while (m<M);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400762 }
763 m=0;
764#ifdef FIXED_POINT
765 do {
766 if (SHR32(sum[m+1],3) > sum[m])
767 {
768 mdct_weight_shift=2;
769 mdct_weight_pos = m;
770 } else if (SHR32(sum[m+1],1) > sum[m] && mdct_weight_shift < 2)
771 {
772 mdct_weight_shift=1;
773 mdct_weight_pos = m;
774 }
775 m++;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400776 } while (m<M-1);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400777#else
778 do {
779 if (sum[m+1] > 8*sum[m])
780 {
781 mdct_weight_shift=2;
782 mdct_weight_pos = m;
783 } else if (sum[m+1] > 2*sum[m] && mdct_weight_shift < 2)
784 {
785 mdct_weight_shift=1;
786 mdct_weight_pos = m;
787 }
788 m++;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400789 } while (m<M-1);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400790#endif
791 if (mdct_weight_shift)
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400792 mdct_shape(st->mode, X, mdct_weight_pos+1, M, N, mdct_weight_shift, effEnd, C, 0, M);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400793 }
794
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400795 ALLOC(tf_res, st->mode->nbEBands, int);
Jean-Marc Valin5e7f02d2010-08-08 09:48:22 -0400796 /* Needs to be before coarse energy quantization because otherwise the energy gets modified */
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400797 tf_select = tf_analysis(bandLogE, st->oldBandE, effEnd, C, isTransient, tf_res, nbAvailableBytes);
798 for (i=effEnd;i<st->end;i++)
799 tf_res[i] = tf_res[effEnd-1];
800
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400801 ALLOC(error, C*st->mode->nbEBands, celt_word16);
Jean-Marc Valin5e7f02d2010-08-08 09:48:22 -0400802 quant_coarse_energy(st->mode, st->start, st->end, effEnd, bandLogE,
803 st->oldBandE, nbCompressedBytes*8, st->mode->prob,
804 error, enc, C, LM, nbAvailableBytes, st->force_intra, &st->delayedIntra);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400805
Jean-Marc Valin017001a2010-08-05 15:42:50 -0400806 ec_enc_bit_prob(enc, shortBlocks!=0, 8192);
Jean-Marc Valin4c77ea92009-09-14 22:50:41 -0400807
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -0400808 if (shortBlocks)
809 {
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -0400810 if (transient_shift)
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400811 {
Jean-Marc Valin0be05b02010-07-16 14:23:03 -0400812 int max_time = (N+st->mode->overlap)*(celt_int32)8000/st->mode->Fs;
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400813 ec_enc_uint(enc, transient_shift, 4);
Jean-Marc Valin0be05b02010-07-16 14:23:03 -0400814 ec_enc_uint(enc, transient_time_quant, max_time);
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400815 } else {
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400816 ec_enc_uint(enc, mdct_weight_shift, 4);
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400817 if (mdct_weight_shift && M!=2)
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400818 ec_enc_uint(enc, mdct_weight_pos, M-1);
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400819 }
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -0400820 }
Jean-Marc Valinc890b582008-08-01 22:26:49 -0400821
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -0400822 tf_encode(st->start, st->end, isTransient, tf_res, nbAvailableBytes, LM, tf_select, enc);
823
Jean-Marc Valin908958c2010-08-07 22:15:02 -0400824 if (!shortBlocks && !folding_decision(st->mode, X, &st->tonal_average, &st->fold_decision, effEnd, C, M))
825 has_fold = 0;
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400826 ec_enc_bit_prob(enc, has_fold>>1, 8192);
827 ec_enc_bit_prob(enc, has_fold&1, (has_fold>>1) ? 32768 : 49152);
828
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400829 /* Variable bitrate */
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -0400830 if (st->vbr_rate_norm>0)
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400831 {
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400832 celt_word16 alpha;
Jean-Marc Valin25767d12009-10-21 23:24:18 -0400833 celt_int32 delta;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400834 /* The target rate in 16th bits per frame */
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -0400835 celt_int32 vbr_rate;
836 celt_int32 target;
837 celt_int32 vbr_bound, max_allowed;
838
839 vbr_rate = M*st->vbr_rate_norm;
840
841 /* Computes the max bit-rate allowed in VBR more to avoid busting the budget */
842 vbr_bound = vbr_rate;
843 max_allowed = (vbr_rate + vbr_bound - st->vbr_reservoir)>>(BITRES+3);
844 if (max_allowed < 4)
845 max_allowed = 4;
846 if (max_allowed < nbAvailableBytes)
847 nbAvailableBytes = max_allowed;
848 target=vbr_rate;
849
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400850 /* Shortblocks get a large boost in bitrate, but since they
851 are uncommon long blocks are not greatly effected */
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400852 if (shortBlocks)
853 target*=2;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400854 else if (M > 1)
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400855 target-=(target+14)/28;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400856
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400857 /* The average energy is removed from the target and the actual
858 energy added*/
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400859 target=target+st->vbr_offset-588+ec_enc_tell(enc, BITRES);
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400860
861 /* In VBR mode the frame size must not be reduced so much that it would result in the coarse energy busting its budget */
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400862 target=IMIN(nbAvailableBytes,target);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400863 /* Make the adaptation coef (alpha) higher at the beginning */
864 if (st->vbr_count < 990)
865 {
866 st->vbr_count++;
867 alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+10),16));
868 /*printf ("%d %d\n", st->vbr_count+10, alpha);*/
869 } else
870 alpha = QCONST16(.001f,15);
871
872 /* By how much did we "miss" the target on that frame */
Jean-Marc Valin8cc945c2010-05-29 08:07:18 -0400873 delta = (8<<BITRES)*(celt_int32)target - vbr_rate;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400874 /* How many bits have we used in excess of what we're allowed */
875 st->vbr_reservoir += delta;
876 /*printf ("%d\n", st->vbr_reservoir);*/
877
878 /* Compute the offset we need to apply in order to reach the target */
879 st->vbr_drift += MULT16_32_Q15(alpha,delta-st->vbr_offset-st->vbr_drift);
880 st->vbr_offset = -st->vbr_drift;
881 /*printf ("%d\n", st->vbr_drift);*/
882
883 /* We could use any multiple of vbr_rate as bound (depending on the delay) */
Jean-Marc Valin25767d12009-10-21 23:24:18 -0400884 if (st->vbr_reservoir < 0)
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400885 {
886 /* We're under the min value -- increase rate */
887 int adjust = 1-(st->vbr_reservoir-1)/(8<<BITRES);
888 st->vbr_reservoir += adjust*(8<<BITRES);
Jean-Marc Valin45f11102009-10-22 00:12:31 -0400889 target += adjust;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400890 /*printf ("+%d\n", adjust);*/
891 }
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400892 if (target < nbAvailableBytes)
893 nbAvailableBytes = target;
894 nbCompressedBytes = nbAvailableBytes + nbFilledBytes;
895
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400896 /* This moves the raw bits to take into account the new compressed size */
Jean-Marc Valine6108642009-08-01 23:05:47 +0200897 ec_byte_shrink(&buf, nbCompressedBytes);
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400898 }
899
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -0400900 /* Bit allocation */
901 ALLOC(fine_quant, st->mode->nbEBands, int);
902 ALLOC(pulses, st->mode->nbEBands, int);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400903 ALLOC(offsets, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -0400904 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +1100905
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400906 for (i=0;i<st->mode->nbEBands;i++)
907 offsets[i] = 0;
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400908 bits = nbCompressedBytes*8 - ec_enc_tell(enc, 0) - 1;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -0400909 compute_allocation(st->mode, st->start, st->end, offsets, bits, pulses, fine_quant, fine_priority, C, M);
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -0500910
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -0400911 quant_fine_energy(st->mode, st->start, st->end, bandE, st->oldBandE, error, fine_quant, enc, C);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400912
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +0200913#ifdef MEASURE_NORM_MSE
Jean-Marc Valin44092242010-07-29 18:32:54 +0200914 float X0[3000];
915 float bandE0[60];
916 for (c=0;c<C;c++)
917 for (i=0;i<N;i++)
918 X0[i+c*N] = X[i+c*N];
919 for (i=0;i<C*st->mode->nbEBands;i++)
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +0200920 bandE0[i] = bandE[i];
921#endif
922
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100923 /* Residual quantisation */
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400924 quant_all_bands(1, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, bandE, pulses, shortBlocks, has_fold, tf_res, resynth, nbCompressedBytes*8, enc, LM);
Jean-Marc Valin39710532009-06-09 00:10:32 -0400925
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -0400926 quant_energy_finalise(st->mode, st->start, st->end, bandE, st->oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_enc_tell(enc, 0), enc, C);
Jean-Marc Valin39710532009-06-09 00:10:32 -0400927
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -0500928 /* Re-synthesis of the coded audio if required */
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -0400929 if (resynth)
Jean-Marc Valin18ddc022008-02-22 14:24:50 +1100930 {
Jean-Marc Valinbc272de2010-08-02 09:41:31 -0400931 log2Amp(st->mode, st->start, st->end, bandE, st->oldBandE, C);
932
933#ifdef MEASURE_NORM_MSE
934 measure_norm_mse(st->mode, X, X0, bandE, bandE0, M, N, C);
935#endif
936
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400937 if (mdct_weight_shift)
938 {
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400939 mdct_shape(st->mode, X, 0, mdct_weight_pos+1, N, mdct_weight_shift, effEnd, C, 1, M);
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400940 }
Jean-Marc Valin88619552009-10-04 21:35:36 -0400941
942 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400943 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400944
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400945 CELT_MOVE(st->out_mem[0], st->out_mem[0]+N, MAX_PERIOD+st->overlap-N);
946 if (C==2)
947 CELT_MOVE(st->out_mem[1], st->out_mem[1]+N, MAX_PERIOD+st->overlap-N);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400948
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -0400949 for (c=0;c<C;c++)
950 for (i=0;i<M*st->mode->eBands[st->start];i++)
951 freq[c*N+i] = 0;
952 for (c=0;c<C;c++)
953 for (i=M*st->mode->eBands[st->end];i<N;i++)
954 freq[c*N+i] = 0;
955
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400956 compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem, C, LM);
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400957
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400958 /* De-emphasis and put everything back at the right place
959 in the synthesis history */
Jean-Marc Valind56c6102010-05-07 20:30:22 -0400960 if (optional_resynthesis != NULL) {
Jean-Marc Valinaf1fce92010-07-16 11:05:06 -0400961 deemphasis(st->out_mem, optional_resynthesis, N, C, st->mode->preemph, st->preemph_memD);
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400962
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +1100963 }
Jean-Marc Valind9b95652008-08-31 23:34:47 -0400964 }
Gregory Maxwell54547f12009-02-16 18:56:44 -0500965
Jean-Marc Valin30d51252010-06-21 17:55:28 -0400966 /* If there's any room left (can only happen for very high rates),
967 fill it with zeros */
Jean-Marc Valin5d774e02010-08-04 17:17:18 -0400968 while (ec_enc_tell(enc,0) + 8 <= nbCompressedBytes*8)
Jean-Marc Valin30d51252010-06-21 17:55:28 -0400969 ec_enc_bits(enc, 0, 8);
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400970 ec_enc_done(enc);
Jean-Marc Valinc871c8d2009-06-09 00:57:00 -0400971
Jean-Marc Valin8600f692008-02-29 15:14:12 +1100972 RESTORE_STACK;
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -0400973 if (ec_enc_get_error(enc))
Jean-Marc Valin9d785af2010-07-18 09:42:05 -0400974 return CELT_CORRUPTED_DATA;
975 else
976 return nbCompressedBytes;
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100977}
978
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400979#ifdef FIXED_POINT
980#ifndef DISABLE_FLOAT_API
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400981int celt_encode_with_ec_float(CELTEncoder * restrict st, const float * pcm, float * optional_resynthesis, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400982{
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400983 int j, ret, C, N, LM, M;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400984 VARDECL(celt_int16, in);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -0400985 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -0400986
987 if (check_encoder(st) != CELT_OK)
988 return CELT_INVALID_STATE;
989
990 if (check_mode(st->mode) != CELT_OK)
991 return CELT_INVALID_MODE;
992
Gregory Maxwell0719f6f2009-07-09 17:07:24 -0400993 if (pcm==NULL)
994 return CELT_BAD_ARG;
995
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400996 for (LM=0;LM<4;LM++)
997 if (st->mode->shortMdctSize<<LM==frame_size)
998 break;
999 if (LM>=MAX_CONFIG_SIZES)
1000 return CELT_BAD_ARG;
1001 M=1<<LM;
1002
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001003 C = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001004 N = M*st->mode->shortMdctSize;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001005 ALLOC(in, C*N, celt_int16);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001006
1007 for (j=0;j<C*N;j++)
1008 in[j] = FLOAT2INT16(pcm[j]);
1009
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001010 if (optional_resynthesis != NULL) {
1011 ret=celt_encode_with_ec(st,in,in,frame_size,compressed,nbCompressedBytes, enc);
Gregory Maxwellb0a73a02008-12-12 16:54:25 -05001012 for (j=0;j<C*N;j++)
Jean-Marc Valinae01e112010-08-03 21:43:41 -04001013 optional_resynthesis[j]=in[j]*(1.f/32768.f);
Gregory Maxwell82595312008-09-30 18:20:14 -04001014 } else {
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001015 ret=celt_encode_with_ec(st,in,NULL,frame_size,compressed,nbCompressedBytes, enc);
Gregory Maxwell82595312008-09-30 18:20:14 -04001016 }
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001017 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001018 return ret;
1019
1020}
1021#endif /*DISABLE_FLOAT_API*/
1022#else
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001023int celt_encode_with_ec(CELTEncoder * restrict st, const celt_int16 * pcm, celt_int16 * optional_resynthesis, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001024{
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001025 int j, ret, C, N, LM, M;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001026 VARDECL(celt_sig, in);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -04001027 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001028
1029 if (check_encoder(st) != CELT_OK)
1030 return CELT_INVALID_STATE;
1031
1032 if (check_mode(st->mode) != CELT_OK)
1033 return CELT_INVALID_MODE;
1034
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001035 if (pcm==NULL)
1036 return CELT_BAD_ARG;
1037
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001038 for (LM=0;LM<4;LM++)
1039 if (st->mode->shortMdctSize<<LM==frame_size)
1040 break;
1041 if (LM>=MAX_CONFIG_SIZES)
1042 return CELT_BAD_ARG;
1043 M=1<<LM;
1044
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001045 C=CHANNELS(st->channels);
Jean-Marc Valin04752672010-05-05 07:21:21 -04001046 N=M*st->mode->shortMdctSize;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001047 ALLOC(in, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001048 for (j=0;j<C*N;j++) {
1049 in[j] = SCALEOUT(pcm[j]);
1050 }
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001051
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001052 if (optional_resynthesis != NULL) {
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001053 ret = celt_encode_with_ec_float(st,in,in,frame_size,compressed,nbCompressedBytes, enc);
Gregory Maxwell82595312008-09-30 18:20:14 -04001054 for (j=0;j<C*N;j++)
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001055 optional_resynthesis[j] = FLOAT2INT16(in[j]);
Gregory Maxwell82595312008-09-30 18:20:14 -04001056 } else {
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001057 ret = celt_encode_with_ec_float(st,in,NULL,frame_size,compressed,nbCompressedBytes, enc);
Gregory Maxwell82595312008-09-30 18:20:14 -04001058 }
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001059 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001060 return ret;
1061}
1062#endif
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +11001063
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001064int celt_encode(CELTEncoder * restrict st, const celt_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1065{
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001066 return celt_encode_with_ec(st, pcm, NULL, frame_size, compressed, nbCompressedBytes, NULL);
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001067}
1068
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001069#ifndef DISABLE_FLOAT_API
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001070int celt_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1071{
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001072 return celt_encode_with_ec_float(st, pcm, NULL, frame_size, compressed, nbCompressedBytes, NULL);
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001073}
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001074#endif /* DISABLE_FLOAT_API */
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001075
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001076int celt_encode_resynthesis(CELTEncoder * restrict st, const celt_int16 * pcm, celt_int16 * optional_resynthesis, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1077{
1078 return celt_encode_with_ec(st, pcm, optional_resynthesis, frame_size, compressed, nbCompressedBytes, NULL);
1079}
1080
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001081#ifndef DISABLE_FLOAT_API
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001082int celt_encode_resynthesis_float(CELTEncoder * restrict st, const float * pcm, float * optional_resynthesis, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1083{
1084 return celt_encode_with_ec_float(st, pcm, optional_resynthesis, frame_size, compressed, nbCompressedBytes, NULL);
1085}
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001086#endif /* DISABLE_FLOAT_API */
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001087
1088
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001089int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...)
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001090{
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001091 va_list ap;
Gregory Maxwell17169992009-06-04 15:15:34 -04001092
1093 if (check_encoder(st) != CELT_OK)
1094 return CELT_INVALID_STATE;
1095
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001096 va_start(ap, request);
Gregory Maxwell17169992009-06-04 15:15:34 -04001097 if ((request!=CELT_GET_MODE_REQUEST) && (check_mode(st->mode) != CELT_OK))
1098 goto bad_mode;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001099 switch (request)
1100 {
Gregory Maxwellf3b44ef2009-06-03 13:37:45 -04001101 case CELT_GET_MODE_REQUEST:
1102 {
1103 const CELTMode ** value = va_arg(ap, const CELTMode**);
1104 if (value==0)
1105 goto bad_arg;
1106 *value=st->mode;
1107 }
1108 break;
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001109 case CELT_SET_COMPLEXITY_REQUEST:
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001110 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001111 int value = va_arg(ap, celt_int32);
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001112 if (value<0 || value>10)
1113 goto bad_arg;
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001114 }
1115 break;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001116 case CELT_SET_START_BAND_REQUEST:
1117 {
1118 celt_int32 value = va_arg(ap, celt_int32);
1119 if (value<0 || value>=st->mode->nbEBands)
1120 goto bad_arg;
1121 st->start = value;
1122 }
1123 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001124 case CELT_SET_END_BAND_REQUEST:
1125 {
1126 celt_int32 value = va_arg(ap, celt_int32);
1127 if (value<0 || value>=st->mode->nbEBands)
1128 goto bad_arg;
1129 st->end = value;
1130 }
1131 break;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001132 case CELT_SET_PREDICTION_REQUEST:
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001133 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001134 int value = va_arg(ap, celt_int32);
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001135 if (value<0 || value>2)
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001136 goto bad_arg;
1137 if (value==0)
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001138 {
1139 st->force_intra = 1;
Gregory Maxwella80958b2009-06-29 12:48:57 -04001140 } else if (value==1) {
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001141 st->force_intra = 0;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001142 } else {
1143 st->force_intra = 0;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001144 }
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001145 }
1146 break;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001147 case CELT_SET_VBR_RATE_REQUEST:
1148 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001149 celt_int32 value = va_arg(ap, celt_int32);
Jean-Marc Valin8cc945c2010-05-29 08:07:18 -04001150 int frame_rate;
1151 int N = st->mode->shortMdctSize;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001152 if (value<0)
1153 goto bad_arg;
1154 if (value>3072000)
1155 value = 3072000;
Jean-Marc Valin8cc945c2010-05-29 08:07:18 -04001156 frame_rate = ((st->mode->Fs<<3)+(N>>1))/N;
1157 st->vbr_rate_norm = ((value<<(BITRES+3))+(frame_rate>>1))/frame_rate;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001158 }
1159 break;
John Ridges454d1d02009-05-21 22:38:39 -04001160 case CELT_RESET_STATE:
1161 {
1162 const CELTMode *mode = st->mode;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001163 int C = st->channels;
John Ridges454d1d02009-05-21 22:38:39 -04001164
John Ridges454d1d02009-05-21 22:38:39 -04001165 CELT_MEMSET(st->in_mem, 0, st->overlap*C);
1166 CELT_MEMSET(st->out_mem, 0, (MAX_PERIOD+st->overlap)*C);
1167
1168 CELT_MEMSET(st->oldBandE, 0, C*mode->nbEBands);
1169
1170 CELT_MEMSET(st->preemph_memE, 0, C);
1171 CELT_MEMSET(st->preemph_memD, 0, C);
1172 st->delayedIntra = 1;
John Ridges5378bf82010-02-12 07:08:01 -05001173
1174 st->fold_decision = 1;
Jean-Marc Valin628c0252010-04-16 20:57:56 -04001175 st->tonal_average = QCONST16(1.f,8);
John Ridges5378bf82010-02-12 07:08:01 -05001176 st->gain_prod = 0;
1177 st->vbr_reservoir = 0;
1178 st->vbr_drift = 0;
1179 st->vbr_offset = 0;
1180 st->vbr_count = 0;
Jean-Marc Valin9c30de52010-04-19 13:32:15 -04001181 st->frame_max = 0;
John Ridges454d1d02009-05-21 22:38:39 -04001182 }
1183 break;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001184 default:
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001185 goto bad_request;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001186 }
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001187 va_end(ap);
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001188 return CELT_OK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001189bad_mode:
1190 va_end(ap);
1191 return CELT_INVALID_MODE;
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001192bad_arg:
1193 va_end(ap);
1194 return CELT_BAD_ARG;
1195bad_request:
1196 va_end(ap);
1197 return CELT_UNIMPLEMENTED;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001198}
1199
Jean-Marc Valin56522ad2009-06-05 17:17:25 -04001200/**********************************************************************/
1201/* */
1202/* DECODER */
1203/* */
1204/**********************************************************************/
Jean-Marc Valineafbdd52009-04-27 19:35:09 -04001205#define DECODE_BUFFER_SIZE 2048
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001206
Gregory Maxwell17169992009-06-04 15:15:34 -04001207#define DECODERVALID 0x4c434454
1208#define DECODERPARTIAL 0x5444434c
1209#define DECODERFREED 0x4c004400
1210
Jean-Marc Valin276de722008-02-20 17:45:51 +11001211/** Decoder state
1212 @brief Decoder state
1213 */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001214struct CELTDecoder {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001215 celt_uint32 marker;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001216 const CELTMode *mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001217 int overlap;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001218 int channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001219
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001220 int start, end;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001221
Jean-Marc Valinac1da4f2010-07-24 11:48:10 -04001222 celt_sig preemph_memD[2];
Jean-Marc Valin81b38c22008-02-29 21:08:49 +11001223
Jean-Marc Valin903dbf72010-08-26 20:06:49 -04001224 celt_sig *out_mem[2];
1225 celt_word32 *decode_mem[2];
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001226
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001227 celt_word16 *oldBandE;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001228
Jean-Marc Valin74128be2010-01-01 09:33:17 -05001229 celt_word16 *lpc;
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001230
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001231 int last_pitch_index;
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001232 int loss_count;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001233};
1234
Gregory Maxwell17169992009-06-04 15:15:34 -04001235int check_decoder(const CELTDecoder *st)
1236{
1237 if (st==NULL)
1238 {
1239 celt_warning("NULL passed a decoder structure");
1240 return CELT_INVALID_STATE;
1241 }
1242 if (st->marker == DECODERVALID)
1243 return CELT_OK;
1244 if (st->marker == DECODERFREED)
1245 celt_warning("Referencing a decoder that has already been freed");
1246 else
1247 celt_warning("This is not a valid CELT decoder structure");
1248 return CELT_INVALID_STATE;
1249}
1250
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001251CELTDecoder *celt_decoder_create(const CELTMode *mode, int channels, int *error)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001252{
Jean-Marc Valin04752672010-05-05 07:21:21 -04001253 int C;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11001254 CELTDecoder *st;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001255
1256 if (check_mode(mode) != CELT_OK)
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001257 {
1258 if (error)
1259 *error = CELT_INVALID_MODE;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001260 return NULL;
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001261 }
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001262
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001263 if (channels < 0 || channels > 2)
1264 {
1265 celt_warning("Only mono and stereo supported");
1266 if (error)
1267 *error = CELT_BAD_ARG;
1268 return NULL;
1269 }
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001270
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001271 C = CHANNELS(channels);
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11001272 st = celt_alloc(sizeof(CELTDecoder));
Gregory Maxwell17169992009-06-04 15:15:34 -04001273
1274 if (st==NULL)
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001275 {
1276 if (error)
1277 *error = CELT_ALLOC_FAIL;
Gregory Maxwell17169992009-06-04 15:15:34 -04001278 return NULL;
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001279 }
1280
Gregory Maxwell17169992009-06-04 15:15:34 -04001281 st->marker = DECODERPARTIAL;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001282 st->mode = mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001283 st->overlap = mode->overlap;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001284 st->channels = channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001285
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001286 st->start = 0;
Jean-Marc Valin8952c452010-07-16 21:48:44 -04001287 st->end = st->mode->effEBands;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001288
Jean-Marc Valin903dbf72010-08-26 20:06:49 -04001289 st->decode_mem[0] = (celt_sig*)celt_alloc((DECODE_BUFFER_SIZE+st->overlap)*C*sizeof(celt_sig));
1290 if (C==2)
1291 st->decode_mem[1] = st->decode_mem[0] + (DECODE_BUFFER_SIZE+st->overlap);
1292 st->out_mem[0] = st->decode_mem[0]+DECODE_BUFFER_SIZE-MAX_PERIOD;
1293 if (C==2)
1294 st->out_mem[1] = st->decode_mem[1]+DECODE_BUFFER_SIZE-MAX_PERIOD;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001295 st->oldBandE = (celt_word16*)celt_alloc(C*mode->nbEBands*sizeof(celt_word16));
Gregory Maxwell17169992009-06-04 15:15:34 -04001296
Jean-Marc Valin74128be2010-01-01 09:33:17 -05001297 st->lpc = (celt_word16*)celt_alloc(C*LPC_ORDER*sizeof(celt_word16));
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001298
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001299 st->loss_count = 0;
Gregory Maxwell17169992009-06-04 15:15:34 -04001300
1301 if ((st->decode_mem!=NULL) && (st->out_mem!=NULL) && (st->oldBandE!=NULL) &&
Jean-Marc Valinac1da4f2010-07-24 11:48:10 -04001302 (st->lpc!=NULL))
Gregory Maxwell17169992009-06-04 15:15:34 -04001303 {
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001304 if (error)
1305 *error = CELT_OK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001306 st->marker = DECODERVALID;
1307 return st;
1308 }
1309 /* If the setup fails for some reason deallocate it. */
1310 celt_decoder_destroy(st);
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001311 if (error)
1312 *error = CELT_ALLOC_FAIL;
Gregory Maxwell17169992009-06-04 15:15:34 -04001313 return NULL;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001314}
1315
Peter Kirk19f9dc92008-06-06 14:38:38 +02001316void celt_decoder_destroy(CELTDecoder *st)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001317{
1318 if (st == NULL)
1319 {
Gregory Maxwell17169992009-06-04 15:15:34 -04001320 celt_warning("NULL passed to celt_decoder_destroy");
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001321 return;
1322 }
Gregory Maxwell17169992009-06-04 15:15:34 -04001323
1324 if (st->marker == DECODERFREED)
1325 {
1326 celt_warning("Freeing a decoder which has already been freed");
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001327 return;
Gregory Maxwell17169992009-06-04 15:15:34 -04001328 }
1329
1330 if (st->marker != DECODERVALID && st->marker != DECODERPARTIAL)
1331 {
1332 celt_warning("This is not a valid CELT decoder structure");
1333 return;
1334 }
1335
1336 /*Check_mode is non-fatal here because we can still free
1337 the encoder memory even if the mode is bad, although calling
1338 the free functions in this order is a violation of the API.*/
1339 check_mode(st->mode);
1340
Jean-Marc Valin903dbf72010-08-26 20:06:49 -04001341 celt_free(st->decode_mem[0]);
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001342 celt_free(st->oldBandE);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001343 celt_free(st->lpc);
Gregory Maxwell17169992009-06-04 15:15:34 -04001344
1345 st->marker = DECODERFREED;
1346
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001347 celt_free(st);
1348}
1349
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001350static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict pcm, int N, int LM)
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001351{
Jean-Marc Valin04752672010-05-05 07:21:21 -04001352 int c;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11001353 int pitch_index;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001354 int overlap = st->mode->overlap;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001355 celt_word16 fade = Q15ONE;
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001356 int i, len;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001357 const int C = CHANNELS(st->channels);
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001358 int offset;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001359 SAVE_STACK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001360
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001361 len = N+st->mode->overlap;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001362
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001363 if (st->loss_count == 0)
1364 {
Jean-Marc Valin7a7c42a2009-11-25 20:38:52 -05001365 celt_word16 pitch_buf[MAX_PERIOD>>1];
Jean-Marc Valin294863b2009-11-08 22:29:54 +09001366 celt_word32 tmp=0;
Jean-Marc Valine465c142009-11-26 00:39:36 -05001367 celt_word32 mem0[2]={0,0};
1368 celt_word16 mem1[2]={0,0};
Jean-Marc Valin6202c742010-06-01 00:30:37 -04001369 int len2 = len;
1370 /* FIXME: This is a kludge */
1371 if (len2>MAX_PERIOD>>1)
1372 len2 = MAX_PERIOD>>1;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001373 pitch_downsample(st->out_mem, pitch_buf, MAX_PERIOD, MAX_PERIOD,
1374 C, mem0, mem1);
Jean-Marc Valin6202c742010-06-01 00:30:37 -04001375 pitch_search(st->mode, pitch_buf+((MAX_PERIOD-len2)>>1), pitch_buf, len2,
1376 MAX_PERIOD-len2-100, &pitch_index, &tmp, 1<<LM);
1377 pitch_index = MAX_PERIOD-len2-pitch_index;
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001378 st->last_pitch_index = pitch_index;
1379 } else {
1380 pitch_index = st->last_pitch_index;
1381 if (st->loss_count < 5)
1382 fade = QCONST16(.8f,15);
1383 else
1384 fade = 0;
1385 }
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001386
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001387 for (c=0;c<C;c++)
1388 {
Jean-Marc Valin6202c742010-06-01 00:30:37 -04001389 /* FIXME: This is more memory than necessary */
1390 celt_word32 e[2*MAX_PERIOD];
1391 celt_word16 exc[2*MAX_PERIOD];
Jean-Marc Valin456eab22010-06-16 22:38:57 -04001392 celt_word32 ac[LPC_ORDER+1];
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001393 celt_word16 decay = 1;
1394 celt_word32 S1=0;
Jean-Marc Valin74128be2010-01-01 09:33:17 -05001395 celt_word16 mem[LPC_ORDER]={0};
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001396
Jean-Marc Valind5f99302009-12-16 22:42:32 -05001397 offset = MAX_PERIOD-pitch_index;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001398 for (i=0;i<MAX_PERIOD;i++)
Jean-Marc Valin903dbf72010-08-26 20:06:49 -04001399 exc[i] = ROUND16(st->out_mem[c][i], SIG_SHIFT);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001400
1401 if (st->loss_count == 0)
1402 {
1403 _celt_autocorr(exc, ac, st->mode->window, st->mode->overlap,
1404 LPC_ORDER, MAX_PERIOD);
1405
Jean-Marc Valin456eab22010-06-16 22:38:57 -04001406 /* Noise floor -40 dB */
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001407#ifdef FIXED_POINT
1408 ac[0] += SHR32(ac[0],13);
1409#else
Jean-Marc Valinae01e112010-08-03 21:43:41 -04001410 ac[0] *= 1.0001f;
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001411#endif
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001412 /* Lag windowing */
1413 for (i=1;i<=LPC_ORDER;i++)
1414 {
1415 /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001416#ifdef FIXED_POINT
1417 ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);
1418#else
Jean-Marc Valinae01e112010-08-03 21:43:41 -04001419 ac[i] -= ac[i]*(.008f*i)*(.008f*i);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001420#endif
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001421 }
1422
Jean-Marc Valin74128be2010-01-01 09:33:17 -05001423 _celt_lpc(st->lpc+c*LPC_ORDER, ac, LPC_ORDER);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001424 }
Jean-Marc Valin74128be2010-01-01 09:33:17 -05001425 fir(exc, st->lpc+c*LPC_ORDER, exc, MAX_PERIOD, LPC_ORDER, mem);
1426 /*for (i=0;i<MAX_PERIOD;i++)printf("%d ", exc[i]); printf("\n");*/
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001427 /* Check if the waveform is decaying (and if so how fast) */
1428 {
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001429 celt_word32 E1=1, E2=1;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001430 int period;
1431 if (pitch_index <= MAX_PERIOD/2)
1432 period = pitch_index;
1433 else
1434 period = MAX_PERIOD/2;
1435 for (i=0;i<period;i++)
1436 {
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001437 E1 += SHR32(MULT16_16(exc[MAX_PERIOD-period+i],exc[MAX_PERIOD-period+i]),8);
1438 E2 += SHR32(MULT16_16(exc[MAX_PERIOD-2*period+i],exc[MAX_PERIOD-2*period+i]),8);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001439 }
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001440 if (E1 > E2)
1441 E1 = E2;
1442 decay = celt_sqrt(frac_div32(SHR(E1,1),E2));
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001443 }
1444
1445 /* Copy excitation, taking decay into account */
1446 for (i=0;i<len+st->mode->overlap;i++)
1447 {
1448 if (offset+i >= MAX_PERIOD)
1449 {
1450 offset -= pitch_index;
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001451 decay = MULT16_16_Q15(decay, decay);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001452 }
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001453 e[i] = SHL32(EXTEND32(MULT16_16_Q15(decay, exc[offset+i])), SIG_SHIFT);
Jean-Marc Valin903dbf72010-08-26 20:06:49 -04001454 S1 += SHR32(MULT16_16(st->out_mem[c][offset+i],st->out_mem[c][offset+i]),8);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001455 }
1456
Jean-Marc Valin74128be2010-01-01 09:33:17 -05001457 iir(e, st->lpc+c*LPC_ORDER, e, len+st->mode->overlap, LPC_ORDER, mem);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001458
1459 {
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001460 celt_word32 S2=0;
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001461 for (i=0;i<len+overlap;i++)
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001462 S2 += SHR32(MULT16_16(e[i],e[i]),8);
Jean-Marc Valinfeca0952010-06-17 20:25:51 -04001463 /* This checks for an "explosion" in the synthesis */
1464#ifdef FIXED_POINT
1465 if (!(S1 > SHR32(S2,2)))
1466#else
1467 /* Float test is written this way to catch NaNs at the same time */
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05001468 if (!(S1 > 0.2f*S2))
Jean-Marc Valinfeca0952010-06-17 20:25:51 -04001469#endif
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05001470 {
1471 for (i=0;i<len+overlap;i++)
1472 e[i] = 0;
1473 } else if (S1 < S2)
1474 {
Jean-Marc Valin12996402010-08-04 09:13:24 -04001475 celt_word16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001476 for (i=0;i<len+overlap;i++)
Jean-Marc Valinfeca0952010-06-17 20:25:51 -04001477 e[i] = MULT16_16_Q15(ratio, e[i]);
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05001478 }
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001479 }
1480
1481 for (i=0;i<MAX_PERIOD+st->mode->overlap-N;i++)
Jean-Marc Valin903dbf72010-08-26 20:06:49 -04001482 st->out_mem[c][i] = st->out_mem[c][N+i];
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001483
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001484 /* Apply TDAC to the concealed audio so that it blends with the
1485 previous and next frames */
1486 for (i=0;i<overlap/2;i++)
1487 {
Jean-Marc Valind69c1cb2009-12-28 00:34:29 -05001488 celt_word32 tmp1, tmp2;
1489 tmp1 = MULT16_32_Q15(st->mode->window[i ], e[i ]) -
1490 MULT16_32_Q15(st->mode->window[overlap-i-1], e[overlap-i-1]);
1491 tmp2 = MULT16_32_Q15(st->mode->window[i], e[N+overlap-1-i]) +
1492 MULT16_32_Q15(st->mode->window[overlap-i-1], e[N+i ]);
1493 tmp1 = MULT16_32_Q15(fade, tmp1);
1494 tmp2 = MULT16_32_Q15(fade, tmp2);
Jean-Marc Valin903dbf72010-08-26 20:06:49 -04001495 st->out_mem[c][MAX_PERIOD+i] = MULT16_32_Q15(st->mode->window[overlap-i-1], tmp2);
1496 st->out_mem[c][MAX_PERIOD+overlap-i-1] = MULT16_32_Q15(st->mode->window[i], tmp2);
1497 st->out_mem[c][MAX_PERIOD-N+i] += MULT16_32_Q15(st->mode->window[i], tmp1);
1498 st->out_mem[c][MAX_PERIOD-N+overlap-i-1] -= MULT16_32_Q15(st->mode->window[overlap-i-1], tmp1);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001499 }
1500 for (i=0;i<N-overlap;i++)
Jean-Marc Valin903dbf72010-08-26 20:06:49 -04001501 st->out_mem[c][MAX_PERIOD-N+overlap+i] = MULT16_32_Q15(fade, e[overlap+i]);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001502 }
Jean-Marc Valin1677aa92007-12-08 01:13:34 +11001503
Jean-Marc Valinaf1fce92010-07-16 11:05:06 -04001504 deemphasis(st->out_mem, pcm, N, C, st->mode->preemph, st->preemph_memD);
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001505
1506 st->loss_count++;
1507
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001508 RESTORE_STACK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001509}
1510
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001511#ifdef FIXED_POINT
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001512int celt_decode_with_ec(CELTDecoder * restrict st, const unsigned char *data, int len, celt_int16 * restrict pcm, int frame_size, ec_dec *dec)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001513{
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001514#else
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001515int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *data, int len, celt_sig * restrict pcm, int frame_size, ec_dec *dec)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001516{
1517#endif
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001518 int c, i, N, N4;
Jean-Marc Valin8cbea172010-08-05 15:22:57 -04001519 int has_fold;
Jean-Marc Valinc890b582008-08-01 22:26:49 -04001520 int bits;
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001521 ec_dec _dec;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11001522 ec_byte_buffer buf;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001523 VARDECL(celt_sig, freq);
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001524 VARDECL(celt_norm, X);
1525 VARDECL(celt_ener, bandE);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001526 VARDECL(int, fine_quant);
1527 VARDECL(int, pulses);
1528 VARDECL(int, offsets);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04001529 VARDECL(int, fine_priority);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -04001530 VARDECL(int, tf_res);
Jean-Marc Valinc890b582008-08-01 22:26:49 -04001531
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +10001532 int shortBlocks;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001533 int isTransient;
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -04001534 int intra_ener;
Jean-Marc Valin12b22482008-06-16 14:13:05 +10001535 int transient_time;
Jean-Marc Valin528f4b82008-06-29 03:46:39 +10001536 int transient_shift;
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001537 int mdct_weight_shift=0;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001538 const int C = CHANNELS(st->channels);
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001539 int mdct_weight_pos=0;
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001540 int LM, M;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04001541 int nbFilledBytes, nbAvailableBytes;
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001542 int effEnd;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001543 SAVE_STACK;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001544
Gregory Maxwell17169992009-06-04 15:15:34 -04001545 if (check_decoder(st) != CELT_OK)
1546 return CELT_INVALID_STATE;
1547
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001548 if (check_mode(st->mode) != CELT_OK)
1549 return CELT_INVALID_MODE;
1550
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001551 if (pcm==NULL)
1552 return CELT_BAD_ARG;
1553
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001554 for (LM=0;LM<4;LM++)
1555 if (st->mode->shortMdctSize<<LM==frame_size)
1556 break;
1557 if (LM>=MAX_CONFIG_SIZES)
1558 return CELT_BAD_ARG;
1559 M=1<<LM;
1560
Jean-Marc Valin04752672010-05-05 07:21:21 -04001561 N = M*st->mode->shortMdctSize;
Jean-Marc Valina536f772008-03-22 09:01:50 +11001562 N4 = (N-st->overlap)>>1;
Jean-Marc Valin01417232008-03-03 13:59:55 +11001563
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001564 effEnd = st->end;
1565 if (effEnd > st->mode->effEBands)
1566 effEnd = st->mode->effEBands;
1567
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001568 ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
1569 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
1570 ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001571 for (c=0;c<C;c++)
1572 for (i=0;i<M*st->mode->eBands[st->start];i++)
1573 X[c*N+i] = 0;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001574 for (c=0;c<C;c++)
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001575 for (i=M*st->mode->eBands[effEnd];i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001576 X[c*N+i] = 0;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001577
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001578 if (data == NULL)
1579 {
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001580 celt_decode_lost(st, pcm, N, LM);
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001581 RESTORE_STACK;
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001582 return CELT_OK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001583 }
Gregory Maxwell520eeae2009-02-09 01:33:21 -05001584 if (len<0) {
1585 RESTORE_STACK;
1586 return CELT_BAD_ARG;
1587 }
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001588
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001589 if (dec == NULL)
1590 {
1591 ec_byte_readinit(&buf,(unsigned char*)data,len);
1592 ec_dec_init(&_dec,&buf);
1593 dec = &_dec;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04001594 nbFilledBytes = 0;
1595 } else {
Jean-Marc Valinbdcaaf72010-07-05 13:52:41 -04001596 nbFilledBytes = (ec_dec_tell(dec, 0)+4)>>3;
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001597 }
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04001598 nbAvailableBytes = len-nbFilledBytes;
1599
Jean-Marc Valin017001a2010-08-05 15:42:50 -04001600 /* Decode the global flags (first symbols in the stream) */
1601 intra_ener = ec_dec_bit_prob(dec, 8192);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001602 /* Get band energies */
1603 unquant_coarse_energy(st->mode, st->start, st->end, bandE, st->oldBandE, intra_ener, st->mode->prob, dec, C, LM);
1604
Jean-Marc Valin017001a2010-08-05 15:42:50 -04001605 isTransient = ec_dec_bit_prob(dec, 8192);
Jean-Marc Valin017001a2010-08-05 15:42:50 -04001606
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001607 if (isTransient)
1608 shortBlocks = M;
1609 else
1610 shortBlocks = 0;
1611
1612 if (isTransient)
Gregory Maxwell0527f372008-09-23 19:28:35 -04001613 {
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001614 transient_shift = ec_dec_uint(dec, 4);
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001615 if (transient_shift == 3)
1616 {
Jean-Marc Valin0be05b02010-07-16 14:23:03 -04001617 int transient_time_quant;
1618 int max_time = (N+st->mode->overlap)*(celt_int32)8000/st->mode->Fs;
1619 transient_time_quant = ec_dec_uint(dec, max_time);
1620 transient_time = transient_time_quant*(celt_int32)st->mode->Fs/8000;
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001621 } else {
1622 mdct_weight_shift = transient_shift;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001623 if (mdct_weight_shift && M>2)
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001624 mdct_weight_pos = ec_dec_uint(dec, M-1);
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001625 transient_shift = 0;
Gregory Maxwell0527f372008-09-23 19:28:35 -04001626 transient_time = 0;
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001627 }
Gregory Maxwell0527f372008-09-23 19:28:35 -04001628 } else {
Jean-Marc Valin12b22482008-06-16 14:13:05 +10001629 transient_time = -1;
Jean-Marc Valin528f4b82008-06-29 03:46:39 +10001630 transient_shift = 0;
Jean-Marc Valin12b22482008-06-16 14:13:05 +10001631 }
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04001632
1633 ALLOC(tf_res, st->mode->nbEBands, int);
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -04001634 tf_decode(st->start, st->end, C, isTransient, tf_res, nbAvailableBytes, LM, dec);
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04001635
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001636 has_fold = ec_dec_bit_prob(dec, 8192)<<1;
1637 has_fold |= ec_dec_bit_prob(dec, (has_fold>>1) ? 32768 : 49152);
1638
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001639 ALLOC(pulses, st->mode->nbEBands, int);
1640 ALLOC(offsets, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04001641 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001642
1643 for (i=0;i<st->mode->nbEBands;i++)
1644 offsets[i] = 0;
1645
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001646 bits = len*8 - ec_dec_tell(dec, 0) - 1;
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001647 ALLOC(fine_quant, st->mode->nbEBands, int);
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001648 compute_allocation(st->mode, st->start, st->end, offsets, bits, pulses, fine_quant, fine_priority, C, M);
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001649 /*bits = ec_dec_tell(dec, 0);
1650 compute_fine_allocation(st->mode, fine_quant, (20*C+len*8/5-(ec_dec_tell(dec, 0)-bits))/C);*/
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001651
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001652 unquant_fine_energy(st->mode, st->start, st->end, bandE, st->oldBandE, fine_quant, dec, C);
Jean-Marc Valin827f9312008-05-06 23:21:55 +10001653
Jean-Marc Valin8cbea172010-08-05 15:22:57 -04001654 /* Decode fixed codebook */
Jean-Marc Valin8952c452010-07-16 21:48:44 -04001655 quant_all_bands(0, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, NULL, pulses, shortBlocks, has_fold, tf_res, 1, len*8, dec, LM);
Jean-Marc Valin746b2a82010-05-14 22:12:33 -04001656
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001657 unquant_energy_finalise(st->mode, st->start, st->end, bandE, st->oldBandE, fine_quant, fine_priority, len*8-ec_dec_tell(dec, 0), dec, C);
Jean-Marc Valin30d51252010-06-21 17:55:28 -04001658
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04001659 log2Amp(st->mode, st->start, st->end, bandE, st->oldBandE, C);
1660
Jean-Marc Valin88619552009-10-04 21:35:36 -04001661 if (mdct_weight_shift)
1662 {
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001663 mdct_shape(st->mode, X, 0, mdct_weight_pos+1, N, mdct_weight_shift, effEnd, C, 1, M);
Jean-Marc Valin88619552009-10-04 21:35:36 -04001664 }
1665
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11001666 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001667 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11001668
Jean-Marc Valin903dbf72010-08-26 20:06:49 -04001669 CELT_MOVE(st->decode_mem[0], st->decode_mem[0]+N, DECODE_BUFFER_SIZE+st->overlap-N);
1670 if (C==2)
1671 CELT_MOVE(st->decode_mem[1], st->decode_mem[1]+N, DECODE_BUFFER_SIZE+st->overlap-N);
Jean-Marc Valin88619552009-10-04 21:35:36 -04001672
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001673 for (c=0;c<C;c++)
1674 for (i=0;i<M*st->mode->eBands[st->start];i++)
1675 freq[c*N+i] = 0;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001676 for (c=0;c<C;c++)
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001677 for (i=M*st->mode->eBands[effEnd];i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001678 freq[c*N+i] = 0;
Jean-Marc Valin3a0bc3d2010-02-21 15:10:22 -05001679
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001680 /* Compute inverse MDCTs */
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001681 compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem, C, LM);
Jean-Marc Valinffa13472007-12-10 16:54:17 +11001682
Jean-Marc Valinaf1fce92010-07-16 11:05:06 -04001683 deemphasis(st->out_mem, pcm, N, C, st->mode->preemph, st->preemph_memD);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001684 st->loss_count = 0;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001685 RESTORE_STACK;
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001686 if (ec_dec_get_error(dec))
1687 return CELT_CORRUPTED_DATA;
1688 else
1689 return CELT_OK;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001690}
1691
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001692#ifdef FIXED_POINT
1693#ifndef DISABLE_FLOAT_API
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001694int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size, ec_dec *dec)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001695{
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001696 int j, ret, C, N, LM, M;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001697 VARDECL(celt_int16, out);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -04001698 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001699
1700 if (check_decoder(st) != CELT_OK)
1701 return CELT_INVALID_STATE;
1702
1703 if (check_mode(st->mode) != CELT_OK)
1704 return CELT_INVALID_MODE;
1705
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001706 if (pcm==NULL)
1707 return CELT_BAD_ARG;
1708
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001709 for (LM=0;LM<4;LM++)
1710 if (st->mode->shortMdctSize<<LM==frame_size)
1711 break;
1712 if (LM>=MAX_CONFIG_SIZES)
1713 return CELT_BAD_ARG;
1714 M=1<<LM;
1715
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001716 C = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001717 N = M*st->mode->shortMdctSize;
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001718
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001719 ALLOC(out, C*N, celt_int16);
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001720 ret=celt_decode_with_ec(st, data, len, out, frame_size, dec);
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001721 if (ret==0)
1722 for (j=0;j<C*N;j++)
Jean-Marc Valinae01e112010-08-03 21:43:41 -04001723 pcm[j]=out[j]*(1.f/32768.f);
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001724
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001725 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001726 return ret;
1727}
1728#endif /*DISABLE_FLOAT_API*/
1729#else
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001730int celt_decode_with_ec(CELTDecoder * restrict st, const unsigned char *data, int len, celt_int16 * restrict pcm, int frame_size, ec_dec *dec)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001731{
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001732 int j, ret, C, N, LM, M;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001733 VARDECL(celt_sig, out);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -04001734 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001735
1736 if (check_decoder(st) != CELT_OK)
1737 return CELT_INVALID_STATE;
1738
1739 if (check_mode(st->mode) != CELT_OK)
1740 return CELT_INVALID_MODE;
1741
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001742 if (pcm==NULL)
1743 return CELT_BAD_ARG;
1744
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001745 for (LM=0;LM<4;LM++)
1746 if (st->mode->shortMdctSize<<LM==frame_size)
1747 break;
1748 if (LM>=MAX_CONFIG_SIZES)
1749 return CELT_BAD_ARG;
1750 M=1<<LM;
1751
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001752 C = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001753 N = M*st->mode->shortMdctSize;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001754 ALLOC(out, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001755
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001756 ret=celt_decode_with_ec_float(st, data, len, out, frame_size, dec);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001757
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001758 if (ret==0)
1759 for (j=0;j<C*N;j++)
1760 pcm[j] = FLOAT2INT16 (out[j]);
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001761
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001762 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001763 return ret;
1764}
1765#endif
John Ridges454d1d02009-05-21 22:38:39 -04001766
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001767int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, celt_int16 * restrict pcm, int frame_size)
1768{
1769 return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL);
1770}
1771
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001772#ifndef DISABLE_FLOAT_API
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001773int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size)
1774{
1775 return celt_decode_with_ec_float(st, data, len, pcm, frame_size, NULL);
1776}
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001777#endif /* DISABLE_FLOAT_API */
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001778
John Ridges454d1d02009-05-21 22:38:39 -04001779int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
1780{
1781 va_list ap;
Gregory Maxwell17169992009-06-04 15:15:34 -04001782
1783 if (check_decoder(st) != CELT_OK)
1784 return CELT_INVALID_STATE;
1785
John Ridges454d1d02009-05-21 22:38:39 -04001786 va_start(ap, request);
Gregory Maxwell17169992009-06-04 15:15:34 -04001787 if ((request!=CELT_GET_MODE_REQUEST) && (check_mode(st->mode) != CELT_OK))
1788 goto bad_mode;
John Ridges454d1d02009-05-21 22:38:39 -04001789 switch (request)
1790 {
Gregory Maxwellf3b44ef2009-06-03 13:37:45 -04001791 case CELT_GET_MODE_REQUEST:
1792 {
1793 const CELTMode ** value = va_arg(ap, const CELTMode**);
1794 if (value==0)
1795 goto bad_arg;
1796 *value=st->mode;
1797 }
1798 break;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001799 case CELT_SET_START_BAND_REQUEST:
1800 {
1801 celt_int32 value = va_arg(ap, celt_int32);
1802 if (value<0 || value>=st->mode->nbEBands)
1803 goto bad_arg;
1804 st->start = value;
1805 }
1806 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001807 case CELT_SET_END_BAND_REQUEST:
1808 {
1809 celt_int32 value = va_arg(ap, celt_int32);
1810 if (value<0 || value>=st->mode->nbEBands)
1811 goto bad_arg;
1812 st->end = value;
1813 }
1814 break;
John Ridges454d1d02009-05-21 22:38:39 -04001815 case CELT_RESET_STATE:
1816 {
1817 const CELTMode *mode = st->mode;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001818 int C = st->channels;
John Ridges454d1d02009-05-21 22:38:39 -04001819
1820 CELT_MEMSET(st->decode_mem, 0, (DECODE_BUFFER_SIZE+st->overlap)*C);
1821 CELT_MEMSET(st->oldBandE, 0, C*mode->nbEBands);
1822
1823 CELT_MEMSET(st->preemph_memD, 0, C);
1824
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001825 st->loss_count = 0;
John Ridges5378bf82010-02-12 07:08:01 -05001826
John Ridges5378bf82010-02-12 07:08:01 -05001827 CELT_MEMSET(st->lpc, 0, C*LPC_ORDER);
John Ridges454d1d02009-05-21 22:38:39 -04001828 }
1829 break;
1830 default:
1831 goto bad_request;
1832 }
1833 va_end(ap);
1834 return CELT_OK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001835bad_mode:
1836 va_end(ap);
1837 return CELT_INVALID_MODE;
John Ridges454d1d02009-05-21 22:38:39 -04001838bad_arg:
1839 va_end(ap);
1840 return CELT_BAD_ARG;
John Ridges454d1d02009-05-21 22:38:39 -04001841bad_request:
1842 va_end(ap);
1843 return CELT_UNIMPLEMENTED;
1844}
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001845
1846const char *celt_strerror(int error)
1847{
1848 static const char *error_strings[8] = {
1849 "success",
1850 "invalid argument",
1851 "invalid mode",
1852 "internal error",
1853 "corrupted stream",
1854 "request not implemented",
1855 "invalid state",
1856 "memory allocation failed"
1857 };
1858 if (error > 0 || error < -7)
1859 return "unknown error";
1860 else
1861 return error_strings[-error];
1862}
1863