blob: 8341e06b10c53b6596ad2f69870b0efef1809211 [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,
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400395 int len, int C, int isTransient, int *tf_res, int nbCompressedBytes, celt_norm *X,
396 int N0, int LM, int *tf_sum)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400397{
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400398 int i;
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400399 VARDECL(int, metric);
400 int cost0;
401 int cost1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400402 VARDECL(int, path0);
403 VARDECL(int, path1);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400404 VARDECL(celt_norm, tmp);
405 int lambda;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400406 int tf_select=0;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400407 SAVE_STACK;
408
Jean-Marc Valin6bf3b0a2010-07-19 14:32:40 -0400409 /* FIXME: Should check number of bytes *left* */
410 if (nbCompressedBytes<15*C)
411 {
412 for (i=0;i<len;i++)
413 tf_res[i] = 0;
414 return 0;
415 }
Jean-Marc Valin73319772010-05-28 21:12:39 -0400416 if (nbCompressedBytes<40)
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400417 lambda = 10;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400418 else if (nbCompressedBytes<60)
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400419 lambda = 4;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400420 else if (nbCompressedBytes<100)
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400421 lambda = 2;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400422 else
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400423 lambda = 1;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400424
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400425 ALLOC(metric, len, int);
426 ALLOC(tmp, (m->eBands[len]-m->eBands[len-1])<<LM, celt_norm);
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400427 ALLOC(path0, len, int);
428 ALLOC(path1, len, int);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400429
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400430 *tf_sum = 0;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400431 for (i=0;i<len;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400432 {
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400433 int j, k, N;
434 celt_word32 L1, best_L1;
435 int best_level=0;
436 N = (m->eBands[i+1]-m->eBands[i])<<LM;
437 for (j=0;j<N;j++)
438 tmp[j] = X[j+(m->eBands[i]<<LM)];
439 if (C==2)
440 for (j=0;j<N;j++)
441 tmp[j] = ADD16(tmp[j],X[N0+j+(m->eBands[i]<<LM)]);
442 L1=0;
443 for (j=0;j<N;j++)
444 L1 += ABS16(tmp[j]);
445 /* Biasing towards better freq resolution (because of spreading) */
446 if (isTransient)
447 L1 += MULT16_32_Q15(QCONST16(.08,15), L1);
448 else
449 L1 -= MULT16_32_Q15(QCONST16(.08,15), L1);
450 best_L1 = L1;
451 /*printf ("%f ", L1);*/
452 for (k=0;k<LM;k++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400453 {
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400454 if (isTransient)
455 haar1(tmp, N>>(LM-k), 1<<(LM-k));
456 else
457 haar1(tmp, N>>k, 1<<k);
458
459 L1=0;
460 for (j=0;j<N;j++)
461 L1 += ABS16(tmp[j]);
462
463 /*printf ("%f ", L1);*/
464 if (L1 < best_L1)
465 {
466 best_L1 = L1;
467 best_level = k+1;
468 }
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400469 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400470 /*printf ("%d ", isTransient ? LM-best_level : best_level);*/
471 if (isTransient)
472 metric[i] = best_level;
473 else
474 metric[i] = -best_level;
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400475 *tf_sum += metric[i];
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400476 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400477 /*printf("\n");*/
478 /* FIXME: Figure out how to set this */
479 tf_select = 1;
480
Jean-Marc Valin88232612010-05-28 18:01:02 -0400481 cost0 = 0;
482 cost1 = lambda;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400483 /* Viterbi forward pass */
484 for (i=1;i<len;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400485 {
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400486 int curr0, curr1;
487 int from0, from1;
Jean-Marc Valin581fdba2010-05-28 06:56:23 -0400488
Jean-Marc Valin88232612010-05-28 18:01:02 -0400489 from0 = cost0;
490 from1 = cost1 + lambda;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400491 if (from0 < from1)
492 {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400493 curr0 = from0;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400494 path0[i]= 0;
495 } else {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400496 curr0 = from1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400497 path0[i]= 1;
498 }
499
Jean-Marc Valin88232612010-05-28 18:01:02 -0400500 from0 = cost0 + lambda;
501 from1 = cost1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400502 if (from0 < from1)
503 {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400504 curr1 = from0;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400505 path1[i]= 0;
506 } else {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400507 curr1 = from1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400508 path1[i]= 1;
509 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400510 cost0 = curr0 + abs(metric[i]-tf_select_table[LM][4*isTransient+2*tf_select+0]);
511 cost1 = curr1 + abs(metric[i]-tf_select_table[LM][4*isTransient+2*tf_select+1]);
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400512 }
Jean-Marc Valin88232612010-05-28 18:01:02 -0400513 tf_res[len-1] = cost0 < cost1 ? 0 : 1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400514 /* Viterbi backward pass to check the decisions */
515 for (i=len-2;i>=0;i--)
516 {
517 if (tf_res[i+1] == 1)
518 tf_res[i] = path1[i+1];
519 else
520 tf_res[i] = path0[i+1];
521 }
Jean-Marc Valin71ae6d42010-06-27 21:55:08 -0400522 RESTORE_STACK;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400523 return tf_select;
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400524}
525
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400526static 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 -0400527{
528 int curr, i;
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400529 ec_enc_bit_prob(enc, tf_res[start], isTransient ? 16384 : 4096);
530 curr = tf_res[start];
531 for (i=start+1;i<end;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400532 {
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400533 ec_enc_bit_prob(enc, tf_res[i] ^ curr, isTransient ? 4096 : 2048);
534 curr = tf_res[i];
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400535 }
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400536 ec_enc_bits(enc, tf_select, 1);
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400537 for (i=start;i<end;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400538 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400539 /*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 -0400540}
541
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400542static 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 -0400543{
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400544 int i, curr, tf_select;
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400545 tf_res[start] = ec_dec_bit_prob(dec, isTransient ? 16384 : 4096);
546 curr = tf_res[start];
547 for (i=start+1;i<end;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400548 {
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400549 tf_res[i] = ec_dec_bit_prob(dec, isTransient ? 4096 : 2048) ^ curr;
550 curr = tf_res[i];
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400551 }
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400552 tf_select = ec_dec_bits(dec, 1);
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400553 for (i=start;i<end;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400554 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400555}
556
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400557#ifdef FIXED_POINT
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400558int 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 +1100559{
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400560#else
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400561int 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 -0400562{
563#endif
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -0400564 int i, c, N, NN;
Jean-Marc Valinc890b582008-08-01 22:26:49 -0400565 int bits;
Jean-Marc Valinbc799912008-11-07 22:53:13 -0500566 int has_fold=1;
Jean-Marc Valin8679a802008-10-18 07:44:35 -0400567 ec_byte_buffer buf;
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400568 ec_enc _enc;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400569 VARDECL(celt_sig, in);
570 VARDECL(celt_sig, freq);
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400571 VARDECL(celt_norm, X);
572 VARDECL(celt_ener, bandE);
573 VARDECL(celt_word16, bandLogE);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400574 VARDECL(int, fine_quant);
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400575 VARDECL(celt_word16, error);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400576 VARDECL(int, pulses);
577 VARDECL(int, offsets);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -0400578 VARDECL(int, fine_priority);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400579 VARDECL(int, tf_res);
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400580 celt_sig *_overlap_mem;
581 celt_word16 *oldBandE;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000582 int shortBlocks=0;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400583 int isTransient=0;
Jean-Marc Valin0be05b02010-07-16 14:23:03 -0400584 int transient_time, transient_time_quant;
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000585 int transient_shift;
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -0400586 int resynth;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400587 const int C = CHANNELS(st->channels);
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400588 int mdct_weight_shift = 0;
589 int mdct_weight_pos=0;
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400590 int LM, M;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400591 int tf_select;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400592 int nbFilledBytes, nbAvailableBytes;
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400593 int effEnd;
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400594 int codedBands;
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400595 int tf_sum;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -0400596 int alloc_trim;
Jean-Marc Valin8600f692008-02-29 15:14:12 +1100597 SAVE_STACK;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100598
Gregory Maxwell0719f6f2009-07-09 17:07:24 -0400599 if (nbCompressedBytes<0 || pcm==NULL)
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400600 return CELT_BAD_ARG;
Gregory Maxwell520eeae2009-02-09 01:33:21 -0500601
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400602 for (LM=0;LM<4;LM++)
603 if (st->mode->shortMdctSize<<LM==frame_size)
604 break;
605 if (LM>=MAX_CONFIG_SIZES)
606 return CELT_BAD_ARG;
607 M=1<<LM;
Jean-Marc Valin8679a802008-10-18 07:44:35 -0400608
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400609 _overlap_mem = st->in_mem+C*(st->overlap);
610 oldBandE = (celt_word16*)(st->in_mem+2*C*(st->overlap));
611
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400612 if (enc==NULL)
613 {
614 ec_byte_writeinit_buffer(&buf, compressed, nbCompressedBytes);
615 ec_enc_init(&_enc,&buf);
616 enc = &_enc;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400617 nbFilledBytes=0;
618 } else {
Jean-Marc Valinbdcaaf72010-07-05 13:52:41 -0400619 nbFilledBytes=(ec_enc_tell(enc, 0)+4)>>3;
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400620 }
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400621 nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
622
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400623 effEnd = st->end;
624 if (effEnd > st->mode->effEBands)
625 effEnd = st->mode->effEBands;
626
Jean-Marc Valin04752672010-05-05 07:21:21 -0400627 N = M*st->mode->shortMdctSize;
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -0400628 ALLOC(in, C*(N+st->overlap), celt_sig);
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100629
Jean-Marc Valinbdb58832008-04-20 17:42:10 +1000630 CELT_COPY(in, st->in_mem, C*st->overlap);
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100631 for (c=0;c<C;c++)
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +1100632 {
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400633 const celt_word16 * restrict pcmp = pcm+c;
634 celt_sig * restrict inp = in+C*st->overlap+c;
Jean-Marc Valinb886ddc2008-03-25 14:38:55 +1100635 for (i=0;i<N;i++)
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100636 {
Jean-Marc Valin62290062008-04-20 22:16:02 +1000637 /* Apply pre-emphasis */
Jean-Marc Valinaf1fce92010-07-16 11:05:06 -0400638 celt_sig tmp = MULT16_16(st->mode->preemph[2], SCALEIN(*pcmp));
639 *inp = tmp + st->preemph_memE[c];
640 st->preemph_memE[c] = MULT16_32_Q15(st->mode->preemph[1], *inp)
641 - MULT16_32_Q15(st->mode->preemph[0], tmp);
Jean-Marc Valin62290062008-04-20 22:16:02 +1000642 inp += C;
643 pcmp += C;
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100644 }
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +1100645 }
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -0400646 CELT_COPY(st->in_mem, in+C*N, C*st->overlap);
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400647
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -0500648 /* Transient handling */
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400649 transient_time = -1;
Jean-Marc Valin0be05b02010-07-16 14:23:03 -0400650 transient_time_quant = -1;
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400651 transient_shift = 0;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400652 isTransient = 0;
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400653
Jean-Marc Valin8cbea172010-08-05 15:22:57 -0400654 resynth = optional_resynthesis!=NULL;
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -0400655
Jean-Marc Valinf9fdbff2010-09-05 21:02:38 -0400656 if (st->complexity > 1 && LM>0)
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400657 {
658 isTransient = M > 1 &&
659 transient_analysis(in, N+st->overlap, C, &transient_time,
660 &transient_shift, &st->frame_max, st->overlap);
661 } else {
662 isTransient = 0;
663 }
664 if (isTransient)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000665 {
Jean-Marc Valin7028d622008-07-10 23:06:58 -0400666#ifndef FIXED_POINT
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400667 float gain_1;
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000668#endif
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400669 /* Apply the inverse shaping window */
670 if (transient_shift)
671 {
Jean-Marc Valin0be05b02010-07-16 14:23:03 -0400672 transient_time_quant = transient_time*(celt_int32)8000/st->mode->Fs;
673 transient_time = transient_time_quant*(celt_int32)st->mode->Fs/8000;
Jean-Marc Valin7028d622008-07-10 23:06:58 -0400674#ifdef FIXED_POINT
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400675 for (c=0;c<C;c++)
676 for (i=0;i<16;i++)
677 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]);
678 for (c=0;c<C;c++)
679 for (i=transient_time;i<N+st->overlap;i++)
680 in[C*i+c] = SHR32(in[C*i+c], transient_shift);
Jean-Marc Valin7028d622008-07-10 23:06:58 -0400681#else
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400682 for (c=0;c<C;c++)
683 for (i=0;i<16;i++)
684 in[C*(transient_time+i-16)+c] /= 1+transientWindow[i]*((1<<transient_shift)-1);
Jean-Marc Valin12996402010-08-04 09:13:24 -0400685 gain_1 = 1.f/(1<<transient_shift);
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400686 for (c=0;c<C;c++)
687 for (i=transient_time;i<N+st->overlap;i++)
688 in[C*i+c] *= gain_1;
Jean-Marc Valin7028d622008-07-10 23:06:58 -0400689#endif
Jean-Marc Valin528f4b82008-06-29 03:46:39 +1000690 }
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400691 has_fold = 1;
Jean-Marc Valin12b22482008-06-16 14:13:05 +1000692 }
Jean-Marc Valinc5f2a9d2008-10-26 22:00:26 -0400693
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400694 if (isTransient)
695 shortBlocks = M;
696 else
697 shortBlocks = 0;
698
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400699 ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
700 ALLOC(bandE,st->mode->nbEBands*C, celt_ener);
701 ALLOC(bandLogE,st->mode->nbEBands*C, celt_word16);
Jean-Marc Valin32ec58c2009-05-01 21:28:58 -0400702 /* Compute MDCTs */
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400703 compute_mdcts(st->mode, shortBlocks, in, freq, C, LM);
Jean-Marc Valin08a82ff2009-06-14 14:05:19 -0400704
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400705 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
Jean-Marc Valin8d4ac152008-02-29 17:24:02 +1100706
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400707 compute_band_energies(st->mode, freq, bandE, effEnd, C, M);
Jean-Marc Valin504fb3c2010-08-06 15:56:22 -0400708
709 amp2Log2(st->mode, effEnd, st->end, bandE, bandLogE, C);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400710
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100711 /* Band normalisation */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400712 normalise_bands(st->mode, freq, X, bandE, effEnd, C, M);
Jean-Marc Valin4c77ea92009-09-14 22:50:41 -0400713
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400714 NN = M*st->mode->eBands[effEnd];
Jean-Marc Valin9f89cab2010-05-21 14:18:38 -0400715 if (shortBlocks && !transient_shift)
Jean-Marc Valin88619552009-10-04 21:35:36 -0400716 {
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400717 celt_word32 sum[8]={1,1,1,1,1,1,1,1};
Jean-Marc Valin88619552009-10-04 21:35:36 -0400718 int m;
719 for (c=0;c<C;c++)
720 {
721 m=0;
722 do {
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400723 celt_word32 tmp=0;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400724 for (i=m+c*N;i<c*N+NN;i+=M)
Jean-Marc Valin88619552009-10-04 21:35:36 -0400725 tmp += ABS32(X[i]);
726 sum[m++] += tmp;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400727 } while (m<M);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400728 }
729 m=0;
730#ifdef FIXED_POINT
731 do {
732 if (SHR32(sum[m+1],3) > sum[m])
733 {
734 mdct_weight_shift=2;
735 mdct_weight_pos = m;
736 } else if (SHR32(sum[m+1],1) > sum[m] && mdct_weight_shift < 2)
737 {
738 mdct_weight_shift=1;
739 mdct_weight_pos = m;
740 }
741 m++;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400742 } while (m<M-1);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400743#else
744 do {
745 if (sum[m+1] > 8*sum[m])
746 {
747 mdct_weight_shift=2;
748 mdct_weight_pos = m;
749 } else if (sum[m+1] > 2*sum[m] && mdct_weight_shift < 2)
750 {
751 mdct_weight_shift=1;
752 mdct_weight_pos = m;
753 }
754 m++;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400755 } while (m<M-1);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400756#endif
757 if (mdct_weight_shift)
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400758 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 -0400759 }
760
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400761 ALLOC(tf_res, st->mode->nbEBands, int);
Jean-Marc Valin5e7f02d2010-08-08 09:48:22 -0400762 /* Needs to be before coarse energy quantization because otherwise the energy gets modified */
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400763 tf_select = tf_analysis(st->mode, bandLogE, oldBandE, effEnd, C, isTransient, tf_res, nbAvailableBytes, X, N, LM, &tf_sum);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400764 for (i=effEnd;i<st->end;i++)
765 tf_res[i] = tf_res[effEnd-1];
766
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400767 ALLOC(error, C*st->mode->nbEBands, celt_word16);
Jean-Marc Valin5e7f02d2010-08-08 09:48:22 -0400768 quant_coarse_energy(st->mode, st->start, st->end, effEnd, bandLogE,
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400769 oldBandE, nbCompressedBytes*8, st->mode->prob,
Jean-Marc Valin1b36d6c2010-08-31 17:21:52 -0400770 error, enc, C, LM, nbAvailableBytes, st->force_intra,
771 &st->delayedIntra, st->complexity >= 4);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400772
Jean-Marc Valinf9fdbff2010-09-05 21:02:38 -0400773 if (LM > 0)
774 ec_enc_bit_prob(enc, shortBlocks!=0, 8192);
Jean-Marc Valin4c77ea92009-09-14 22:50:41 -0400775
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -0400776 if (shortBlocks)
777 {
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -0400778 if (transient_shift)
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400779 {
Jean-Marc Valin0be05b02010-07-16 14:23:03 -0400780 int max_time = (N+st->mode->overlap)*(celt_int32)8000/st->mode->Fs;
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400781 ec_enc_uint(enc, transient_shift, 4);
Jean-Marc Valin0be05b02010-07-16 14:23:03 -0400782 ec_enc_uint(enc, transient_time_quant, max_time);
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400783 } else {
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400784 ec_enc_uint(enc, mdct_weight_shift, 4);
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400785 if (mdct_weight_shift && M!=2)
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400786 ec_enc_uint(enc, mdct_weight_pos, M-1);
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400787 }
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -0400788 }
Jean-Marc Valinc890b582008-08-01 22:26:49 -0400789
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -0400790 tf_encode(st->start, st->end, isTransient, tf_res, nbAvailableBytes, LM, tf_select, enc);
791
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400792 if (shortBlocks || st->complexity < 3)
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -0400793 {
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400794 if (st->complexity == 0)
795 {
796 has_fold = 0;
797 st->fold_decision = 3;
798 } else {
799 has_fold = 1;
800 st->fold_decision = 1;
801 }
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -0400802 } else {
803 has_fold = folding_decision(st->mode, X, &st->tonal_average, &st->fold_decision, effEnd, C, M);
804 }
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400805 ec_enc_bit_prob(enc, has_fold>>1, 8192);
806 ec_enc_bit_prob(enc, has_fold&1, (has_fold>>1) ? 32768 : 49152);
807
Jean-Marc Valinf1fea662010-10-09 22:58:52 -0400808 ALLOC(offsets, st->mode->nbEBands, int);
809
810 for (i=0;i<st->mode->nbEBands;i++)
811 offsets[i] = 0;
812 /* Dynamic allocation code */
813 /* Make sure that dynamic allocation can't make us bust the budget */
814 if (nbCompressedBytes > 30)
815 {
816 int t1, t2;
817 if (LM <= 1)
818 {
819 t1 = 3;
820 t2 = 5;
821 } else {
822 t1 = 2;
823 t2 = 4;
824 }
825 for (i=1;i<st->mode->nbEBands-1;i++)
826 {
827 if (2*bandLogE[i]-bandLogE[i-1]-bandLogE[i+1] > SHL16(t1,DB_SHIFT))
828 offsets[i] += 1;
829 if (2*bandLogE[i]-bandLogE[i-1]-bandLogE[i+1] > SHL16(t2,DB_SHIFT))
830 offsets[i] += 1;
831 }
832 }
833 for (i=0;i<st->mode->nbEBands;i++)
834 {
835 int j;
836 ec_enc_bit_prob(enc, offsets[i]!=0, 1024);
837 if (offsets[i]!=0)
838 {
839 for (j=0;j<offsets[i]-1;j++)
840 ec_enc_bit_prob(enc, 1, 32768);
841 ec_enc_bit_prob(enc, 0, 32768);
842 }
843 offsets[i] *= (6<<BITRES);
844 }
845 {
846 int trim_index = 3;
847
848 /*if (isTransient)
849 trim_index--;
850 if (has_fold==0)
851 trim_index--;
852 if (C==2)
853 trim_index--;*/
854 alloc_trim = trim_coef[trim_index];
855 ec_encode_bin(enc, trim_cdf[trim_index], trim_cdf[trim_index+1], 7);
856 }
857
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400858 /* Variable bitrate */
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -0400859 if (st->vbr_rate_norm>0)
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400860 {
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400861 celt_word16 alpha;
Jean-Marc Valin25767d12009-10-21 23:24:18 -0400862 celt_int32 delta;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400863 /* The target rate in 16th bits per frame */
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -0400864 celt_int32 vbr_rate;
865 celt_int32 target;
866 celt_int32 vbr_bound, max_allowed;
867
868 vbr_rate = M*st->vbr_rate_norm;
869
870 /* Computes the max bit-rate allowed in VBR more to avoid busting the budget */
871 vbr_bound = vbr_rate;
872 max_allowed = (vbr_rate + vbr_bound - st->vbr_reservoir)>>(BITRES+3);
873 if (max_allowed < 4)
874 max_allowed = 4;
875 if (max_allowed < nbAvailableBytes)
876 nbAvailableBytes = max_allowed;
877 target=vbr_rate;
878
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400879 /* Shortblocks get a large boost in bitrate, but since they
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400880 are uncommon long blocks are not greatly affected */
881 if (shortBlocks || tf_sum < -2*(st->end-st->start))
882 target*=2;
883 else if (tf_sum < -(st->end-st->start))
884 target = 3*target/2;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400885 else if (M > 1)
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400886 target-=(target+14)/28;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400887
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400888 /* The average energy is removed from the target and the actual
889 energy added*/
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400890 target=target+st->vbr_offset-(50<<BITRES)+ec_enc_tell(enc, BITRES);
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400891
892 /* 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 -0400893 target=IMIN(nbAvailableBytes,target);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400894 /* Make the adaptation coef (alpha) higher at the beginning */
895 if (st->vbr_count < 990)
896 {
897 st->vbr_count++;
898 alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+10),16));
899 /*printf ("%d %d\n", st->vbr_count+10, alpha);*/
900 } else
901 alpha = QCONST16(.001f,15);
902
903 /* By how much did we "miss" the target on that frame */
Jean-Marc Valin8cc945c2010-05-29 08:07:18 -0400904 delta = (8<<BITRES)*(celt_int32)target - vbr_rate;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400905 /* How many bits have we used in excess of what we're allowed */
906 st->vbr_reservoir += delta;
907 /*printf ("%d\n", st->vbr_reservoir);*/
908
909 /* Compute the offset we need to apply in order to reach the target */
Jean-Marc Valin736efd62010-08-31 11:52:45 -0400910 st->vbr_drift += (celt_int32)MULT16_32_Q15(alpha,delta-st->vbr_offset-st->vbr_drift);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400911 st->vbr_offset = -st->vbr_drift;
912 /*printf ("%d\n", st->vbr_drift);*/
913
914 /* We could use any multiple of vbr_rate as bound (depending on the delay) */
Jean-Marc Valin25767d12009-10-21 23:24:18 -0400915 if (st->vbr_reservoir < 0)
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400916 {
917 /* We're under the min value -- increase rate */
918 int adjust = 1-(st->vbr_reservoir-1)/(8<<BITRES);
919 st->vbr_reservoir += adjust*(8<<BITRES);
Jean-Marc Valin45f11102009-10-22 00:12:31 -0400920 target += adjust;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400921 /*printf ("+%d\n", adjust);*/
922 }
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400923 if (target < nbAvailableBytes)
924 nbAvailableBytes = target;
925 nbCompressedBytes = nbAvailableBytes + nbFilledBytes;
926
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400927 /* This moves the raw bits to take into account the new compressed size */
Jean-Marc Valine6108642009-08-01 23:05:47 +0200928 ec_byte_shrink(&buf, nbCompressedBytes);
Gregory Maxwell888d8ce2009-05-21 04:21:53 -0400929 }
930
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -0400931 /* Bit allocation */
932 ALLOC(fine_quant, st->mode->nbEBands, int);
933 ALLOC(pulses, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -0400934 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +1100935
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400936 bits = nbCompressedBytes*8 - ec_enc_tell(enc, 0) - 1;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -0400937 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 -0500938
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400939 quant_fine_energy(st->mode, st->start, st->end, bandE, oldBandE, error, fine_quant, enc, C);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400940
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +0200941#ifdef MEASURE_NORM_MSE
Jean-Marc Valin44092242010-07-29 18:32:54 +0200942 float X0[3000];
943 float bandE0[60];
944 for (c=0;c<C;c++)
945 for (i=0;i<N;i++)
946 X0[i+c*N] = X[i+c*N];
947 for (i=0;i<C*st->mode->nbEBands;i++)
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +0200948 bandE0[i] = bandE[i];
949#endif
950
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100951 /* Residual quantisation */
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400952 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 -0400953
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400954 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 -0400955
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -0500956 /* Re-synthesis of the coded audio if required */
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -0400957 if (resynth)
Jean-Marc Valin18ddc022008-02-22 14:24:50 +1100958 {
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400959 VARDECL(celt_sig, _out_mem);
960 celt_sig *out_mem[2];
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400961 celt_sig *overlap_mem[2];
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400962
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400963 log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
Jean-Marc Valinbc272de2010-08-02 09:41:31 -0400964
965#ifdef MEASURE_NORM_MSE
966 measure_norm_mse(st->mode, X, X0, bandE, bandE0, M, N, C);
967#endif
968
Jean-Marc Valinaa936252009-05-29 22:14:20 -0400969 if (mdct_weight_shift)
970 {
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400971 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 -0400972 }
Jean-Marc Valin88619552009-10-04 21:35:36 -0400973
974 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400975 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valin88619552009-10-04 21:35:36 -0400976
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -0400977 for (c=0;c<C;c++)
978 for (i=0;i<M*st->mode->eBands[st->start];i++)
979 freq[c*N+i] = 0;
980 for (c=0;c<C;c++)
981 for (i=M*st->mode->eBands[st->end];i<N;i++)
982 freq[c*N+i] = 0;
983
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400984 ALLOC(_out_mem, C*N, celt_sig);
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400985
986 for (c=0;c<C;c++)
987 {
988 overlap_mem[c] = _overlap_mem + c*st->overlap;
989 out_mem[c] = _out_mem+c*N;
990 }
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400991
992 compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time,
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400993 transient_shift, out_mem, overlap_mem, C, LM);
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400994
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400995 /* De-emphasis and put everything back at the right place
996 in the synthesis history */
Jean-Marc Valind56c6102010-05-07 20:30:22 -0400997 if (optional_resynthesis != NULL) {
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400998 deemphasis(out_mem, optional_resynthesis, N, C, st->mode->preemph, st->preemph_memD);
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400999
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +11001000 }
Jean-Marc Valind9b95652008-08-31 23:34:47 -04001001 }
Gregory Maxwell54547f12009-02-16 18:56:44 -05001002
Jean-Marc Valin30d51252010-06-21 17:55:28 -04001003 /* If there's any room left (can only happen for very high rates),
1004 fill it with zeros */
Jean-Marc Valin5d774e02010-08-04 17:17:18 -04001005 while (ec_enc_tell(enc,0) + 8 <= nbCompressedBytes*8)
Jean-Marc Valin30d51252010-06-21 17:55:28 -04001006 ec_enc_bits(enc, 0, 8);
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001007 ec_enc_done(enc);
Jean-Marc Valinc871c8d2009-06-09 00:57:00 -04001008
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001009 RESTORE_STACK;
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001010 if (ec_enc_get_error(enc))
Jean-Marc Valin9d785af2010-07-18 09:42:05 -04001011 return CELT_CORRUPTED_DATA;
1012 else
1013 return nbCompressedBytes;
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11001014}
1015
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001016#ifdef FIXED_POINT
1017#ifndef DISABLE_FLOAT_API
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001018int 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 -04001019{
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001020 int j, ret, C, N, LM, M;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001021 VARDECL(celt_int16, in);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -04001022 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001023
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001024 if (pcm==NULL)
1025 return CELT_BAD_ARG;
1026
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001027 for (LM=0;LM<4;LM++)
1028 if (st->mode->shortMdctSize<<LM==frame_size)
1029 break;
1030 if (LM>=MAX_CONFIG_SIZES)
1031 return CELT_BAD_ARG;
1032 M=1<<LM;
1033
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001034 C = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001035 N = M*st->mode->shortMdctSize;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001036 ALLOC(in, C*N, celt_int16);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001037
1038 for (j=0;j<C*N;j++)
1039 in[j] = FLOAT2INT16(pcm[j]);
1040
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001041 if (optional_resynthesis != NULL) {
1042 ret=celt_encode_with_ec(st,in,in,frame_size,compressed,nbCompressedBytes, enc);
Gregory Maxwellb0a73a02008-12-12 16:54:25 -05001043 for (j=0;j<C*N;j++)
Jean-Marc Valinae01e112010-08-03 21:43:41 -04001044 optional_resynthesis[j]=in[j]*(1.f/32768.f);
Gregory Maxwell82595312008-09-30 18:20:14 -04001045 } else {
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001046 ret=celt_encode_with_ec(st,in,NULL,frame_size,compressed,nbCompressedBytes, enc);
Gregory Maxwell82595312008-09-30 18:20:14 -04001047 }
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001048 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001049 return ret;
1050
1051}
1052#endif /*DISABLE_FLOAT_API*/
1053#else
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001054int 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 -04001055{
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001056 int j, ret, C, N, LM, M;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001057 VARDECL(celt_sig, in);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -04001058 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001059
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001060 if (pcm==NULL)
1061 return CELT_BAD_ARG;
1062
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001063 for (LM=0;LM<4;LM++)
1064 if (st->mode->shortMdctSize<<LM==frame_size)
1065 break;
1066 if (LM>=MAX_CONFIG_SIZES)
1067 return CELT_BAD_ARG;
1068 M=1<<LM;
1069
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001070 C=CHANNELS(st->channels);
Jean-Marc Valin04752672010-05-05 07:21:21 -04001071 N=M*st->mode->shortMdctSize;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001072 ALLOC(in, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001073 for (j=0;j<C*N;j++) {
1074 in[j] = SCALEOUT(pcm[j]);
1075 }
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001076
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001077 if (optional_resynthesis != NULL) {
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001078 ret = celt_encode_with_ec_float(st,in,in,frame_size,compressed,nbCompressedBytes, enc);
Gregory Maxwell82595312008-09-30 18:20:14 -04001079 for (j=0;j<C*N;j++)
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001080 optional_resynthesis[j] = FLOAT2INT16(in[j]);
Gregory Maxwell82595312008-09-30 18:20:14 -04001081 } else {
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001082 ret = celt_encode_with_ec_float(st,in,NULL,frame_size,compressed,nbCompressedBytes, enc);
Gregory Maxwell82595312008-09-30 18:20:14 -04001083 }
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001084 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001085 return ret;
1086}
1087#endif
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +11001088
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001089int celt_encode(CELTEncoder * restrict st, const celt_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1090{
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001091 return celt_encode_with_ec(st, pcm, NULL, frame_size, compressed, nbCompressedBytes, NULL);
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001092}
1093
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001094#ifndef DISABLE_FLOAT_API
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001095int celt_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1096{
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001097 return celt_encode_with_ec_float(st, pcm, NULL, frame_size, compressed, nbCompressedBytes, NULL);
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001098}
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001099#endif /* DISABLE_FLOAT_API */
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001100
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001101int celt_encode_resynthesis(CELTEncoder * restrict st, const celt_int16 * pcm, celt_int16 * optional_resynthesis, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1102{
1103 return celt_encode_with_ec(st, pcm, optional_resynthesis, frame_size, compressed, nbCompressedBytes, NULL);
1104}
1105
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001106#ifndef DISABLE_FLOAT_API
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001107int celt_encode_resynthesis_float(CELTEncoder * restrict st, const float * pcm, float * optional_resynthesis, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1108{
1109 return celt_encode_with_ec_float(st, pcm, optional_resynthesis, frame_size, compressed, nbCompressedBytes, NULL);
1110}
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001111#endif /* DISABLE_FLOAT_API */
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001112
1113
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001114int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...)
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001115{
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001116 va_list ap;
Gregory Maxwell17169992009-06-04 15:15:34 -04001117
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001118 va_start(ap, request);
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001119 switch (request)
1120 {
Gregory Maxwellf3b44ef2009-06-03 13:37:45 -04001121 case CELT_GET_MODE_REQUEST:
1122 {
1123 const CELTMode ** value = va_arg(ap, const CELTMode**);
1124 if (value==0)
1125 goto bad_arg;
1126 *value=st->mode;
1127 }
1128 break;
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001129 case CELT_SET_COMPLEXITY_REQUEST:
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001130 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001131 int value = va_arg(ap, celt_int32);
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001132 if (value<0 || value>10)
1133 goto bad_arg;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001134 st->complexity = value;
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001135 }
1136 break;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001137 case CELT_SET_START_BAND_REQUEST:
1138 {
1139 celt_int32 value = va_arg(ap, celt_int32);
1140 if (value<0 || value>=st->mode->nbEBands)
1141 goto bad_arg;
1142 st->start = value;
1143 }
1144 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001145 case CELT_SET_END_BAND_REQUEST:
1146 {
1147 celt_int32 value = va_arg(ap, celt_int32);
1148 if (value<0 || value>=st->mode->nbEBands)
1149 goto bad_arg;
1150 st->end = value;
1151 }
1152 break;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001153 case CELT_SET_PREDICTION_REQUEST:
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001154 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001155 int value = va_arg(ap, celt_int32);
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001156 if (value<0 || value>2)
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001157 goto bad_arg;
1158 if (value==0)
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001159 {
1160 st->force_intra = 1;
Gregory Maxwella80958b2009-06-29 12:48:57 -04001161 } else if (value==1) {
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001162 st->force_intra = 0;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001163 } else {
1164 st->force_intra = 0;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001165 }
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001166 }
1167 break;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001168 case CELT_SET_VBR_RATE_REQUEST:
1169 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001170 celt_int32 value = va_arg(ap, celt_int32);
Jean-Marc Valin8cc945c2010-05-29 08:07:18 -04001171 int frame_rate;
1172 int N = st->mode->shortMdctSize;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001173 if (value<0)
1174 goto bad_arg;
1175 if (value>3072000)
1176 value = 3072000;
Jean-Marc Valin8cc945c2010-05-29 08:07:18 -04001177 frame_rate = ((st->mode->Fs<<3)+(N>>1))/N;
1178 st->vbr_rate_norm = ((value<<(BITRES+3))+(frame_rate>>1))/frame_rate;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001179 }
1180 break;
John Ridges454d1d02009-05-21 22:38:39 -04001181 case CELT_RESET_STATE:
1182 {
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001183 CELT_MEMSET((char*)&st->ENCODER_RESET_START, 0,
1184 celt_encoder_get_size(st->mode, st->channels)-
1185 ((char*)&st->ENCODER_RESET_START - (char*)st));
John Ridges454d1d02009-05-21 22:38:39 -04001186 st->delayedIntra = 1;
John Ridges5378bf82010-02-12 07:08:01 -05001187 st->fold_decision = 1;
Jean-Marc Valin628c0252010-04-16 20:57:56 -04001188 st->tonal_average = QCONST16(1.f,8);
John Ridges454d1d02009-05-21 22:38:39 -04001189 }
1190 break;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001191 default:
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001192 goto bad_request;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001193 }
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001194 va_end(ap);
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001195 return CELT_OK;
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001196bad_arg:
1197 va_end(ap);
1198 return CELT_BAD_ARG;
1199bad_request:
1200 va_end(ap);
1201 return CELT_UNIMPLEMENTED;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001202}
1203
Jean-Marc Valin56522ad2009-06-05 17:17:25 -04001204/**********************************************************************/
1205/* */
1206/* DECODER */
1207/* */
1208/**********************************************************************/
Jean-Marc Valineafbdd52009-04-27 19:35:09 -04001209#define DECODE_BUFFER_SIZE 2048
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001210
Jean-Marc Valin276de722008-02-20 17:45:51 +11001211/** Decoder state
1212 @brief Decoder state
1213 */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001214struct CELTDecoder {
1215 const CELTMode *mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001216 int overlap;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001217 int channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001218
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001219 int start, end;
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001220
1221 /* Everything beyond this point gets cleared on a reset */
1222#define DECODER_RESET_START last_pitch_index
1223
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001224 int last_pitch_index;
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001225 int loss_count;
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001226
1227 celt_sig preemph_memD[2];
1228
Jean-Marc Valinca8b9922010-08-27 16:23:03 -04001229 celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */
1230 /* celt_word16 lpc[], Size = channels*LPC_ORDER */
1231 /* celt_word16 oldEBands[], Size = channels*mode->nbEBands */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001232};
1233
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001234int celt_decoder_get_size(const CELTMode *mode, int channels)
1235{
1236 int size = sizeof(struct CELTDecoder)
1237 + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig)
1238 + channels*LPC_ORDER*sizeof(celt_word16)
1239 + channels*mode->nbEBands*sizeof(celt_word16);
1240 return size;
1241}
1242
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001243CELTDecoder *celt_decoder_create(const CELTMode *mode, int channels, int *error)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001244{
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -04001245 return celt_decoder_init(
1246 (CELTDecoder *)celt_alloc(celt_decoder_get_size(mode, channels)),
1247 mode, channels, error);
1248}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001249
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -04001250CELTDecoder *celt_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels, int *error)
1251{
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001252 if (channels < 0 || channels > 2)
1253 {
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001254 if (error)
1255 *error = CELT_BAD_ARG;
1256 return NULL;
1257 }
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001258
Gregory Maxwell17169992009-06-04 15:15:34 -04001259 if (st==NULL)
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001260 {
1261 if (error)
1262 *error = CELT_ALLOC_FAIL;
Gregory Maxwell17169992009-06-04 15:15:34 -04001263 return NULL;
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001264 }
1265
Jean-Marc Valin6d3829f2010-08-27 17:52:38 -04001266 CELT_MEMSET((char*)st, 0, celt_decoder_get_size(mode, channels));
1267
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001268 st->mode = mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001269 st->overlap = mode->overlap;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001270 st->channels = channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001271
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001272 st->start = 0;
Jean-Marc Valin8952c452010-07-16 21:48:44 -04001273 st->end = st->mode->effEBands;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001274
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001275 st->loss_count = 0;
Gregory Maxwell17169992009-06-04 15:15:34 -04001276
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001277 if (error)
1278 *error = CELT_OK;
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001279 return st;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001280}
1281
Peter Kirk19f9dc92008-06-06 14:38:38 +02001282void celt_decoder_destroy(CELTDecoder *st)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001283{
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001284 celt_free(st);
1285}
1286
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001287static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict pcm, int N, int LM)
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001288{
Jean-Marc Valin04752672010-05-05 07:21:21 -04001289 int c;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11001290 int pitch_index;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001291 int overlap = st->mode->overlap;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001292 celt_word16 fade = Q15ONE;
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001293 int i, len;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001294 const int C = CHANNELS(st->channels);
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001295 int offset;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001296 celt_sig *out_mem[2];
1297 celt_sig *decode_mem[2];
1298 celt_sig *overlap_mem[2];
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001299 celt_word16 *lpc;
1300 celt_word16 *oldBandE;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001301 SAVE_STACK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001302
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001303 for (c=0;c<C;c++)
1304 {
1305 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
1306 out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
1307 overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
1308 }
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001309 lpc = (celt_word16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C);
1310 oldBandE = lpc+C*LPC_ORDER;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001311
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001312 len = N+st->mode->overlap;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001313
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001314 if (st->loss_count == 0)
1315 {
Jean-Marc Valin7a7c42a2009-11-25 20:38:52 -05001316 celt_word16 pitch_buf[MAX_PERIOD>>1];
Jean-Marc Valin294863b2009-11-08 22:29:54 +09001317 celt_word32 tmp=0;
Jean-Marc Valine465c142009-11-26 00:39:36 -05001318 celt_word32 mem0[2]={0,0};
1319 celt_word16 mem1[2]={0,0};
Jean-Marc Valin6202c742010-06-01 00:30:37 -04001320 int len2 = len;
1321 /* FIXME: This is a kludge */
1322 if (len2>MAX_PERIOD>>1)
1323 len2 = MAX_PERIOD>>1;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001324 pitch_downsample(out_mem, pitch_buf, MAX_PERIOD, MAX_PERIOD,
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001325 C, mem0, mem1);
Jean-Marc Valin6202c742010-06-01 00:30:37 -04001326 pitch_search(st->mode, pitch_buf+((MAX_PERIOD-len2)>>1), pitch_buf, len2,
1327 MAX_PERIOD-len2-100, &pitch_index, &tmp, 1<<LM);
1328 pitch_index = MAX_PERIOD-len2-pitch_index;
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001329 st->last_pitch_index = pitch_index;
1330 } else {
1331 pitch_index = st->last_pitch_index;
1332 if (st->loss_count < 5)
1333 fade = QCONST16(.8f,15);
1334 else
1335 fade = 0;
1336 }
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001337
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001338 for (c=0;c<C;c++)
1339 {
Jean-Marc Valin6202c742010-06-01 00:30:37 -04001340 /* FIXME: This is more memory than necessary */
1341 celt_word32 e[2*MAX_PERIOD];
1342 celt_word16 exc[2*MAX_PERIOD];
Jean-Marc Valin456eab22010-06-16 22:38:57 -04001343 celt_word32 ac[LPC_ORDER+1];
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001344 celt_word16 decay = 1;
1345 celt_word32 S1=0;
Jean-Marc Valin74128be2010-01-01 09:33:17 -05001346 celt_word16 mem[LPC_ORDER]={0};
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001347
Jean-Marc Valind5f99302009-12-16 22:42:32 -05001348 offset = MAX_PERIOD-pitch_index;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001349 for (i=0;i<MAX_PERIOD;i++)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001350 exc[i] = ROUND16(out_mem[c][i], SIG_SHIFT);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001351
1352 if (st->loss_count == 0)
1353 {
1354 _celt_autocorr(exc, ac, st->mode->window, st->mode->overlap,
1355 LPC_ORDER, MAX_PERIOD);
1356
Jean-Marc Valin456eab22010-06-16 22:38:57 -04001357 /* Noise floor -40 dB */
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001358#ifdef FIXED_POINT
1359 ac[0] += SHR32(ac[0],13);
1360#else
Jean-Marc Valinae01e112010-08-03 21:43:41 -04001361 ac[0] *= 1.0001f;
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001362#endif
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001363 /* Lag windowing */
1364 for (i=1;i<=LPC_ORDER;i++)
1365 {
1366 /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001367#ifdef FIXED_POINT
1368 ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);
1369#else
Jean-Marc Valinae01e112010-08-03 21:43:41 -04001370 ac[i] -= ac[i]*(.008f*i)*(.008f*i);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001371#endif
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001372 }
1373
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001374 _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001375 }
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001376 fir(exc, lpc+c*LPC_ORDER, exc, MAX_PERIOD, LPC_ORDER, mem);
Jean-Marc Valin74128be2010-01-01 09:33:17 -05001377 /*for (i=0;i<MAX_PERIOD;i++)printf("%d ", exc[i]); printf("\n");*/
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001378 /* Check if the waveform is decaying (and if so how fast) */
1379 {
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001380 celt_word32 E1=1, E2=1;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001381 int period;
1382 if (pitch_index <= MAX_PERIOD/2)
1383 period = pitch_index;
1384 else
1385 period = MAX_PERIOD/2;
1386 for (i=0;i<period;i++)
1387 {
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001388 E1 += SHR32(MULT16_16(exc[MAX_PERIOD-period+i],exc[MAX_PERIOD-period+i]),8);
1389 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 -05001390 }
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001391 if (E1 > E2)
1392 E1 = E2;
1393 decay = celt_sqrt(frac_div32(SHR(E1,1),E2));
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001394 }
1395
1396 /* Copy excitation, taking decay into account */
1397 for (i=0;i<len+st->mode->overlap;i++)
1398 {
1399 if (offset+i >= MAX_PERIOD)
1400 {
1401 offset -= pitch_index;
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001402 decay = MULT16_16_Q15(decay, decay);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001403 }
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001404 e[i] = SHL32(EXTEND32(MULT16_16_Q15(decay, exc[offset+i])), SIG_SHIFT);
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001405 S1 += SHR32(MULT16_16(out_mem[c][offset+i],out_mem[c][offset+i]),8);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001406 }
1407
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001408 iir(e, lpc+c*LPC_ORDER, e, len+st->mode->overlap, LPC_ORDER, mem);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001409
1410 {
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001411 celt_word32 S2=0;
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001412 for (i=0;i<len+overlap;i++)
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001413 S2 += SHR32(MULT16_16(e[i],e[i]),8);
Jean-Marc Valinfeca0952010-06-17 20:25:51 -04001414 /* This checks for an "explosion" in the synthesis */
1415#ifdef FIXED_POINT
1416 if (!(S1 > SHR32(S2,2)))
1417#else
1418 /* Float test is written this way to catch NaNs at the same time */
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05001419 if (!(S1 > 0.2f*S2))
Jean-Marc Valinfeca0952010-06-17 20:25:51 -04001420#endif
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05001421 {
1422 for (i=0;i<len+overlap;i++)
1423 e[i] = 0;
1424 } else if (S1 < S2)
1425 {
Jean-Marc Valin12996402010-08-04 09:13:24 -04001426 celt_word16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001427 for (i=0;i<len+overlap;i++)
Jean-Marc Valinfeca0952010-06-17 20:25:51 -04001428 e[i] = MULT16_16_Q15(ratio, e[i]);
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05001429 }
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001430 }
1431
1432 for (i=0;i<MAX_PERIOD+st->mode->overlap-N;i++)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001433 out_mem[c][i] = out_mem[c][N+i];
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001434
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001435 /* Apply TDAC to the concealed audio so that it blends with the
1436 previous and next frames */
1437 for (i=0;i<overlap/2;i++)
1438 {
Jean-Marc Valind69c1cb2009-12-28 00:34:29 -05001439 celt_word32 tmp1, tmp2;
1440 tmp1 = MULT16_32_Q15(st->mode->window[i ], e[i ]) -
1441 MULT16_32_Q15(st->mode->window[overlap-i-1], e[overlap-i-1]);
1442 tmp2 = MULT16_32_Q15(st->mode->window[i], e[N+overlap-1-i]) +
1443 MULT16_32_Q15(st->mode->window[overlap-i-1], e[N+i ]);
1444 tmp1 = MULT16_32_Q15(fade, tmp1);
1445 tmp2 = MULT16_32_Q15(fade, tmp2);
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001446 out_mem[c][MAX_PERIOD+i] = MULT16_32_Q15(st->mode->window[overlap-i-1], tmp2);
1447 out_mem[c][MAX_PERIOD+overlap-i-1] = MULT16_32_Q15(st->mode->window[i], tmp2);
1448 out_mem[c][MAX_PERIOD-N+i] += MULT16_32_Q15(st->mode->window[i], tmp1);
1449 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 -05001450 }
1451 for (i=0;i<N-overlap;i++)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001452 out_mem[c][MAX_PERIOD-N+overlap+i] = MULT16_32_Q15(fade, e[overlap+i]);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001453 }
Jean-Marc Valin1677aa92007-12-08 01:13:34 +11001454
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001455 deemphasis(out_mem, pcm, N, C, st->mode->preemph, st->preemph_memD);
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001456
1457 st->loss_count++;
1458
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001459 RESTORE_STACK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001460}
1461
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001462#ifdef FIXED_POINT
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001463int 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 +11001464{
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001465#else
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001466int 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 -04001467{
1468#endif
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -04001469 int c, i, N;
Jean-Marc Valin8cbea172010-08-05 15:22:57 -04001470 int has_fold;
Jean-Marc Valinc890b582008-08-01 22:26:49 -04001471 int bits;
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001472 ec_dec _dec;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11001473 ec_byte_buffer buf;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001474 VARDECL(celt_sig, freq);
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001475 VARDECL(celt_norm, X);
1476 VARDECL(celt_ener, bandE);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001477 VARDECL(int, fine_quant);
1478 VARDECL(int, pulses);
1479 VARDECL(int, offsets);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04001480 VARDECL(int, fine_priority);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -04001481 VARDECL(int, tf_res);
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001482 celt_sig *out_mem[2];
1483 celt_sig *decode_mem[2];
1484 celt_sig *overlap_mem[2];
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04001485 celt_sig *out_syn[2];
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001486 celt_word16 *lpc;
1487 celt_word16 *oldBandE;
Jean-Marc Valinc890b582008-08-01 22:26:49 -04001488
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +10001489 int shortBlocks;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001490 int isTransient;
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -04001491 int intra_ener;
Jean-Marc Valin12b22482008-06-16 14:13:05 +10001492 int transient_time;
Jean-Marc Valin528f4b82008-06-29 03:46:39 +10001493 int transient_shift;
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001494 int mdct_weight_shift=0;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001495 const int C = CHANNELS(st->channels);
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001496 int mdct_weight_pos=0;
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001497 int LM, M;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04001498 int nbFilledBytes, nbAvailableBytes;
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001499 int effEnd;
Jean-Marc Valinb801da52010-09-28 14:56:20 -04001500 int codedBands;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001501 int alloc_trim;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001502 SAVE_STACK;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001503
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001504 if (pcm==NULL)
1505 return CELT_BAD_ARG;
1506
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001507 for (LM=0;LM<4;LM++)
1508 if (st->mode->shortMdctSize<<LM==frame_size)
1509 break;
1510 if (LM>=MAX_CONFIG_SIZES)
1511 return CELT_BAD_ARG;
1512 M=1<<LM;
1513
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001514 for (c=0;c<C;c++)
1515 {
1516 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
1517 out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
1518 overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
1519 }
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001520 lpc = (celt_word16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C);
1521 oldBandE = lpc+C*LPC_ORDER;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001522
Jean-Marc Valin04752672010-05-05 07:21:21 -04001523 N = M*st->mode->shortMdctSize;
Jean-Marc Valin01417232008-03-03 13:59:55 +11001524
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001525 effEnd = st->end;
1526 if (effEnd > st->mode->effEBands)
1527 effEnd = st->mode->effEBands;
1528
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001529 ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
1530 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
1531 ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001532 for (c=0;c<C;c++)
1533 for (i=0;i<M*st->mode->eBands[st->start];i++)
1534 X[c*N+i] = 0;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001535 for (c=0;c<C;c++)
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001536 for (i=M*st->mode->eBands[effEnd];i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001537 X[c*N+i] = 0;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001538
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001539 if (data == NULL)
1540 {
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001541 celt_decode_lost(st, pcm, N, LM);
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001542 RESTORE_STACK;
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001543 return CELT_OK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001544 }
Gregory Maxwell520eeae2009-02-09 01:33:21 -05001545 if (len<0) {
1546 RESTORE_STACK;
1547 return CELT_BAD_ARG;
1548 }
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001549
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001550 if (dec == NULL)
1551 {
1552 ec_byte_readinit(&buf,(unsigned char*)data,len);
1553 ec_dec_init(&_dec,&buf);
1554 dec = &_dec;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04001555 nbFilledBytes = 0;
1556 } else {
Jean-Marc Valinbdcaaf72010-07-05 13:52:41 -04001557 nbFilledBytes = (ec_dec_tell(dec, 0)+4)>>3;
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001558 }
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04001559 nbAvailableBytes = len-nbFilledBytes;
1560
Jean-Marc Valin017001a2010-08-05 15:42:50 -04001561 /* Decode the global flags (first symbols in the stream) */
1562 intra_ener = ec_dec_bit_prob(dec, 8192);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001563 /* Get band energies */
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001564 unquant_coarse_energy(st->mode, st->start, st->end, bandE, oldBandE,
1565 intra_ener, st->mode->prob, dec, C, LM);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001566
Jean-Marc Valinf9fdbff2010-09-05 21:02:38 -04001567 if (LM > 0)
1568 isTransient = ec_dec_bit_prob(dec, 8192);
1569 else
1570 isTransient = 0;
Jean-Marc Valin017001a2010-08-05 15:42:50 -04001571
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001572 if (isTransient)
1573 shortBlocks = M;
1574 else
1575 shortBlocks = 0;
1576
1577 if (isTransient)
Gregory Maxwell0527f372008-09-23 19:28:35 -04001578 {
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001579 transient_shift = ec_dec_uint(dec, 4);
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001580 if (transient_shift == 3)
1581 {
Jean-Marc Valin0be05b02010-07-16 14:23:03 -04001582 int transient_time_quant;
1583 int max_time = (N+st->mode->overlap)*(celt_int32)8000/st->mode->Fs;
1584 transient_time_quant = ec_dec_uint(dec, max_time);
1585 transient_time = transient_time_quant*(celt_int32)st->mode->Fs/8000;
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001586 } else {
1587 mdct_weight_shift = transient_shift;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001588 if (mdct_weight_shift && M>2)
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001589 mdct_weight_pos = ec_dec_uint(dec, M-1);
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001590 transient_shift = 0;
Gregory Maxwell0527f372008-09-23 19:28:35 -04001591 transient_time = 0;
Jean-Marc Valinaa936252009-05-29 22:14:20 -04001592 }
Gregory Maxwell0527f372008-09-23 19:28:35 -04001593 } else {
Jean-Marc Valin12b22482008-06-16 14:13:05 +10001594 transient_time = -1;
Jean-Marc Valin528f4b82008-06-29 03:46:39 +10001595 transient_shift = 0;
Jean-Marc Valin12b22482008-06-16 14:13:05 +10001596 }
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04001597
1598 ALLOC(tf_res, st->mode->nbEBands, int);
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -04001599 tf_decode(st->start, st->end, C, isTransient, tf_res, nbAvailableBytes, LM, dec);
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04001600
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001601 has_fold = ec_dec_bit_prob(dec, 8192)<<1;
1602 has_fold |= ec_dec_bit_prob(dec, (has_fold>>1) ? 32768 : 49152);
1603
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001604 ALLOC(pulses, st->mode->nbEBands, int);
1605 ALLOC(offsets, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04001606 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001607
1608 for (i=0;i<st->mode->nbEBands;i++)
1609 offsets[i] = 0;
Jean-Marc Valind74c8512010-09-29 17:39:54 -04001610 for (i=0;i<st->mode->nbEBands;i++)
1611 {
1612 if (ec_dec_bit_prob(dec, 1024))
1613 {
1614 while (ec_dec_bit_prob(dec, 32768))
1615 offsets[i]++;
1616 offsets[i]++;
1617 offsets[i] *= (6<<BITRES);
1618 }
1619 }
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001620
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001621 ALLOC(fine_quant, st->mode->nbEBands, int);
Jean-Marc Valin6bf04622010-09-30 10:16:22 -04001622 {
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001623 int fl;
Jean-Marc Valin6bf04622010-09-30 10:16:22 -04001624 int trim_index=0;
1625 fl = ec_decode_bin(dec, 7);
1626 while (trim_cdf[trim_index+1] <= fl)
1627 trim_index++;
1628 ec_dec_update(dec, trim_cdf[trim_index], trim_cdf[trim_index+1], 128);
1629 alloc_trim = trim_coef[trim_index];
Jean-Marc Valin6bf04622010-09-30 10:16:22 -04001630 }
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001631
1632 bits = len*8 - ec_dec_tell(dec, 0) - 1;
1633 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 -04001634
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001635 unquant_fine_energy(st->mode, st->start, st->end, bandE, oldBandE, fine_quant, dec, C);
Jean-Marc Valin827f9312008-05-06 23:21:55 +10001636
Jean-Marc Valin8cbea172010-08-05 15:22:57 -04001637 /* Decode fixed codebook */
Jean-Marc Valinb801da52010-09-28 14:56:20 -04001638 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 -04001639
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001640 unquant_energy_finalise(st->mode, st->start, st->end, bandE, oldBandE,
1641 fine_quant, fine_priority, len*8-ec_dec_tell(dec, 0), dec, C);
Jean-Marc Valin30d51252010-06-21 17:55:28 -04001642
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001643 log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04001644
Jean-Marc Valin88619552009-10-04 21:35:36 -04001645 if (mdct_weight_shift)
1646 {
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001647 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 -04001648 }
1649
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11001650 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001651 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11001652
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001653 CELT_MOVE(decode_mem[0], decode_mem[0]+N, DECODE_BUFFER_SIZE-N);
Jean-Marc Valin903dbf72010-08-26 20:06:49 -04001654 if (C==2)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001655 CELT_MOVE(decode_mem[1], decode_mem[1]+N, DECODE_BUFFER_SIZE-N);
Jean-Marc Valin88619552009-10-04 21:35:36 -04001656
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001657 for (c=0;c<C;c++)
1658 for (i=0;i<M*st->mode->eBands[st->start];i++)
1659 freq[c*N+i] = 0;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001660 for (c=0;c<C;c++)
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001661 for (i=M*st->mode->eBands[effEnd];i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001662 freq[c*N+i] = 0;
Jean-Marc Valin3a0bc3d2010-02-21 15:10:22 -05001663
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001664 out_syn[0] = out_mem[0]+MAX_PERIOD-N;
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04001665 if (C==2)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001666 out_syn[1] = out_mem[1]+MAX_PERIOD-N;
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04001667
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001668 /* Compute inverse MDCTs */
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001669 compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time,
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001670 transient_shift, out_syn, overlap_mem, C, LM);
Jean-Marc Valinffa13472007-12-10 16:54:17 +11001671
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04001672 deemphasis(out_syn, pcm, N, C, st->mode->preemph, st->preemph_memD);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001673 st->loss_count = 0;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001674 RESTORE_STACK;
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001675 if (ec_dec_get_error(dec))
1676 return CELT_CORRUPTED_DATA;
1677 else
1678 return CELT_OK;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001679}
1680
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001681#ifdef FIXED_POINT
1682#ifndef DISABLE_FLOAT_API
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001683int 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 -04001684{
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001685 int j, ret, C, N, LM, M;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001686 VARDECL(celt_int16, out);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -04001687 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001688
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001689 if (pcm==NULL)
1690 return CELT_BAD_ARG;
1691
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001692 for (LM=0;LM<4;LM++)
1693 if (st->mode->shortMdctSize<<LM==frame_size)
1694 break;
1695 if (LM>=MAX_CONFIG_SIZES)
1696 return CELT_BAD_ARG;
1697 M=1<<LM;
1698
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001699 C = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001700 N = M*st->mode->shortMdctSize;
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001701
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001702 ALLOC(out, C*N, celt_int16);
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001703 ret=celt_decode_with_ec(st, data, len, out, frame_size, dec);
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001704 if (ret==0)
1705 for (j=0;j<C*N;j++)
Jean-Marc Valinae01e112010-08-03 21:43:41 -04001706 pcm[j]=out[j]*(1.f/32768.f);
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001707
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001708 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001709 return ret;
1710}
1711#endif /*DISABLE_FLOAT_API*/
1712#else
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001713int 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 -04001714{
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001715 int j, ret, C, N, LM, M;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001716 VARDECL(celt_sig, out);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -04001717 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001718
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001719 if (pcm==NULL)
1720 return CELT_BAD_ARG;
1721
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001722 for (LM=0;LM<4;LM++)
1723 if (st->mode->shortMdctSize<<LM==frame_size)
1724 break;
1725 if (LM>=MAX_CONFIG_SIZES)
1726 return CELT_BAD_ARG;
1727 M=1<<LM;
1728
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001729 C = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001730 N = M*st->mode->shortMdctSize;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001731 ALLOC(out, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001732
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001733 ret=celt_decode_with_ec_float(st, data, len, out, frame_size, dec);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001734
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001735 if (ret==0)
1736 for (j=0;j<C*N;j++)
1737 pcm[j] = FLOAT2INT16 (out[j]);
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001738
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001739 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001740 return ret;
1741}
1742#endif
John Ridges454d1d02009-05-21 22:38:39 -04001743
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001744int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, celt_int16 * restrict pcm, int frame_size)
1745{
1746 return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL);
1747}
1748
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001749#ifndef DISABLE_FLOAT_API
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001750int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size)
1751{
1752 return celt_decode_with_ec_float(st, data, len, pcm, frame_size, NULL);
1753}
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001754#endif /* DISABLE_FLOAT_API */
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001755
John Ridges454d1d02009-05-21 22:38:39 -04001756int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
1757{
1758 va_list ap;
Gregory Maxwell17169992009-06-04 15:15:34 -04001759
John Ridges454d1d02009-05-21 22:38:39 -04001760 va_start(ap, request);
1761 switch (request)
1762 {
Gregory Maxwellf3b44ef2009-06-03 13:37:45 -04001763 case CELT_GET_MODE_REQUEST:
1764 {
1765 const CELTMode ** value = va_arg(ap, const CELTMode**);
1766 if (value==0)
1767 goto bad_arg;
1768 *value=st->mode;
1769 }
1770 break;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001771 case CELT_SET_START_BAND_REQUEST:
1772 {
1773 celt_int32 value = va_arg(ap, celt_int32);
1774 if (value<0 || value>=st->mode->nbEBands)
1775 goto bad_arg;
1776 st->start = value;
1777 }
1778 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001779 case CELT_SET_END_BAND_REQUEST:
1780 {
1781 celt_int32 value = va_arg(ap, celt_int32);
1782 if (value<0 || value>=st->mode->nbEBands)
1783 goto bad_arg;
1784 st->end = value;
1785 }
1786 break;
John Ridges454d1d02009-05-21 22:38:39 -04001787 case CELT_RESET_STATE:
1788 {
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001789 CELT_MEMSET((char*)&st->DECODER_RESET_START, 0,
1790 celt_decoder_get_size(st->mode, st->channels)-
1791 ((char*)&st->DECODER_RESET_START - (char*)st));
John Ridges454d1d02009-05-21 22:38:39 -04001792 }
1793 break;
1794 default:
1795 goto bad_request;
1796 }
1797 va_end(ap);
1798 return CELT_OK;
John Ridges454d1d02009-05-21 22:38:39 -04001799bad_arg:
1800 va_end(ap);
1801 return CELT_BAD_ARG;
John Ridges454d1d02009-05-21 22:38:39 -04001802bad_request:
1803 va_end(ap);
1804 return CELT_UNIMPLEMENTED;
1805}
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001806
1807const char *celt_strerror(int error)
1808{
1809 static const char *error_strings[8] = {
1810 "success",
1811 "invalid argument",
1812 "invalid mode",
1813 "internal error",
1814 "corrupted stream",
1815 "request not implemented",
1816 "invalid state",
1817 "memory allocation failed"
1818 };
1819 if (error > 0 || error < -7)
1820 return "unknown error";
1821 else
1822 return error_strings[-error];
1823}
1824