blob: feaa480fe7236a5ea962009a8241355920788eae [file] [log] [blame]
Jean-Marc Valin8b2ff0d2009-10-17 21:40:10 -04001/* Copyright (c) 2007-2008 CSIRO
Jean-Marc Valin190b7822010-08-27 15:03:20 -04002 Copyright (c) 2007-2010 Xiph.Org Foundation
Jean-Marc Valin8b2ff0d2009-10-17 21:40:10 -04003 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
Jean-Marc Valin6bf04622010-09-30 10:16:22 -040068static const int trim_cdf[7] = {0, 4, 10, 23, 119, 125, 128};
69static const int trim_coef[6] = {4, 6, 7, 8, 10, 12};
70
Jean-Marc Valin276de722008-02-20 17:45:51 +110071/** Encoder state
72 @brief Encoder state
73 */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +110074struct CELTEncoder {
Jean-Marc Valin276de722008-02-20 17:45:51 +110075 const CELTMode *mode; /**< Mode used by the encoder */
Jean-Marc Valina5431bf2008-01-03 20:53:01 +110076 int overlap;
Jean-Marc Valinffa13472007-12-10 16:54:17 +110077 int channels;
78
Gregory Maxwell2dd3d322009-06-05 14:05:51 -040079 int force_intra;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -040080 int complexity;
Jean-Marc Valinc09807d2010-08-27 17:17:50 -040081 int start, end;
82
83 celt_int32 vbr_rate_norm; /* Target number of 16th bits per frame */
84
85 /* Everything beyond this point gets cleared on a reset */
86#define ENCODER_RESET_START frame_max
87
88 celt_word32 frame_max;
89 int fold_decision;
Jean-Marc Valin74f4e9f2009-05-02 09:57:50 -040090 int delayedIntra;
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -040091 int tonal_average;
Jean-Marc Valin527db5c2009-06-02 07:56:19 -040092
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -040093 /* VBR-related parameters */
94 celt_int32 vbr_reservoir;
95 celt_int32 vbr_drift;
96 celt_int32 vbr_offset;
97 celt_int32 vbr_count;
98
Jean-Marc Valinac1da4f2010-07-24 11:48:10 -040099 celt_word32 preemph_memE[2];
100 celt_word32 preemph_memD[2];
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100101
Jean-Marc Valinca8b9922010-08-27 16:23:03 -0400102 celt_sig in_mem[1]; /* Size = channels*mode->overlap */
103 /* celt_sig overlap_mem[], Size = channels*mode->overlap */
104 /* celt_word16 oldEBands[], Size = channels*mode->nbEBands */
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100105};
106
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400107int celt_encoder_get_size(const CELTMode *mode, int channels)
108{
109 int size = sizeof(struct CELTEncoder)
110 + (2*channels*mode->overlap-1)*sizeof(celt_sig)
111 + channels*mode->nbEBands*sizeof(celt_word16);
112 return size;
113}
114
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400115CELTEncoder *celt_encoder_create(const CELTMode *mode, int channels, int *error)
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100116{
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -0400117 return celt_encoder_init(
118 (CELTEncoder *)celt_alloc(celt_encoder_get_size(mode, channels)),
119 mode, channels, error);
120}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100121
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -0400122CELTEncoder *celt_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels, int *error)
123{
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400124 if (channels < 0 || channels > 2)
125 {
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400126 if (error)
127 *error = CELT_BAD_ARG;
128 return NULL;
129 }
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100130
Jean-Marc Valinece94a02009-10-16 07:30:14 -0400131 if (st==NULL)
132 {
133 if (error)
134 *error = CELT_ALLOC_FAIL;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400135 return NULL;
Jean-Marc Valinece94a02009-10-16 07:30:14 -0400136 }
Jean-Marc Valin6d3829f2010-08-27 17:52:38 -0400137
138 CELT_MEMSET((char*)st, 0, celt_encoder_get_size(mode, channels));
139
Jean-Marc Valin73e51b32007-12-05 17:48:24 +1100140 st->mode = mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100141 st->overlap = mode->overlap;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400142 st->channels = channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100143
Jean-Marc Valin5f961462010-05-19 13:38:10 -0400144 st->start = 0;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400145 st->end = st->mode->effEBands;
Jean-Marc Valin5f961462010-05-19 13:38:10 -0400146
Jean-Marc Valin8cc945c2010-05-29 08:07:18 -0400147 st->vbr_rate_norm = 0;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -0400148 st->force_intra = 0;
Gregory Maxwell8842fde2009-05-04 15:58:40 -0400149 st->delayedIntra = 1;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400150 st->tonal_average = 256;
Jean-Marc Valin527db5c2009-06-02 07:56:19 -0400151 st->fold_decision = 1;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400152 st->complexity = 5;
Jean-Marc Valina76a0b22008-01-17 22:43:05 +1100153
Jean-Marc Valinece94a02009-10-16 07:30:14 -0400154 if (error)
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400155 *error = CELT_OK;
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400156 return st;
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100157}
158
Peter Kirk19f9dc92008-06-06 14:38:38 +0200159void celt_encoder_destroy(CELTEncoder *st)
Jean-Marc Valin14191b32007-11-30 12:15:49 +1100160{
Jean-Marc Valin14191b32007-11-30 12:15:49 +1100161 celt_free(st);
162}
163
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400164static inline celt_int16 FLOAT2INT16(float x)
Jean-Marc Valin42074382008-02-27 11:08:53 +1100165{
Gregory Maxwell0ac2b2f2009-05-21 23:08:46 -0400166 x = x*CELT_SIG_SCALE;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400167 x = MAX32(x, -32768);
168 x = MIN32(x, 32767);
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400169 return (celt_int16)float2int(x);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400170}
171
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400172static inline celt_word16 SIG2WORD16(celt_sig x)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400173{
174#ifdef FIXED_POINT
Jean-Marc Valin42074382008-02-27 11:08:53 +1100175 x = PSHR32(x, SIG_SHIFT);
Jean-Marc Valinabdfc382008-04-18 15:57:18 +1000176 x = MAX32(x, -32768);
177 x = MIN32(x, 32767);
Jean-Marc Valin42074382008-02-27 11:08:53 +1100178 return EXTRACT16(x);
179#else
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400180 return (celt_word16)x;
Jean-Marc Valin42074382008-02-27 11:08:53 +1100181#endif
182}
183
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400184static int transient_analysis(const celt_word32 * restrict in, int len, int C,
185 int *transient_time, int *transient_shift,
Jean-Marc Valinbdb58712010-05-28 18:58:42 -0400186 celt_word32 *frame_max, int overlap)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000187{
Jean-Marc Valinbdb58712010-05-28 18:58:42 -0400188 int i, n;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400189 celt_word32 ratio;
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400190 celt_word32 threshold;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400191 VARDECL(celt_word32, begin);
Jean-Marc Valin0ceccb22008-07-03 20:41:06 -0400192 SAVE_STACK;
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400193 ALLOC(begin, len+1, celt_word32);
194 begin[0] = 0;
195 if (C==1)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000196 {
197 for (i=0;i<len;i++)
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400198 begin[i+1] = MAX32(begin[i], ABS32(in[i]));
199 } else {
200 for (i=0;i<len;i++)
201 begin[i+1] = MAX32(begin[i], MAX32(ABS32(in[C*i]),
202 ABS32(in[C*i+1])));
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000203 }
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000204 n = -1;
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400205
Jean-Marc Valine34c85a2010-07-15 17:57:50 -0400206 threshold = MULT16_32_Q15(QCONST16(.4f,15),begin[len]);
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400207 /* If the following condition isn't met, there's just no way
208 we'll have a transient*/
209 if (*frame_max < threshold)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000210 {
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400211 /* It's likely we have a transient, now find it */
212 for (i=8;i<len-8;i++)
213 {
214 if (begin[i+1] < threshold)
215 n=i;
216 }
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000217 }
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000218 if (n<32)
219 {
220 n = -1;
221 ratio = 0;
Jean-Marc Valinbd7de0a2008-07-06 10:57:26 -0400222 } else {
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400223 ratio = DIV32(begin[len],1+MAX32(*frame_max, begin[n-16]));
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000224 }
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400225
Jean-Marc Valin816f8932010-05-31 21:35:40 -0400226 if (ratio > 45)
Jean-Marc Valinbd7de0a2008-07-06 10:57:26 -0400227 *transient_shift = 3;
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400228 else
229 *transient_shift = 0;
230
Jean-Marc Valinbd7de0a2008-07-06 10:57:26 -0400231 *transient_time = n;
Jean-Marc Valinbdb58712010-05-28 18:58:42 -0400232 *frame_max = begin[len-overlap];
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400233
Jean-Marc Valin0ceccb22008-07-03 20:41:06 -0400234 RESTORE_STACK;
Jean-Marc Valine34c85a2010-07-15 17:57:50 -0400235 return ratio > 0;
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000236}
237
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400238/** Apply window and compute the MDCT for all sub-frames and
239 all channels in a frame */
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400240static 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 +1100241{
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400242 const int C = CHANNELS(_C);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000243 if (C==1 && !shortBlocks)
Jean-Marc Valinda721882007-11-30 15:17:42 +1100244 {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000245 const int overlap = OVERLAP(mode);
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400246 clt_mdct_forward(&mode->mdct, in, out, mode->window, overlap, mode->maxLM-LM);
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400247 } else {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000248 const int overlap = OVERLAP(mode);
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400249 int N = mode->shortMdctSize<<LM;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400250 int B = 1;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000251 int b, c;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400252 VARDECL(celt_word32, x);
253 VARDECL(celt_word32, tmp);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000254 SAVE_STACK;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400255 if (shortBlocks)
256 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400257 /*lookup = &mode->mdct[0];*/
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400258 N = mode->shortMdctSize;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400259 B = shortBlocks;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400260 }
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400261 ALLOC(x, N+overlap, celt_word32);
262 ALLOC(tmp, N, celt_word32);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000263 for (c=0;c<C;c++)
264 {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000265 for (b=0;b<B;b++)
266 {
267 int j;
268 for (j=0;j<N+overlap;j++)
269 x[j] = in[C*(b*N+j)+c];
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400270 clt_mdct_forward(&mode->mdct, x, tmp, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000271 /* Interleaving the sub-frames */
272 for (j=0;j<N;j++)
Jean-Marc Valin08a82ff2009-06-14 14:05:19 -0400273 out[(j*B+b)+c*N*B] = tmp[j];
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000274 }
275 }
276 RESTORE_STACK;
Jean-Marc Valinda721882007-11-30 15:17:42 +1100277 }
Jean-Marc Valinda721882007-11-30 15:17:42 +1100278}
279
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400280/** Compute the IMDCT and apply window for all sub-frames and
281 all channels in a frame */
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400282static void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig *X,
283 int transient_time, int transient_shift, celt_sig * restrict out_mem[],
284 celt_sig * restrict overlap_mem[], int _C, int LM)
Jean-Marc Valin1677aa92007-12-08 01:13:34 +1100285{
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -0400286 int c;
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400287 const int C = CHANNELS(_C);
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400288 const int N = mode->shortMdctSize<<LM;
Jean-Marc Valinb18ec0b2008-04-11 04:07:52 +1000289 const int overlap = OVERLAP(mode);
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100290 for (c=0;c<C;c++)
Jean-Marc Valin1677aa92007-12-08 01:13:34 +1100291 {
Jean-Marc Valinb886ddc2008-03-25 14:38:55 +1100292 int j;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400293 VARDECL(celt_word32, x);
294 VARDECL(celt_word32, tmp);
Jean-Marc Valinde678582009-10-03 10:36:27 -0400295 int b;
296 int N2 = N;
297 int B = 1;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000298 SAVE_STACK;
Jean-Marc Valinde678582009-10-03 10:36:27 -0400299
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400300 ALLOC(x, N+overlap, celt_word32);
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400301 ALLOC(tmp, N, celt_word32);
Jean-Marc Valinde678582009-10-03 10:36:27 -0400302
303 if (shortBlocks)
304 {
Jean-Marc Valinde678582009-10-03 10:36:27 -0400305 N2 = mode->shortMdctSize;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400306 B = shortBlocks;
Jean-Marc Valinde678582009-10-03 10:36:27 -0400307 }
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000308 /* Prevents problems from the imdct doing the overlap-add */
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400309 CELT_MEMSET(x, 0, overlap);
Jean-Marc Valinde678582009-10-03 10:36:27 -0400310
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000311 for (b=0;b<B;b++)
312 {
313 /* De-interleaving the sub-frames */
314 for (j=0;j<N2;j++)
Jean-Marc Valin08a82ff2009-06-14 14:05:19 -0400315 tmp[j] = X[(j*B+b)+c*N2*B];
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400316 clt_mdct_backward(&mode->mdct, tmp, x+N2*b, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000317 }
Jean-Marc Valinde678582009-10-03 10:36:27 -0400318
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000319 if (transient_shift > 0)
Jean-Marc Valin12b22482008-06-16 14:13:05 +1000320 {
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000321#ifdef FIXED_POINT
Jean-Marc Valin12b22482008-06-16 14:13:05 +1000322 for (j=0;j<16;j++)
Jean-Marc Valind13cd152010-08-27 16:05:01 -0400323 x[transient_time+j-16] = MULT16_32_Q15(SHR16(Q15_ONE-transientWindow[j],transient_shift)+transientWindow[j], SHL32(x[transient_time+j-16],transient_shift));
Jean-Marc Valin12b22482008-06-16 14:13:05 +1000324 for (j=transient_time;j<N+overlap;j++)
Jean-Marc Valind13cd152010-08-27 16:05:01 -0400325 x[j] = SHL32(x[j], transient_shift);
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000326#else
327 for (j=0;j<16;j++)
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400328 x[transient_time+j-16] *= 1+transientWindow[j]*((1<<transient_shift)-1);
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000329 for (j=transient_time;j<N+overlap;j++)
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400330 x[j] *= 1<<transient_shift;
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000331#endif
Jean-Marc Valin12b22482008-06-16 14:13:05 +1000332 }
Jean-Marc Valin8ddd7f42008-04-22 13:37:16 +1000333 for (j=0;j<overlap;j++)
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400334 out_mem[c][j] = x[j] + overlap_mem[c][j];
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400335 for (;j<N;j++)
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400336 out_mem[c][j] = x[j];
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400337 for (j=0;j<overlap;j++)
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400338 overlap_mem[c][j] = x[N+j];
Jean-Marc Valin8ddd7f42008-04-22 13:37:16 +1000339 RESTORE_STACK;
Jean-Marc Valin1677aa92007-12-08 01:13:34 +1100340 }
341}
342
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400343static 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 -0400344{
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400345 const int C = CHANNELS(_C);
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400346 int c;
347 for (c=0;c<C;c++)
348 {
349 int j;
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400350 celt_sig * restrict x;
351 celt_word16 * restrict y;
352 celt_sig m = mem[c];
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400353 x =in[c];
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400354 y = pcm+c;
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400355 for (j=0;j<N;j++)
356 {
Jean-Marc Valinaf1fce92010-07-16 11:05:06 -0400357 celt_sig tmp = *x + m;
358 m = MULT16_32_Q15(coef[0], tmp)
359 - MULT16_32_Q15(coef[1], *x);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400360 tmp = SHL32(MULT16_32_Q15(coef[3], tmp), 2);
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400361 *y = SCALEOUT(SIG2WORD16(tmp));
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400362 x++;
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400363 y+=C;
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400364 }
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400365 mem[c] = m;
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400366 }
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400367}
368
Jean-Marc Valind6b79ee2010-04-20 17:31:45 -0400369static void mdct_shape(const CELTMode *mode, celt_norm *X, int start,
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400370 int end, int N,
Jean-Marc Valin69921c42010-07-16 15:25:30 -0400371 int mdct_weight_shift, int end_band, int _C, int renorm, int M)
Jean-Marc Valin88619552009-10-04 21:35:36 -0400372{
373 int m, i, c;
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400374 const int C = CHANNELS(_C);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400375 for (c=0;c<C;c++)
376 for (m=start;m<end;m++)
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400377 for (i=m+c*N;i<(c+1)*N;i+=M)
Jean-Marc Valin88619552009-10-04 21:35:36 -0400378#ifdef FIXED_POINT
379 X[i] = SHR16(X[i], mdct_weight_shift);
380#else
381 X[i] = (1.f/(1<<mdct_weight_shift))*X[i];
382#endif
Jean-Marc Valind6b79ee2010-04-20 17:31:45 -0400383 if (renorm)
Jean-Marc Valin69921c42010-07-16 15:25:30 -0400384 renormalise_bands(mode, X, end_band, C, M);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400385}
386
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400387static const signed char tf_select_table[4][8] = {
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400388 {0, -1, 0, -1, 0,-1, 0,-1},
389 {0, -1, 0, -2, 1, 0, 1 -1},
390 {0, -2, 0, -3, 2, 0, 1 -1},
391 {0, -2, 0, -3, 2, 0, 1 -1},
392};
393
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400394static int tf_analysis(const CELTMode *m, celt_word16 *bandLogE, celt_word16 *oldBandE,
395 int len, int C, int isTransient, int *tf_res, int nbCompressedBytes, celt_norm *X, int N0, int LM)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400396{
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400397 int i;
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400398 VARDECL(int, metric);
399 int cost0;
400 int cost1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400401 VARDECL(int, path0);
402 VARDECL(int, path1);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400403 VARDECL(celt_norm, tmp);
404 int lambda;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400405 int tf_select=0;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400406 SAVE_STACK;
407
Jean-Marc Valin6bf3b0a2010-07-19 14:32:40 -0400408 /* FIXME: Should check number of bytes *left* */
409 if (nbCompressedBytes<15*C)
410 {
411 for (i=0;i<len;i++)
412 tf_res[i] = 0;
413 return 0;
414 }
Jean-Marc Valin73319772010-05-28 21:12:39 -0400415 if (nbCompressedBytes<40)
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400416 lambda = 10;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400417 else if (nbCompressedBytes<60)
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400418 lambda = 4;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400419 else if (nbCompressedBytes<100)
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400420 lambda = 2;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400421 else
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400422 lambda = 1;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400423
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400424 ALLOC(metric, len, int);
425 ALLOC(tmp, (m->eBands[len]-m->eBands[len-1])<<LM, celt_norm);
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400426 ALLOC(path0, len, int);
427 ALLOC(path1, len, int);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400428
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400429 for (i=0;i<len;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400430 {
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400431 int j, k, N;
432 celt_word32 L1, best_L1;
433 int best_level=0;
434 N = (m->eBands[i+1]-m->eBands[i])<<LM;
435 for (j=0;j<N;j++)
436 tmp[j] = X[j+(m->eBands[i]<<LM)];
437 if (C==2)
438 for (j=0;j<N;j++)
439 tmp[j] = ADD16(tmp[j],X[N0+j+(m->eBands[i]<<LM)]);
440 L1=0;
441 for (j=0;j<N;j++)
442 L1 += ABS16(tmp[j]);
443 /* Biasing towards better freq resolution (because of spreading) */
444 if (isTransient)
445 L1 += MULT16_32_Q15(QCONST16(.08,15), L1);
446 else
447 L1 -= MULT16_32_Q15(QCONST16(.08,15), L1);
448 best_L1 = L1;
449 /*printf ("%f ", L1);*/
450 for (k=0;k<LM;k++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400451 {
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400452 if (isTransient)
453 haar1(tmp, N>>(LM-k), 1<<(LM-k));
454 else
455 haar1(tmp, N>>k, 1<<k);
456
457 L1=0;
458 for (j=0;j<N;j++)
459 L1 += ABS16(tmp[j]);
460
461 /*printf ("%f ", L1);*/
462 if (L1 < best_L1)
463 {
464 best_L1 = L1;
465 best_level = k+1;
466 }
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400467 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400468 /*printf ("%d ", isTransient ? LM-best_level : best_level);*/
469 if (isTransient)
470 metric[i] = best_level;
471 else
472 metric[i] = -best_level;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400473 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400474 /*printf("\n");*/
475 /* FIXME: Figure out how to set this */
476 tf_select = 1;
477
Jean-Marc Valin88232612010-05-28 18:01:02 -0400478 cost0 = 0;
479 cost1 = lambda;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400480 /* Viterbi forward pass */
481 for (i=1;i<len;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400482 {
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400483 int curr0, curr1;
484 int from0, from1;
Jean-Marc Valin581fdba2010-05-28 06:56:23 -0400485
Jean-Marc Valin88232612010-05-28 18:01:02 -0400486 from0 = cost0;
487 from1 = cost1 + lambda;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400488 if (from0 < from1)
489 {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400490 curr0 = from0;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400491 path0[i]= 0;
492 } else {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400493 curr0 = from1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400494 path0[i]= 1;
495 }
496
Jean-Marc Valin88232612010-05-28 18:01:02 -0400497 from0 = cost0 + lambda;
498 from1 = cost1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400499 if (from0 < from1)
500 {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400501 curr1 = from0;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400502 path1[i]= 0;
503 } else {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400504 curr1 = from1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400505 path1[i]= 1;
506 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400507 cost0 = curr0 + abs(metric[i]-tf_select_table[LM][4*isTransient+2*tf_select+0]);
508 cost1 = curr1 + abs(metric[i]-tf_select_table[LM][4*isTransient+2*tf_select+1]);
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400509 }
Jean-Marc Valin88232612010-05-28 18:01:02 -0400510 tf_res[len-1] = cost0 < cost1 ? 0 : 1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400511 /* Viterbi backward pass to check the decisions */
512 for (i=len-2;i>=0;i--)
513 {
514 if (tf_res[i+1] == 1)
515 tf_res[i] = path1[i+1];
516 else
517 tf_res[i] = path0[i+1];
518 }
Jean-Marc Valin71ae6d42010-06-27 21:55:08 -0400519 RESTORE_STACK;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400520 return tf_select;
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400521}
522
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400523static 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 -0400524{
525 int curr, i;
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400526 ec_enc_bit_prob(enc, tf_res[start], isTransient ? 16384 : 4096);
527 curr = tf_res[start];
528 for (i=start+1;i<end;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400529 {
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400530 ec_enc_bit_prob(enc, tf_res[i] ^ curr, isTransient ? 4096 : 2048);
531 curr = tf_res[i];
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400532 }
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400533 ec_enc_bits(enc, tf_select, 1);
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400534 for (i=start;i<end;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400535 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400536 /*printf("%d %d ", isTransient, tf_select); for(i=0;i<end;i++)printf("%d ", tf_res[i]);printf("\n");*/
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400537}
538
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400539static 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 -0400540{
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400541 int i, curr, tf_select;
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400542 tf_res[start] = ec_dec_bit_prob(dec, isTransient ? 16384 : 4096);
543 curr = tf_res[start];
544 for (i=start+1;i<end;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400545 {
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400546 tf_res[i] = ec_dec_bit_prob(dec, isTransient ? 4096 : 2048) ^ curr;
547 curr = tf_res[i];
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400548 }
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400549 tf_select = ec_dec_bits(dec, 1);
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400550 for (i=start;i<end;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400551 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400552}
553
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400554#ifdef FIXED_POINT
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400555int 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 +1100556{
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400557#else
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400558int 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 -0400559{
560#endif
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -0400561 int i, c, N, NN;
Jean-Marc Valinc890b582008-08-01 22:26:49 -0400562 int bits;
Jean-Marc Valinbc799912008-11-07 22:53:13 -0500563 int has_fold=1;
Jean-Marc Valin8679a802008-10-18 07:44:35 -0400564 ec_byte_buffer buf;
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400565 ec_enc _enc;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400566 VARDECL(celt_sig, in);
567 VARDECL(celt_sig, freq);
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400568 VARDECL(celt_norm, X);
569 VARDECL(celt_ener, bandE);
570 VARDECL(celt_word16, bandLogE);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400571 VARDECL(int, fine_quant);
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400572 VARDECL(celt_word16, error);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400573 VARDECL(int, pulses);
574 VARDECL(int, offsets);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -0400575 VARDECL(int, fine_priority);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400576 VARDECL(int, tf_res);
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400577 celt_sig *_overlap_mem;
578 celt_word16 *oldBandE;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000579 int shortBlocks=0;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400580 int isTransient=0;
Jean-Marc Valin0be05b02010-07-16 14:23:03 -0400581 int transient_time, transient_time_quant;
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000582 int transient_shift;
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -0400583 int resynth;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400584 const int C = CHANNELS(st->channels);
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400585 int mdct_weight_shift = 0;
586 int mdct_weight_pos=0;
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400587 int LM, M;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400588 int tf_select;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400589 int nbFilledBytes, nbAvailableBytes;
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400590 int effEnd;
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400591 int codedBands;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -0400592 int alloc_trim;
Jean-Marc Valin8600f692008-02-29 15:14:12 +1100593 SAVE_STACK;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100594
Gregory Maxwell0719f6f2009-07-09 17:07:24 -0400595 if (nbCompressedBytes<0 || pcm==NULL)
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400596 return CELT_BAD_ARG;
Gregory Maxwell520eeae2009-02-09 01:33:21 -0500597
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400598 for (LM=0;LM<4;LM++)
599 if (st->mode->shortMdctSize<<LM==frame_size)
600 break;
601 if (LM>=MAX_CONFIG_SIZES)
602 return CELT_BAD_ARG;
603 M=1<<LM;
Jean-Marc Valin8679a802008-10-18 07:44:35 -0400604
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400605 _overlap_mem = st->in_mem+C*(st->overlap);
606 oldBandE = (celt_word16*)(st->in_mem+2*C*(st->overlap));
607
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400608 if (enc==NULL)
609 {
610 ec_byte_writeinit_buffer(&buf, compressed, nbCompressedBytes);
611 ec_enc_init(&_enc,&buf);
612 enc = &_enc;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400613 nbFilledBytes=0;
614 } else {
Jean-Marc Valinbdcaaf72010-07-05 13:52:41 -0400615 nbFilledBytes=(ec_enc_tell(enc, 0)+4)>>3;
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400616 }
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400617 nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
618
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400619 effEnd = st->end;
620 if (effEnd > st->mode->effEBands)
621 effEnd = st->mode->effEBands;
622
Jean-Marc Valin04752672010-05-05 07:21:21 -0400623 N = M*st->mode->shortMdctSize;
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -0400624 ALLOC(in, C*(N+st->overlap), celt_sig);
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100625
Jean-Marc Valinbdb58832008-04-20 17:42:10 +1000626 CELT_COPY(in, st->in_mem, C*st->overlap);
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100627 for (c=0;c<C;c++)
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +1100628 {
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400629 const celt_word16 * restrict pcmp = pcm+c;
630 celt_sig * restrict inp = in+C*st->overlap+c;
Jean-Marc Valinb886ddc2008-03-25 14:38:55 +1100631 for (i=0;i<N;i++)
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100632 {
Jean-Marc Valin62290062008-04-20 22:16:02 +1000633 /* Apply pre-emphasis */
Jean-Marc Valinaf1fce92010-07-16 11:05:06 -0400634 celt_sig tmp = MULT16_16(st->mode->preemph[2], SCALEIN(*pcmp));
635 *inp = tmp + st->preemph_memE[c];
636 st->preemph_memE[c] = MULT16_32_Q15(st->mode->preemph[1], *inp)
637 - MULT16_32_Q15(st->mode->preemph[0], tmp);
Jean-Marc Valin62290062008-04-20 22:16:02 +1000638 inp += C;
639 pcmp += C;
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100640 }
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +1100641 }
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -0400642 CELT_COPY(st->in_mem, in+C*N, C*st->overlap);
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400643
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -0500644 /* Transient handling */
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400645 transient_time = -1;
Jean-Marc Valin0be05b02010-07-16 14:23:03 -0400646 transient_time_quant = -1;
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400647 transient_shift = 0;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400648 isTransient = 0;
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400649
Jean-Marc Valin8cbea172010-08-05 15:22:57 -0400650 resynth = optional_resynthesis!=NULL;
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -0400651
Jean-Marc Valinf9fdbff2010-09-05 21:02:38 -0400652 if (st->complexity > 1 && LM>0)
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400653 {
654 isTransient = M > 1 &&
655 transient_analysis(in, N+st->overlap, C, &transient_time,
656 &transient_shift, &st->frame_max, st->overlap);
657 } else {
658 isTransient = 0;
659 }
660 if (isTransient)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000661 {
Jean-Marc Valin7028d622008-07-10 23:06:58 -0400662#ifndef FIXED_POINT
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400663 float gain_1;
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000664#endif
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400665 /* Apply the inverse shaping window */
666 if (transient_shift)
667 {
Jean-Marc Valin0be05b02010-07-16 14:23:03 -0400668 transient_time_quant = transient_time*(celt_int32)8000/st->mode->Fs;
669 transient_time = transient_time_quant*(celt_int32)st->mode->Fs/8000;
Jean-Marc Valin7028d622008-07-10 23:06:58 -0400670#ifdef FIXED_POINT
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400671 for (c=0;c<C;c++)
672 for (i=0;i<16;i++)
673 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]);
674 for (c=0;c<C;c++)
675 for (i=transient_time;i<N+st->overlap;i++)
676 in[C*i+c] = SHR32(in[C*i+c], transient_shift);
Jean-Marc Valin7028d622008-07-10 23:06:58 -0400677#else
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400678 for (c=0;c<C;c++)
679 for (i=0;i<16;i++)
680 in[C*(transient_time+i-16)+c] /= 1+transientWindow[i]*((1<<transient_shift)-1);
Jean-Marc Valin12996402010-08-04 09:13:24 -0400681 gain_1 = 1.f/(1<<transient_shift);
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400682 for (c=0;c<C;c++)
683 for (i=transient_time;i<N+st->overlap;i++)
684 in[C*i+c] *= gain_1;
Jean-Marc Valin7028d622008-07-10 23:06:58 -0400685#endif
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000686 }
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400687 has_fold = 1;
Jean-Marc Valin12b22482008-06-16 14:13:05 +1000688 }
Jean-Marc Valinc5f2a9d2008-10-26 22:00:26 -0400689
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400690 if (isTransient)
691 shortBlocks = M;
692 else
693 shortBlocks = 0;
694
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400695 ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
696 ALLOC(bandE,st->mode->nbEBands*C, celt_ener);
697 ALLOC(bandLogE,st->mode->nbEBands*C, celt_word16);
Jean-Marc Valin32ec58c2009-05-01 21:28:58 -0400698 /* Compute MDCTs */
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400699 compute_mdcts(st->mode, shortBlocks, in, freq, C, LM);
Jean-Marc Valin08a82ff2009-06-14 14:05:19 -0400700
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400701 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
Jean-Marc Valin8d4ac152008-02-29 17:24:02 +1100702
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400703 compute_band_energies(st->mode, freq, bandE, effEnd, C, M);
Jean-Marc Valin504fb3c2010-08-06 15:56:22 -0400704
705 amp2Log2(st->mode, effEnd, st->end, bandE, bandLogE, C);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400706
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100707 /* Band normalisation */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400708 normalise_bands(st->mode, freq, X, bandE, effEnd, C, M);
Jean-Marc Valin4c77ea92009-09-14 22:50:41 -0400709
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400710 NN = M*st->mode->eBands[effEnd];
Jean-Marc Valin9f89cab2010-05-21 14:18:38 -0400711 if (shortBlocks && !transient_shift)
Jean-Marc Valin88619552009-10-04 21:35:36 -0400712 {
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400713 celt_word32 sum[8]={1,1,1,1,1,1,1,1};
Jean-Marc Valin88619552009-10-04 21:35:36 -0400714 int m;
715 for (c=0;c<C;c++)
716 {
717 m=0;
718 do {
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400719 celt_word32 tmp=0;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400720 for (i=m+c*N;i<c*N+NN;i+=M)
Jean-Marc Valin88619552009-10-04 21:35:36 -0400721 tmp += ABS32(X[i]);
722 sum[m++] += tmp;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400723 } while (m<M);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400724 }
725 m=0;
726#ifdef FIXED_POINT
727 do {
728 if (SHR32(sum[m+1],3) > sum[m])
729 {
730 mdct_weight_shift=2;
731 mdct_weight_pos = m;
732 } else if (SHR32(sum[m+1],1) > sum[m] && mdct_weight_shift < 2)
733 {
734 mdct_weight_shift=1;
735 mdct_weight_pos = m;
736 }
737 m++;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400738 } while (m<M-1);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400739#else
740 do {
741 if (sum[m+1] > 8*sum[m])
742 {
743 mdct_weight_shift=2;
744 mdct_weight_pos = m;
745 } else if (sum[m+1] > 2*sum[m] && mdct_weight_shift < 2)
746 {
747 mdct_weight_shift=1;
748 mdct_weight_pos = m;
749 }
750 m++;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400751 } while (m<M-1);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400752#endif
753 if (mdct_weight_shift)
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400754 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 -0400755 }
756
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400757 ALLOC(tf_res, st->mode->nbEBands, int);
Jean-Marc Valin5e7f02d2010-08-08 09:48:22 -0400758 /* Needs to be before coarse energy quantization because otherwise the energy gets modified */
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400759 tf_select = tf_analysis(st->mode, bandLogE, oldBandE, effEnd, C, isTransient, tf_res, nbAvailableBytes, X, N, LM);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400760 for (i=effEnd;i<st->end;i++)
761 tf_res[i] = tf_res[effEnd-1];
762
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400763 ALLOC(error, C*st->mode->nbEBands, celt_word16);
Jean-Marc Valin5e7f02d2010-08-08 09:48:22 -0400764 quant_coarse_energy(st->mode, st->start, st->end, effEnd, bandLogE,
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400765 oldBandE, nbCompressedBytes*8, st->mode->prob,
Jean-Marc Valin1b36d6c2010-08-31 17:21:52 -0400766 error, enc, C, LM, nbAvailableBytes, st->force_intra,
767 &st->delayedIntra, st->complexity >= 4);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400768
Jean-Marc Valinf9fdbff2010-09-05 21:02:38 -0400769 if (LM > 0)
770 ec_enc_bit_prob(enc, shortBlocks!=0, 8192);
Jean-Marc Valin4c77ea92009-09-14 22:50:41 -0400771
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -0400772 if (shortBlocks)
773 {
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -0400774 if (transient_shift)
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400775 {
Jean-Marc Valin0be05b02010-07-16 14:23:03 -0400776 int max_time = (N+st->mode->overlap)*(celt_int32)8000/st->mode->Fs;
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400777 ec_enc_uint(enc, transient_shift, 4);
Jean-Marc Valin0be05b02010-07-16 14:23:03 -0400778 ec_enc_uint(enc, transient_time_quant, max_time);
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400779 } else {
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400780 ec_enc_uint(enc, mdct_weight_shift, 4);
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400781 if (mdct_weight_shift && M!=2)
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400782 ec_enc_uint(enc, mdct_weight_pos, M-1);
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400783 }
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -0400784 }
Jean-Marc Valinc890b582008-08-01 22:26:49 -0400785
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -0400786 tf_encode(st->start, st->end, isTransient, tf_res, nbAvailableBytes, LM, tf_select, enc);
787
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400788 if (shortBlocks || st->complexity < 3)
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -0400789 {
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400790 if (st->complexity == 0)
791 {
792 has_fold = 0;
793 st->fold_decision = 3;
794 } else {
795 has_fold = 1;
796 st->fold_decision = 1;
797 }
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -0400798 } else {
799 has_fold = folding_decision(st->mode, X, &st->tonal_average, &st->fold_decision, effEnd, C, M);
800 }
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400801 ec_enc_bit_prob(enc, has_fold>>1, 8192);
802 ec_enc_bit_prob(enc, has_fold&1, (has_fold>>1) ? 32768 : 49152);
803
Jean-Marc Valinf1fea662010-10-09 22:58:52 -0400804 ALLOC(offsets, st->mode->nbEBands, int);
805
806 for (i=0;i<st->mode->nbEBands;i++)
807 offsets[i] = 0;
808 /* Dynamic allocation code */
809 /* Make sure that dynamic allocation can't make us bust the budget */
810 if (nbCompressedBytes > 30)
811 {
812 int t1, t2;
813 if (LM <= 1)
814 {
815 t1 = 3;
816 t2 = 5;
817 } else {
818 t1 = 2;
819 t2 = 4;
820 }
821 for (i=1;i<st->mode->nbEBands-1;i++)
822 {
823 if (2*bandLogE[i]-bandLogE[i-1]-bandLogE[i+1] > SHL16(t1,DB_SHIFT))
824 offsets[i] += 1;
825 if (2*bandLogE[i]-bandLogE[i-1]-bandLogE[i+1] > SHL16(t2,DB_SHIFT))
826 offsets[i] += 1;
827 }
828 }
829 for (i=0;i<st->mode->nbEBands;i++)
830 {
831 int j;
832 ec_enc_bit_prob(enc, offsets[i]!=0, 1024);
833 if (offsets[i]!=0)
834 {
835 for (j=0;j<offsets[i]-1;j++)
836 ec_enc_bit_prob(enc, 1, 32768);
837 ec_enc_bit_prob(enc, 0, 32768);
838 }
839 offsets[i] *= (6<<BITRES);
840 }
841 {
842 int trim_index = 3;
843
844 /*if (isTransient)
845 trim_index--;
846 if (has_fold==0)
847 trim_index--;
848 if (C==2)
849 trim_index--;*/
850 alloc_trim = trim_coef[trim_index];
851 ec_encode_bin(enc, trim_cdf[trim_index], trim_cdf[trim_index+1], 7);
852 }
853
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400854 /* Variable bitrate */
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -0400855 if (st->vbr_rate_norm>0)
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400856 {
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400857 celt_word16 alpha;
Jean-Marc Valin25767d12009-10-21 23:24:18 -0400858 celt_int32 delta;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400859 /* The target rate in 16th bits per frame */
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -0400860 celt_int32 vbr_rate;
861 celt_int32 target;
862 celt_int32 vbr_bound, max_allowed;
863
864 vbr_rate = M*st->vbr_rate_norm;
865
866 /* Computes the max bit-rate allowed in VBR more to avoid busting the budget */
867 vbr_bound = vbr_rate;
868 max_allowed = (vbr_rate + vbr_bound - st->vbr_reservoir)>>(BITRES+3);
869 if (max_allowed < 4)
870 max_allowed = 4;
871 if (max_allowed < nbAvailableBytes)
872 nbAvailableBytes = max_allowed;
873 target=vbr_rate;
874
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400875 /* Shortblocks get a large boost in bitrate, but since they
876 are uncommon long blocks are not greatly effected */
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400877 if (shortBlocks)
878 target*=2;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400879 else if (M > 1)
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400880 target-=(target+14)/28;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400881
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400882 /* The average energy is removed from the target and the actual
883 energy added*/
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400884 target=target+st->vbr_offset-588+ec_enc_tell(enc, BITRES);
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400885
886 /* 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 -0400887 target=IMIN(nbAvailableBytes,target);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400888 /* Make the adaptation coef (alpha) higher at the beginning */
889 if (st->vbr_count < 990)
890 {
891 st->vbr_count++;
892 alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+10),16));
893 /*printf ("%d %d\n", st->vbr_count+10, alpha);*/
894 } else
895 alpha = QCONST16(.001f,15);
896
897 /* By how much did we "miss" the target on that frame */
Jean-Marc Valin8cc945c2010-05-29 08:07:18 -0400898 delta = (8<<BITRES)*(celt_int32)target - vbr_rate;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400899 /* How many bits have we used in excess of what we're allowed */
900 st->vbr_reservoir += delta;
901 /*printf ("%d\n", st->vbr_reservoir);*/
902
903 /* Compute the offset we need to apply in order to reach the target */
Jean-Marc Valin736efd62010-08-31 11:52:45 -0400904 st->vbr_drift += (celt_int32)MULT16_32_Q15(alpha,delta-st->vbr_offset-st->vbr_drift);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400905 st->vbr_offset = -st->vbr_drift;
906 /*printf ("%d\n", st->vbr_drift);*/
907
908 /* We could use any multiple of vbr_rate as bound (depending on the delay) */
Jean-Marc Valin25767d12009-10-21 23:24:18 -0400909 if (st->vbr_reservoir < 0)
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400910 {
911 /* We're under the min value -- increase rate */
912 int adjust = 1-(st->vbr_reservoir-1)/(8<<BITRES);
913 st->vbr_reservoir += adjust*(8<<BITRES);
Jean-Marc Valin45f11102009-10-22 00:12:31 -0400914 target += adjust;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400915 /*printf ("+%d\n", adjust);*/
916 }
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400917 if (target < nbAvailableBytes)
918 nbAvailableBytes = target;
919 nbCompressedBytes = nbAvailableBytes + nbFilledBytes;
920
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400921 /* This moves the raw bits to take into account the new compressed size */
Jean-Marc Valine6108642009-08-01 23:05:47 +0200922 ec_byte_shrink(&buf, nbCompressedBytes);
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400923 }
924
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -0400925 /* Bit allocation */
926 ALLOC(fine_quant, st->mode->nbEBands, int);
927 ALLOC(pulses, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -0400928 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +1100929
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400930 bits = nbCompressedBytes*8 - ec_enc_tell(enc, 0) - 1;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -0400931 codedBands = compute_allocation(st->mode, st->start, st->end, offsets, alloc_trim, bits, pulses, fine_quant, fine_priority, C, LM);
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -0500932
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400933 quant_fine_energy(st->mode, st->start, st->end, bandE, oldBandE, error, fine_quant, enc, C);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400934
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +0200935#ifdef MEASURE_NORM_MSE
Jean-Marc Valin44092242010-07-29 18:32:54 +0200936 float X0[3000];
937 float bandE0[60];
938 for (c=0;c<C;c++)
939 for (i=0;i<N;i++)
940 X0[i+c*N] = X[i+c*N];
941 for (i=0;i<C*st->mode->nbEBands;i++)
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +0200942 bandE0[i] = bandE[i];
943#endif
944
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100945 /* Residual quantisation */
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400946 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, codedBands);
Jean-Marc Valin39710532009-06-09 00:10:32 -0400947
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400948 quant_energy_finalise(st->mode, st->start, st->end, bandE, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_enc_tell(enc, 0), enc, C);
Jean-Marc Valin39710532009-06-09 00:10:32 -0400949
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -0500950 /* Re-synthesis of the coded audio if required */
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -0400951 if (resynth)
Jean-Marc Valin18ddc022008-02-22 14:24:50 +1100952 {
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400953 VARDECL(celt_sig, _out_mem);
954 celt_sig *out_mem[2];
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400955 celt_sig *overlap_mem[2];
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400956
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400957 log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
Jean-Marc Valinbc272de2010-08-02 09:41:31 -0400958
959#ifdef MEASURE_NORM_MSE
960 measure_norm_mse(st->mode, X, X0, bandE, bandE0, M, N, C);
961#endif
962
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400963 if (mdct_weight_shift)
964 {
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400965 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 -0400966 }
Jean-Marc Valin88619552009-10-04 21:35:36 -0400967
968 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400969 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400970
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -0400971 for (c=0;c<C;c++)
972 for (i=0;i<M*st->mode->eBands[st->start];i++)
973 freq[c*N+i] = 0;
974 for (c=0;c<C;c++)
975 for (i=M*st->mode->eBands[st->end];i<N;i++)
976 freq[c*N+i] = 0;
977
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400978 ALLOC(_out_mem, C*N, celt_sig);
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400979
980 for (c=0;c<C;c++)
981 {
982 overlap_mem[c] = _overlap_mem + c*st->overlap;
983 out_mem[c] = _out_mem+c*N;
984 }
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400985
986 compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time,
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400987 transient_shift, out_mem, overlap_mem, C, LM);
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400988
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400989 /* De-emphasis and put everything back at the right place
990 in the synthesis history */
Jean-Marc Valind56c6102010-05-07 20:30:22 -0400991 if (optional_resynthesis != NULL) {
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400992 deemphasis(out_mem, optional_resynthesis, N, C, st->mode->preemph, st->preemph_memD);
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400993
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +1100994 }
Jean-Marc Valind9b95652008-08-31 23:34:47 -0400995 }
Gregory Maxwell54547f12009-02-16 18:56:44 -0500996
Jean-Marc Valin30d51252010-06-21 17:55:28 -0400997 /* If there's any room left (can only happen for very high rates),
998 fill it with zeros */
Jean-Marc Valin5d774e02010-08-04 17:17:18 -0400999 while (ec_enc_tell(enc,0) + 8 <= nbCompressedBytes*8)
Jean-Marc Valin30d51252010-06-21 17:55:28 -04001000 ec_enc_bits(enc, 0, 8);
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001001 ec_enc_done(enc);
Jean-Marc Valinc871c8d2009-06-09 00:57:00 -04001002
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001003 RESTORE_STACK;
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001004 if (ec_enc_get_error(enc))
Jean-Marc Valin9d785af2010-07-18 09:42:05 -04001005 return CELT_CORRUPTED_DATA;
1006 else
1007 return nbCompressedBytes;
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11001008}
1009
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001010#ifdef FIXED_POINT
1011#ifndef DISABLE_FLOAT_API
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001012int 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 -04001013{
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001014 int j, ret, C, N, LM, M;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001015 VARDECL(celt_int16, in);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -04001016 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001017
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001018 if (pcm==NULL)
1019 return CELT_BAD_ARG;
1020
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001021 for (LM=0;LM<4;LM++)
1022 if (st->mode->shortMdctSize<<LM==frame_size)
1023 break;
1024 if (LM>=MAX_CONFIG_SIZES)
1025 return CELT_BAD_ARG;
1026 M=1<<LM;
1027
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001028 C = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001029 N = M*st->mode->shortMdctSize;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001030 ALLOC(in, C*N, celt_int16);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001031
1032 for (j=0;j<C*N;j++)
1033 in[j] = FLOAT2INT16(pcm[j]);
1034
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001035 if (optional_resynthesis != NULL) {
1036 ret=celt_encode_with_ec(st,in,in,frame_size,compressed,nbCompressedBytes, enc);
Gregory Maxwellb0a73a02008-12-12 16:54:25 -05001037 for (j=0;j<C*N;j++)
Jean-Marc Valinae01e112010-08-03 21:43:41 -04001038 optional_resynthesis[j]=in[j]*(1.f/32768.f);
Gregory Maxwell82595312008-09-30 18:20:14 -04001039 } else {
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001040 ret=celt_encode_with_ec(st,in,NULL,frame_size,compressed,nbCompressedBytes, enc);
Gregory Maxwell82595312008-09-30 18:20:14 -04001041 }
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001042 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001043 return ret;
1044
1045}
1046#endif /*DISABLE_FLOAT_API*/
1047#else
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001048int 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 -04001049{
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001050 int j, ret, C, N, LM, M;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001051 VARDECL(celt_sig, in);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -04001052 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001053
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001054 if (pcm==NULL)
1055 return CELT_BAD_ARG;
1056
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001057 for (LM=0;LM<4;LM++)
1058 if (st->mode->shortMdctSize<<LM==frame_size)
1059 break;
1060 if (LM>=MAX_CONFIG_SIZES)
1061 return CELT_BAD_ARG;
1062 M=1<<LM;
1063
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001064 C=CHANNELS(st->channels);
Jean-Marc Valin04752672010-05-05 07:21:21 -04001065 N=M*st->mode->shortMdctSize;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001066 ALLOC(in, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001067 for (j=0;j<C*N;j++) {
1068 in[j] = SCALEOUT(pcm[j]);
1069 }
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001070
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001071 if (optional_resynthesis != NULL) {
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001072 ret = celt_encode_with_ec_float(st,in,in,frame_size,compressed,nbCompressedBytes, enc);
Gregory Maxwell82595312008-09-30 18:20:14 -04001073 for (j=0;j<C*N;j++)
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001074 optional_resynthesis[j] = FLOAT2INT16(in[j]);
Gregory Maxwell82595312008-09-30 18:20:14 -04001075 } else {
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001076 ret = celt_encode_with_ec_float(st,in,NULL,frame_size,compressed,nbCompressedBytes, enc);
Gregory Maxwell82595312008-09-30 18:20:14 -04001077 }
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001078 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001079 return ret;
1080}
1081#endif
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +11001082
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001083int celt_encode(CELTEncoder * restrict st, const celt_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1084{
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001085 return celt_encode_with_ec(st, pcm, NULL, frame_size, compressed, nbCompressedBytes, NULL);
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001086}
1087
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001088#ifndef DISABLE_FLOAT_API
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001089int celt_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1090{
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001091 return celt_encode_with_ec_float(st, pcm, NULL, frame_size, compressed, nbCompressedBytes, NULL);
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001092}
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001093#endif /* DISABLE_FLOAT_API */
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001094
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001095int celt_encode_resynthesis(CELTEncoder * restrict st, const celt_int16 * pcm, celt_int16 * optional_resynthesis, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1096{
1097 return celt_encode_with_ec(st, pcm, optional_resynthesis, frame_size, compressed, nbCompressedBytes, NULL);
1098}
1099
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001100#ifndef DISABLE_FLOAT_API
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001101int celt_encode_resynthesis_float(CELTEncoder * restrict st, const float * pcm, float * optional_resynthesis, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1102{
1103 return celt_encode_with_ec_float(st, pcm, optional_resynthesis, frame_size, compressed, nbCompressedBytes, NULL);
1104}
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001105#endif /* DISABLE_FLOAT_API */
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001106
1107
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001108int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...)
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001109{
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001110 va_list ap;
Gregory Maxwell17169992009-06-04 15:15:34 -04001111
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001112 va_start(ap, request);
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001113 switch (request)
1114 {
Gregory Maxwellf3b44ef2009-06-03 13:37:45 -04001115 case CELT_GET_MODE_REQUEST:
1116 {
1117 const CELTMode ** value = va_arg(ap, const CELTMode**);
1118 if (value==0)
1119 goto bad_arg;
1120 *value=st->mode;
1121 }
1122 break;
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001123 case CELT_SET_COMPLEXITY_REQUEST:
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001124 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001125 int value = va_arg(ap, celt_int32);
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001126 if (value<0 || value>10)
1127 goto bad_arg;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001128 st->complexity = value;
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001129 }
1130 break;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001131 case CELT_SET_START_BAND_REQUEST:
1132 {
1133 celt_int32 value = va_arg(ap, celt_int32);
1134 if (value<0 || value>=st->mode->nbEBands)
1135 goto bad_arg;
1136 st->start = value;
1137 }
1138 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001139 case CELT_SET_END_BAND_REQUEST:
1140 {
1141 celt_int32 value = va_arg(ap, celt_int32);
1142 if (value<0 || value>=st->mode->nbEBands)
1143 goto bad_arg;
1144 st->end = value;
1145 }
1146 break;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001147 case CELT_SET_PREDICTION_REQUEST:
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001148 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001149 int value = va_arg(ap, celt_int32);
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001150 if (value<0 || value>2)
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001151 goto bad_arg;
1152 if (value==0)
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001153 {
1154 st->force_intra = 1;
Gregory Maxwella80958b2009-06-29 12:48:57 -04001155 } else if (value==1) {
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001156 st->force_intra = 0;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001157 } else {
1158 st->force_intra = 0;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001159 }
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001160 }
1161 break;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001162 case CELT_SET_VBR_RATE_REQUEST:
1163 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001164 celt_int32 value = va_arg(ap, celt_int32);
Jean-Marc Valin8cc945c2010-05-29 08:07:18 -04001165 int frame_rate;
1166 int N = st->mode->shortMdctSize;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001167 if (value<0)
1168 goto bad_arg;
1169 if (value>3072000)
1170 value = 3072000;
Jean-Marc Valin8cc945c2010-05-29 08:07:18 -04001171 frame_rate = ((st->mode->Fs<<3)+(N>>1))/N;
1172 st->vbr_rate_norm = ((value<<(BITRES+3))+(frame_rate>>1))/frame_rate;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001173 }
1174 break;
John Ridges454d1d02009-05-21 22:38:39 -04001175 case CELT_RESET_STATE:
1176 {
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001177 CELT_MEMSET((char*)&st->ENCODER_RESET_START, 0,
1178 celt_encoder_get_size(st->mode, st->channels)-
1179 ((char*)&st->ENCODER_RESET_START - (char*)st));
John Ridges454d1d02009-05-21 22:38:39 -04001180 st->delayedIntra = 1;
John Ridges5378bf82010-02-12 07:08:01 -05001181 st->fold_decision = 1;
Jean-Marc Valin628c0252010-04-16 20:57:56 -04001182 st->tonal_average = QCONST16(1.f,8);
John Ridges454d1d02009-05-21 22:38:39 -04001183 }
1184 break;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001185 default:
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001186 goto bad_request;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001187 }
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001188 va_end(ap);
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001189 return CELT_OK;
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001190bad_arg:
1191 va_end(ap);
1192 return CELT_BAD_ARG;
1193bad_request:
1194 va_end(ap);
1195 return CELT_UNIMPLEMENTED;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001196}
1197
Jean-Marc Valin56522ad2009-06-05 17:17:25 -04001198/**********************************************************************/
1199/* */
1200/* DECODER */
1201/* */
1202/**********************************************************************/
Jean-Marc Valineafbdd52009-04-27 19:35:09 -04001203#define DECODE_BUFFER_SIZE 2048
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001204
Jean-Marc Valin276de722008-02-20 17:45:51 +11001205/** Decoder state
1206 @brief Decoder state
1207 */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001208struct CELTDecoder {
1209 const CELTMode *mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001210 int overlap;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001211 int channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001212
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001213 int start, end;
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001214
1215 /* Everything beyond this point gets cleared on a reset */
1216#define DECODER_RESET_START last_pitch_index
1217
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001218 int last_pitch_index;
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001219 int loss_count;
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001220
1221 celt_sig preemph_memD[2];
1222
Jean-Marc Valinca8b9922010-08-27 16:23:03 -04001223 celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */
1224 /* celt_word16 lpc[], Size = channels*LPC_ORDER */
1225 /* celt_word16 oldEBands[], Size = channels*mode->nbEBands */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001226};
1227
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001228int celt_decoder_get_size(const CELTMode *mode, int channels)
1229{
1230 int size = sizeof(struct CELTDecoder)
1231 + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig)
1232 + channels*LPC_ORDER*sizeof(celt_word16)
1233 + channels*mode->nbEBands*sizeof(celt_word16);
1234 return size;
1235}
1236
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001237CELTDecoder *celt_decoder_create(const CELTMode *mode, int channels, int *error)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001238{
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -04001239 return celt_decoder_init(
1240 (CELTDecoder *)celt_alloc(celt_decoder_get_size(mode, channels)),
1241 mode, channels, error);
1242}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001243
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -04001244CELTDecoder *celt_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels, int *error)
1245{
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001246 if (channels < 0 || channels > 2)
1247 {
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001248 if (error)
1249 *error = CELT_BAD_ARG;
1250 return NULL;
1251 }
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001252
Gregory Maxwell17169992009-06-04 15:15:34 -04001253 if (st==NULL)
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001254 {
1255 if (error)
1256 *error = CELT_ALLOC_FAIL;
Gregory Maxwell17169992009-06-04 15:15:34 -04001257 return NULL;
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001258 }
1259
Jean-Marc Valin6d3829f2010-08-27 17:52:38 -04001260 CELT_MEMSET((char*)st, 0, celt_decoder_get_size(mode, channels));
1261
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001262 st->mode = mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001263 st->overlap = mode->overlap;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001264 st->channels = channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001265
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001266 st->start = 0;
Jean-Marc Valin8952c452010-07-16 21:48:44 -04001267 st->end = st->mode->effEBands;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001268
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001269 st->loss_count = 0;
Gregory Maxwell17169992009-06-04 15:15:34 -04001270
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001271 if (error)
1272 *error = CELT_OK;
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001273 return st;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001274}
1275
Peter Kirk19f9dc92008-06-06 14:38:38 +02001276void celt_decoder_destroy(CELTDecoder *st)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001277{
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001278 celt_free(st);
1279}
1280
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001281static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict pcm, int N, int LM)
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001282{
Jean-Marc Valin04752672010-05-05 07:21:21 -04001283 int c;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11001284 int pitch_index;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001285 int overlap = st->mode->overlap;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001286 celt_word16 fade = Q15ONE;
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001287 int i, len;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001288 const int C = CHANNELS(st->channels);
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001289 int offset;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001290 celt_sig *out_mem[2];
1291 celt_sig *decode_mem[2];
1292 celt_sig *overlap_mem[2];
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001293 celt_word16 *lpc;
1294 celt_word16 *oldBandE;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001295 SAVE_STACK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001296
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001297 for (c=0;c<C;c++)
1298 {
1299 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
1300 out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
1301 overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
1302 }
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001303 lpc = (celt_word16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C);
1304 oldBandE = lpc+C*LPC_ORDER;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001305
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001306 len = N+st->mode->overlap;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001307
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001308 if (st->loss_count == 0)
1309 {
Jean-Marc Valin7a7c42a2009-11-25 20:38:52 -05001310 celt_word16 pitch_buf[MAX_PERIOD>>1];
Jean-Marc Valin294863b2009-11-08 22:29:54 +09001311 celt_word32 tmp=0;
Jean-Marc Valine465c142009-11-26 00:39:36 -05001312 celt_word32 mem0[2]={0,0};
1313 celt_word16 mem1[2]={0,0};
Jean-Marc Valin6202c742010-06-01 00:30:37 -04001314 int len2 = len;
1315 /* FIXME: This is a kludge */
1316 if (len2>MAX_PERIOD>>1)
1317 len2 = MAX_PERIOD>>1;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001318 pitch_downsample(out_mem, pitch_buf, MAX_PERIOD, MAX_PERIOD,
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001319 C, mem0, mem1);
Jean-Marc Valin6202c742010-06-01 00:30:37 -04001320 pitch_search(st->mode, pitch_buf+((MAX_PERIOD-len2)>>1), pitch_buf, len2,
1321 MAX_PERIOD-len2-100, &pitch_index, &tmp, 1<<LM);
1322 pitch_index = MAX_PERIOD-len2-pitch_index;
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001323 st->last_pitch_index = pitch_index;
1324 } else {
1325 pitch_index = st->last_pitch_index;
1326 if (st->loss_count < 5)
1327 fade = QCONST16(.8f,15);
1328 else
1329 fade = 0;
1330 }
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001331
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001332 for (c=0;c<C;c++)
1333 {
Jean-Marc Valin6202c742010-06-01 00:30:37 -04001334 /* FIXME: This is more memory than necessary */
1335 celt_word32 e[2*MAX_PERIOD];
1336 celt_word16 exc[2*MAX_PERIOD];
Jean-Marc Valin456eab22010-06-16 22:38:57 -04001337 celt_word32 ac[LPC_ORDER+1];
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001338 celt_word16 decay = 1;
1339 celt_word32 S1=0;
Jean-Marc Valin74128be2010-01-01 09:33:17 -05001340 celt_word16 mem[LPC_ORDER]={0};
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001341
Jean-Marc Valind5f99302009-12-16 22:42:32 -05001342 offset = MAX_PERIOD-pitch_index;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001343 for (i=0;i<MAX_PERIOD;i++)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001344 exc[i] = ROUND16(out_mem[c][i], SIG_SHIFT);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001345
1346 if (st->loss_count == 0)
1347 {
1348 _celt_autocorr(exc, ac, st->mode->window, st->mode->overlap,
1349 LPC_ORDER, MAX_PERIOD);
1350
Jean-Marc Valin456eab22010-06-16 22:38:57 -04001351 /* Noise floor -40 dB */
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001352#ifdef FIXED_POINT
1353 ac[0] += SHR32(ac[0],13);
1354#else
Jean-Marc Valinae01e112010-08-03 21:43:41 -04001355 ac[0] *= 1.0001f;
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001356#endif
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001357 /* Lag windowing */
1358 for (i=1;i<=LPC_ORDER;i++)
1359 {
1360 /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001361#ifdef FIXED_POINT
1362 ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);
1363#else
Jean-Marc Valinae01e112010-08-03 21:43:41 -04001364 ac[i] -= ac[i]*(.008f*i)*(.008f*i);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001365#endif
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001366 }
1367
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001368 _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001369 }
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001370 fir(exc, lpc+c*LPC_ORDER, exc, MAX_PERIOD, LPC_ORDER, mem);
Jean-Marc Valin74128be2010-01-01 09:33:17 -05001371 /*for (i=0;i<MAX_PERIOD;i++)printf("%d ", exc[i]); printf("\n");*/
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001372 /* Check if the waveform is decaying (and if so how fast) */
1373 {
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001374 celt_word32 E1=1, E2=1;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001375 int period;
1376 if (pitch_index <= MAX_PERIOD/2)
1377 period = pitch_index;
1378 else
1379 period = MAX_PERIOD/2;
1380 for (i=0;i<period;i++)
1381 {
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001382 E1 += SHR32(MULT16_16(exc[MAX_PERIOD-period+i],exc[MAX_PERIOD-period+i]),8);
1383 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 -05001384 }
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001385 if (E1 > E2)
1386 E1 = E2;
1387 decay = celt_sqrt(frac_div32(SHR(E1,1),E2));
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001388 }
1389
1390 /* Copy excitation, taking decay into account */
1391 for (i=0;i<len+st->mode->overlap;i++)
1392 {
1393 if (offset+i >= MAX_PERIOD)
1394 {
1395 offset -= pitch_index;
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001396 decay = MULT16_16_Q15(decay, decay);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001397 }
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001398 e[i] = SHL32(EXTEND32(MULT16_16_Q15(decay, exc[offset+i])), SIG_SHIFT);
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001399 S1 += SHR32(MULT16_16(out_mem[c][offset+i],out_mem[c][offset+i]),8);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001400 }
1401
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001402 iir(e, lpc+c*LPC_ORDER, e, len+st->mode->overlap, LPC_ORDER, mem);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001403
1404 {
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001405 celt_word32 S2=0;
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001406 for (i=0;i<len+overlap;i++)
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001407 S2 += SHR32(MULT16_16(e[i],e[i]),8);
Jean-Marc Valinfeca0952010-06-17 20:25:51 -04001408 /* This checks for an "explosion" in the synthesis */
1409#ifdef FIXED_POINT
1410 if (!(S1 > SHR32(S2,2)))
1411#else
1412 /* Float test is written this way to catch NaNs at the same time */
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05001413 if (!(S1 > 0.2f*S2))
Jean-Marc Valinfeca0952010-06-17 20:25:51 -04001414#endif
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05001415 {
1416 for (i=0;i<len+overlap;i++)
1417 e[i] = 0;
1418 } else if (S1 < S2)
1419 {
Jean-Marc Valin12996402010-08-04 09:13:24 -04001420 celt_word16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001421 for (i=0;i<len+overlap;i++)
Jean-Marc Valinfeca0952010-06-17 20:25:51 -04001422 e[i] = MULT16_16_Q15(ratio, e[i]);
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05001423 }
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001424 }
1425
1426 for (i=0;i<MAX_PERIOD+st->mode->overlap-N;i++)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001427 out_mem[c][i] = out_mem[c][N+i];
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001428
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001429 /* Apply TDAC to the concealed audio so that it blends with the
1430 previous and next frames */
1431 for (i=0;i<overlap/2;i++)
1432 {
Jean-Marc Valind69c1cb2009-12-28 00:34:29 -05001433 celt_word32 tmp1, tmp2;
1434 tmp1 = MULT16_32_Q15(st->mode->window[i ], e[i ]) -
1435 MULT16_32_Q15(st->mode->window[overlap-i-1], e[overlap-i-1]);
1436 tmp2 = MULT16_32_Q15(st->mode->window[i], e[N+overlap-1-i]) +
1437 MULT16_32_Q15(st->mode->window[overlap-i-1], e[N+i ]);
1438 tmp1 = MULT16_32_Q15(fade, tmp1);
1439 tmp2 = MULT16_32_Q15(fade, tmp2);
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001440 out_mem[c][MAX_PERIOD+i] = MULT16_32_Q15(st->mode->window[overlap-i-1], tmp2);
1441 out_mem[c][MAX_PERIOD+overlap-i-1] = MULT16_32_Q15(st->mode->window[i], tmp2);
1442 out_mem[c][MAX_PERIOD-N+i] += MULT16_32_Q15(st->mode->window[i], tmp1);
1443 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 -05001444 }
1445 for (i=0;i<N-overlap;i++)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001446 out_mem[c][MAX_PERIOD-N+overlap+i] = MULT16_32_Q15(fade, e[overlap+i]);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001447 }
Jean-Marc Valin1677aa92007-12-08 01:13:34 +11001448
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001449 deemphasis(out_mem, pcm, N, C, st->mode->preemph, st->preemph_memD);
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001450
1451 st->loss_count++;
1452
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001453 RESTORE_STACK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001454}
1455
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001456#ifdef FIXED_POINT
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001457int 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 +11001458{
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001459#else
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001460int 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 -04001461{
1462#endif
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -04001463 int c, i, N;
Jean-Marc Valin8cbea172010-08-05 15:22:57 -04001464 int has_fold;
Jean-Marc Valinc890b582008-08-01 22:26:49 -04001465 int bits;
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001466 ec_dec _dec;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11001467 ec_byte_buffer buf;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001468 VARDECL(celt_sig, freq);
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001469 VARDECL(celt_norm, X);
1470 VARDECL(celt_ener, bandE);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001471 VARDECL(int, fine_quant);
1472 VARDECL(int, pulses);
1473 VARDECL(int, offsets);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04001474 VARDECL(int, fine_priority);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -04001475 VARDECL(int, tf_res);
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001476 celt_sig *out_mem[2];
1477 celt_sig *decode_mem[2];
1478 celt_sig *overlap_mem[2];
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04001479 celt_sig *out_syn[2];
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001480 celt_word16 *lpc;
1481 celt_word16 *oldBandE;
Jean-Marc Valinc890b582008-08-01 22:26:49 -04001482
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +10001483 int shortBlocks;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001484 int isTransient;
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -04001485 int intra_ener;
Jean-Marc Valin12b22482008-06-16 14:13:05 +10001486 int transient_time;
Jean-Marc Valin528f4b82008-06-29 03:46:39 +10001487 int transient_shift;
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001488 int mdct_weight_shift=0;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001489 const int C = CHANNELS(st->channels);
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001490 int mdct_weight_pos=0;
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001491 int LM, M;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04001492 int nbFilledBytes, nbAvailableBytes;
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001493 int effEnd;
Jean-Marc Valinb801da52010-09-28 14:56:20 -04001494 int codedBands;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001495 int alloc_trim;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001496 SAVE_STACK;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001497
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001498 if (pcm==NULL)
1499 return CELT_BAD_ARG;
1500
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001501 for (LM=0;LM<4;LM++)
1502 if (st->mode->shortMdctSize<<LM==frame_size)
1503 break;
1504 if (LM>=MAX_CONFIG_SIZES)
1505 return CELT_BAD_ARG;
1506 M=1<<LM;
1507
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001508 for (c=0;c<C;c++)
1509 {
1510 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
1511 out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
1512 overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
1513 }
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001514 lpc = (celt_word16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C);
1515 oldBandE = lpc+C*LPC_ORDER;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001516
Jean-Marc Valin04752672010-05-05 07:21:21 -04001517 N = M*st->mode->shortMdctSize;
Jean-Marc Valin01417232008-03-03 13:59:55 +11001518
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001519 effEnd = st->end;
1520 if (effEnd > st->mode->effEBands)
1521 effEnd = st->mode->effEBands;
1522
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001523 ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
1524 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
1525 ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001526 for (c=0;c<C;c++)
1527 for (i=0;i<M*st->mode->eBands[st->start];i++)
1528 X[c*N+i] = 0;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001529 for (c=0;c<C;c++)
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001530 for (i=M*st->mode->eBands[effEnd];i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001531 X[c*N+i] = 0;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001532
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001533 if (data == NULL)
1534 {
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001535 celt_decode_lost(st, pcm, N, LM);
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001536 RESTORE_STACK;
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001537 return CELT_OK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001538 }
Gregory Maxwell520eeae2009-02-09 01:33:21 -05001539 if (len<0) {
1540 RESTORE_STACK;
1541 return CELT_BAD_ARG;
1542 }
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001543
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001544 if (dec == NULL)
1545 {
1546 ec_byte_readinit(&buf,(unsigned char*)data,len);
1547 ec_dec_init(&_dec,&buf);
1548 dec = &_dec;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04001549 nbFilledBytes = 0;
1550 } else {
Jean-Marc Valinbdcaaf72010-07-05 13:52:41 -04001551 nbFilledBytes = (ec_dec_tell(dec, 0)+4)>>3;
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001552 }
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04001553 nbAvailableBytes = len-nbFilledBytes;
1554
Jean-Marc Valin017001a2010-08-05 15:42:50 -04001555 /* Decode the global flags (first symbols in the stream) */
1556 intra_ener = ec_dec_bit_prob(dec, 8192);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001557 /* Get band energies */
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001558 unquant_coarse_energy(st->mode, st->start, st->end, bandE, oldBandE,
1559 intra_ener, st->mode->prob, dec, C, LM);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001560
Jean-Marc Valinf9fdbff2010-09-05 21:02:38 -04001561 if (LM > 0)
1562 isTransient = ec_dec_bit_prob(dec, 8192);
1563 else
1564 isTransient = 0;
Jean-Marc Valin017001a2010-08-05 15:42:50 -04001565
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001566 if (isTransient)
1567 shortBlocks = M;
1568 else
1569 shortBlocks = 0;
1570
1571 if (isTransient)
Gregory Maxwell0527f372008-09-23 19:28:35 -04001572 {
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001573 transient_shift = ec_dec_uint(dec, 4);
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001574 if (transient_shift == 3)
1575 {
Jean-Marc Valin0be05b02010-07-16 14:23:03 -04001576 int transient_time_quant;
1577 int max_time = (N+st->mode->overlap)*(celt_int32)8000/st->mode->Fs;
1578 transient_time_quant = ec_dec_uint(dec, max_time);
1579 transient_time = transient_time_quant*(celt_int32)st->mode->Fs/8000;
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001580 } else {
1581 mdct_weight_shift = transient_shift;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001582 if (mdct_weight_shift && M>2)
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001583 mdct_weight_pos = ec_dec_uint(dec, M-1);
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001584 transient_shift = 0;
Gregory Maxwell0527f372008-09-23 19:28:35 -04001585 transient_time = 0;
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001586 }
Gregory Maxwell0527f372008-09-23 19:28:35 -04001587 } else {
Jean-Marc Valin12b22482008-06-16 14:13:05 +10001588 transient_time = -1;
Jean-Marc Valin528f4b82008-06-29 03:46:39 +10001589 transient_shift = 0;
Jean-Marc Valin12b22482008-06-16 14:13:05 +10001590 }
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04001591
1592 ALLOC(tf_res, st->mode->nbEBands, int);
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -04001593 tf_decode(st->start, st->end, C, isTransient, tf_res, nbAvailableBytes, LM, dec);
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04001594
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001595 has_fold = ec_dec_bit_prob(dec, 8192)<<1;
1596 has_fold |= ec_dec_bit_prob(dec, (has_fold>>1) ? 32768 : 49152);
1597
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001598 ALLOC(pulses, st->mode->nbEBands, int);
1599 ALLOC(offsets, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04001600 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001601
1602 for (i=0;i<st->mode->nbEBands;i++)
1603 offsets[i] = 0;
Jean-Marc Valind74c8512010-09-29 17:39:54 -04001604 for (i=0;i<st->mode->nbEBands;i++)
1605 {
1606 if (ec_dec_bit_prob(dec, 1024))
1607 {
1608 while (ec_dec_bit_prob(dec, 32768))
1609 offsets[i]++;
1610 offsets[i]++;
1611 offsets[i] *= (6<<BITRES);
1612 }
1613 }
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001614
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001615 ALLOC(fine_quant, st->mode->nbEBands, int);
Jean-Marc Valin6bf04622010-09-30 10:16:22 -04001616 {
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001617 int fl;
Jean-Marc Valin6bf04622010-09-30 10:16:22 -04001618 int trim_index=0;
1619 fl = ec_decode_bin(dec, 7);
1620 while (trim_cdf[trim_index+1] <= fl)
1621 trim_index++;
1622 ec_dec_update(dec, trim_cdf[trim_index], trim_cdf[trim_index+1], 128);
1623 alloc_trim = trim_coef[trim_index];
Jean-Marc Valin6bf04622010-09-30 10:16:22 -04001624 }
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001625
1626 bits = len*8 - ec_dec_tell(dec, 0) - 1;
1627 codedBands = compute_allocation(st->mode, st->start, st->end, offsets, alloc_trim, bits, pulses, fine_quant, fine_priority, C, LM);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001628
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001629 unquant_fine_energy(st->mode, st->start, st->end, bandE, oldBandE, fine_quant, dec, C);
Jean-Marc Valin827f9312008-05-06 23:21:55 +10001630
Jean-Marc Valin8cbea172010-08-05 15:22:57 -04001631 /* Decode fixed codebook */
Jean-Marc Valinb801da52010-09-28 14:56:20 -04001632 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, codedBands);
Jean-Marc Valin746b2a82010-05-14 22:12:33 -04001633
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001634 unquant_energy_finalise(st->mode, st->start, st->end, bandE, oldBandE,
1635 fine_quant, fine_priority, len*8-ec_dec_tell(dec, 0), dec, C);
Jean-Marc Valin30d51252010-06-21 17:55:28 -04001636
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001637 log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04001638
Jean-Marc Valin88619552009-10-04 21:35:36 -04001639 if (mdct_weight_shift)
1640 {
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001641 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 -04001642 }
1643
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11001644 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001645 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11001646
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001647 CELT_MOVE(decode_mem[0], decode_mem[0]+N, DECODE_BUFFER_SIZE-N);
Jean-Marc Valin903dbf72010-08-26 20:06:49 -04001648 if (C==2)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001649 CELT_MOVE(decode_mem[1], decode_mem[1]+N, DECODE_BUFFER_SIZE-N);
Jean-Marc Valin88619552009-10-04 21:35:36 -04001650
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001651 for (c=0;c<C;c++)
1652 for (i=0;i<M*st->mode->eBands[st->start];i++)
1653 freq[c*N+i] = 0;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001654 for (c=0;c<C;c++)
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001655 for (i=M*st->mode->eBands[effEnd];i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001656 freq[c*N+i] = 0;
Jean-Marc Valin3a0bc3d2010-02-21 15:10:22 -05001657
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001658 out_syn[0] = out_mem[0]+MAX_PERIOD-N;
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04001659 if (C==2)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001660 out_syn[1] = out_mem[1]+MAX_PERIOD-N;
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04001661
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001662 /* Compute inverse MDCTs */
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001663 compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time,
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001664 transient_shift, out_syn, overlap_mem, C, LM);
Jean-Marc Valinffa13472007-12-10 16:54:17 +11001665
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04001666 deemphasis(out_syn, pcm, N, C, st->mode->preemph, st->preemph_memD);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001667 st->loss_count = 0;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001668 RESTORE_STACK;
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001669 if (ec_dec_get_error(dec))
1670 return CELT_CORRUPTED_DATA;
1671 else
1672 return CELT_OK;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001673}
1674
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001675#ifdef FIXED_POINT
1676#ifndef DISABLE_FLOAT_API
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001677int 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 -04001678{
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001679 int j, ret, C, N, LM, M;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001680 VARDECL(celt_int16, out);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -04001681 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001682
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001683 if (pcm==NULL)
1684 return CELT_BAD_ARG;
1685
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001686 for (LM=0;LM<4;LM++)
1687 if (st->mode->shortMdctSize<<LM==frame_size)
1688 break;
1689 if (LM>=MAX_CONFIG_SIZES)
1690 return CELT_BAD_ARG;
1691 M=1<<LM;
1692
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001693 C = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001694 N = M*st->mode->shortMdctSize;
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001695
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001696 ALLOC(out, C*N, celt_int16);
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001697 ret=celt_decode_with_ec(st, data, len, out, frame_size, dec);
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001698 if (ret==0)
1699 for (j=0;j<C*N;j++)
Jean-Marc Valinae01e112010-08-03 21:43:41 -04001700 pcm[j]=out[j]*(1.f/32768.f);
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001701
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001702 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001703 return ret;
1704}
1705#endif /*DISABLE_FLOAT_API*/
1706#else
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001707int 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 -04001708{
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001709 int j, ret, C, N, LM, M;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001710 VARDECL(celt_sig, out);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -04001711 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001712
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001713 if (pcm==NULL)
1714 return CELT_BAD_ARG;
1715
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001716 for (LM=0;LM<4;LM++)
1717 if (st->mode->shortMdctSize<<LM==frame_size)
1718 break;
1719 if (LM>=MAX_CONFIG_SIZES)
1720 return CELT_BAD_ARG;
1721 M=1<<LM;
1722
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001723 C = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001724 N = M*st->mode->shortMdctSize;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001725 ALLOC(out, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001726
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001727 ret=celt_decode_with_ec_float(st, data, len, out, frame_size, dec);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001728
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001729 if (ret==0)
1730 for (j=0;j<C*N;j++)
1731 pcm[j] = FLOAT2INT16 (out[j]);
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001732
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001733 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001734 return ret;
1735}
1736#endif
John Ridges454d1d02009-05-21 22:38:39 -04001737
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001738int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, celt_int16 * restrict pcm, int frame_size)
1739{
1740 return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL);
1741}
1742
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001743#ifndef DISABLE_FLOAT_API
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001744int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size)
1745{
1746 return celt_decode_with_ec_float(st, data, len, pcm, frame_size, NULL);
1747}
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001748#endif /* DISABLE_FLOAT_API */
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001749
John Ridges454d1d02009-05-21 22:38:39 -04001750int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
1751{
1752 va_list ap;
Gregory Maxwell17169992009-06-04 15:15:34 -04001753
John Ridges454d1d02009-05-21 22:38:39 -04001754 va_start(ap, request);
1755 switch (request)
1756 {
Gregory Maxwellf3b44ef2009-06-03 13:37:45 -04001757 case CELT_GET_MODE_REQUEST:
1758 {
1759 const CELTMode ** value = va_arg(ap, const CELTMode**);
1760 if (value==0)
1761 goto bad_arg;
1762 *value=st->mode;
1763 }
1764 break;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001765 case CELT_SET_START_BAND_REQUEST:
1766 {
1767 celt_int32 value = va_arg(ap, celt_int32);
1768 if (value<0 || value>=st->mode->nbEBands)
1769 goto bad_arg;
1770 st->start = value;
1771 }
1772 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001773 case CELT_SET_END_BAND_REQUEST:
1774 {
1775 celt_int32 value = va_arg(ap, celt_int32);
1776 if (value<0 || value>=st->mode->nbEBands)
1777 goto bad_arg;
1778 st->end = value;
1779 }
1780 break;
John Ridges454d1d02009-05-21 22:38:39 -04001781 case CELT_RESET_STATE:
1782 {
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001783 CELT_MEMSET((char*)&st->DECODER_RESET_START, 0,
1784 celt_decoder_get_size(st->mode, st->channels)-
1785 ((char*)&st->DECODER_RESET_START - (char*)st));
John Ridges454d1d02009-05-21 22:38:39 -04001786 }
1787 break;
1788 default:
1789 goto bad_request;
1790 }
1791 va_end(ap);
1792 return CELT_OK;
John Ridges454d1d02009-05-21 22:38:39 -04001793bad_arg:
1794 va_end(ap);
1795 return CELT_BAD_ARG;
John Ridges454d1d02009-05-21 22:38:39 -04001796bad_request:
1797 va_end(ap);
1798 return CELT_UNIMPLEMENTED;
1799}
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001800
1801const char *celt_strerror(int error)
1802{
1803 static const char *error_strings[8] = {
1804 "success",
1805 "invalid argument",
1806 "invalid mode",
1807 "internal error",
1808 "corrupted stream",
1809 "request not implemented",
1810 "invalid state",
1811 "memory allocation failed"
1812 };
1813 if (error > 0 || error < -7)
1814 return "unknown error";
1815 else
1816 return error_strings[-error];
1817}
1818