blob: 582d306f01639afabf9e9a63270d6ec48cd96df6 [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 Valin4b087df2010-11-30 21:08:31 -050056static const int trim_cdf[12] = {0, 2, 4, 9, 19, 41, 87, 109, 119, 124, 126, 128};
57
Jean-Marc Valin35095c62010-11-04 13:24:44 -040058#define COMBFILTER_MAXPERIOD 1024
59#define COMBFILTER_MINPERIOD 16
Jean-Marc Valin6bf04622010-09-30 10:16:22 -040060
Jean-Marc Valin276de722008-02-20 17:45:51 +110061/** Encoder state
62 @brief Encoder state
63 */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +110064struct CELTEncoder {
Jean-Marc Valin276de722008-02-20 17:45:51 +110065 const CELTMode *mode; /**< Mode used by the encoder */
Jean-Marc Valina5431bf2008-01-03 20:53:01 +110066 int overlap;
Jean-Marc Valinffa13472007-12-10 16:54:17 +110067 int channels;
68
Gregory Maxwell2dd3d322009-06-05 14:05:51 -040069 int force_intra;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -040070 int complexity;
Jean-Marc Valinc09807d2010-08-27 17:17:50 -040071 int start, end;
72
Gregory Maxwella9411472010-10-28 03:52:21 -040073 celt_int32 vbr_rate_norm; /* Target number of 8th bits per frame */
Jean-Marc Valin9faf7402010-12-04 10:27:22 -050074 int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */
Jean-Marc Valinc09807d2010-08-27 17:17:50 -040075
76 /* Everything beyond this point gets cleared on a reset */
77#define ENCODER_RESET_START frame_max
78
79 celt_word32 frame_max;
80 int fold_decision;
Jean-Marc Valin74f4e9f2009-05-02 09:57:50 -040081 int delayedIntra;
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -040082 int tonal_average;
Jean-Marc Valindfd6e712010-12-09 23:23:34 -050083 int lastCodedBands;
Jean-Marc Valin527db5c2009-06-02 07:56:19 -040084
Jean-Marc Valin35095c62010-11-04 13:24:44 -040085 int prefilter_period;
86 celt_word16 prefilter_gain;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -050087#ifdef RESYNTH
88 int prefilter_period_old;
89 celt_word16 prefilter_gain_old;
90#endif
Jean-Marc Valin35095c62010-11-04 13:24:44 -040091
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -040092 /* VBR-related parameters */
93 celt_int32 vbr_reservoir;
94 celt_int32 vbr_drift;
95 celt_int32 vbr_offset;
96 celt_int32 vbr_count;
97
Jean-Marc Valinac1da4f2010-07-24 11:48:10 -040098 celt_word32 preemph_memE[2];
99 celt_word32 preemph_memD[2];
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100100
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400101#ifdef RESYNTH
102 celt_sig syn_mem[2][2*MAX_PERIOD];
103#endif
104
Jean-Marc Valinca8b9922010-08-27 16:23:03 -0400105 celt_sig in_mem[1]; /* Size = channels*mode->overlap */
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400106 /* celt_sig prefilter_mem[], Size = channels*COMBFILTER_PERIOD */
Jean-Marc Valinca8b9922010-08-27 16:23:03 -0400107 /* celt_sig overlap_mem[], Size = channels*mode->overlap */
108 /* celt_word16 oldEBands[], Size = channels*mode->nbEBands */
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100109};
110
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400111int celt_encoder_get_size(const CELTMode *mode, int channels)
112{
113 int size = sizeof(struct CELTEncoder)
114 + (2*channels*mode->overlap-1)*sizeof(celt_sig)
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400115 + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig)
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400116 + channels*mode->nbEBands*sizeof(celt_word16);
117 return size;
118}
119
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400120CELTEncoder *celt_encoder_create(const CELTMode *mode, int channels, int *error)
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100121{
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -0400122 return celt_encoder_init(
123 (CELTEncoder *)celt_alloc(celt_encoder_get_size(mode, channels)),
124 mode, channels, error);
125}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100126
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -0400127CELTEncoder *celt_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels, int *error)
128{
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400129 if (channels < 0 || channels > 2)
130 {
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400131 if (error)
132 *error = CELT_BAD_ARG;
133 return NULL;
134 }
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100135
Jean-Marc Valinece94a02009-10-16 07:30:14 -0400136 if (st==NULL)
137 {
138 if (error)
139 *error = CELT_ALLOC_FAIL;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400140 return NULL;
Jean-Marc Valinece94a02009-10-16 07:30:14 -0400141 }
Jean-Marc Valin6d3829f2010-08-27 17:52:38 -0400142
143 CELT_MEMSET((char*)st, 0, celt_encoder_get_size(mode, channels));
144
Jean-Marc Valin73e51b32007-12-05 17:48:24 +1100145 st->mode = mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100146 st->overlap = mode->overlap;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400147 st->channels = channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100148
Jean-Marc Valin5f961462010-05-19 13:38:10 -0400149 st->start = 0;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400150 st->end = st->mode->effEBands;
Jean-Marc Valin9faf7402010-12-04 10:27:22 -0500151 st->constrained_vbr = 1;
Jean-Marc Valin5f961462010-05-19 13:38:10 -0400152
Jean-Marc Valin8cc945c2010-05-29 08:07:18 -0400153 st->vbr_rate_norm = 0;
Jean-Marc Valin30165bb2010-12-03 14:35:59 -0500154 st->vbr_offset = 0;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -0400155 st->force_intra = 0;
Gregory Maxwell8842fde2009-05-04 15:58:40 -0400156 st->delayedIntra = 1;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400157 st->tonal_average = 256;
Jean-Marc Valin527db5c2009-06-02 07:56:19 -0400158 st->fold_decision = 1;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400159 st->complexity = 5;
Jean-Marc Valina76a0b22008-01-17 22:43:05 +1100160
Jean-Marc Valinece94a02009-10-16 07:30:14 -0400161 if (error)
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400162 *error = CELT_OK;
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400163 return st;
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100164}
165
Peter Kirk19f9dc92008-06-06 14:38:38 +0200166void celt_encoder_destroy(CELTEncoder *st)
Jean-Marc Valin14191b32007-11-30 12:15:49 +1100167{
Jean-Marc Valin14191b32007-11-30 12:15:49 +1100168 celt_free(st);
169}
170
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400171static inline celt_int16 FLOAT2INT16(float x)
Jean-Marc Valin42074382008-02-27 11:08:53 +1100172{
Gregory Maxwell0ac2b2f2009-05-21 23:08:46 -0400173 x = x*CELT_SIG_SCALE;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400174 x = MAX32(x, -32768);
175 x = MIN32(x, 32767);
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400176 return (celt_int16)float2int(x);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400177}
178
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400179static inline celt_word16 SIG2WORD16(celt_sig x)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400180{
181#ifdef FIXED_POINT
Jean-Marc Valin42074382008-02-27 11:08:53 +1100182 x = PSHR32(x, SIG_SHIFT);
Jean-Marc Valinabdfc382008-04-18 15:57:18 +1000183 x = MAX32(x, -32768);
184 x = MIN32(x, 32767);
Jean-Marc Valin42074382008-02-27 11:08:53 +1100185 return EXTRACT16(x);
186#else
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400187 return (celt_word16)x;
Jean-Marc Valin42074382008-02-27 11:08:53 +1100188#endif
189}
190
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400191static int transient_analysis(const celt_word32 * restrict in, int len, int C,
Jean-Marc Valinbdb58712010-05-28 18:58:42 -0400192 celt_word32 *frame_max, int overlap)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000193{
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500194 int i;
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400195 VARDECL(celt_word16, tmp);
196 celt_word32 mem0=0,mem1=0;
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500197 int is_transient = 0;
198 int block;
199 int N;
200 /* FIXME: Make that smaller */
201 celt_word16 bins[50];
Jean-Marc Valin0ceccb22008-07-03 20:41:06 -0400202 SAVE_STACK;
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400203 ALLOC(tmp, len, celt_word16);
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400204
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500205 block = overlap/2;
206 N=len/block;
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400207 if (C==1)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000208 {
209 for (i=0;i<len;i++)
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400210 tmp[i] = SHR32(in[i],SIG_SHIFT);
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400211 } else {
212 for (i=0;i<len;i++)
Jean-Marc Valin933dd832010-10-24 00:08:16 -0400213 tmp[i] = SHR32(ADD32(in[i],in[i+len]), SIG_SHIFT+1);
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000214 }
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400215
216 /* High-pass filter: (1 - 2*z^-1 + z^-2) / (1 - z^-1 + .5*z^-2) */
217 for (i=0;i<len;i++)
218 {
219 celt_word32 x,y;
220 x = tmp[i];
221 y = ADD32(mem0, x);
222#ifdef FIXED_POINT
223 mem0 = mem1 + y - SHL32(x,1);
224 mem1 = x - SHR32(y,1);
225#else
226 mem0 = mem1 + y - 2*x;
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400227 mem1 = x - .5f*y;
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400228#endif
229 tmp[i] = EXTRACT16(SHR(y,2));
230 }
231 /* First few samples are bad because we don't propagate the memory */
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500232 for (i=0;i<12;i++)
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400233 tmp[i] = 0;
234
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500235 for (i=0;i<N;i++)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000236 {
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500237 int j;
238 float max_abs=0;
239 for (j=0;j<block;j++)
240 max_abs = MAX32(max_abs, tmp[i*block+j]);
241 bins[i] = max_abs;
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000242 }
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500243 for (i=0;i<N;i++)
Jean-Marc Valin4a8c1f12010-10-13 18:03:50 -0400244 {
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500245 int j;
246 int conseq=0;
247 celt_word16 t1, t2, t3;
248
249 t1 = MULT16_16_Q15(QCONST16(.15f, 15), bins[i]);
250 t2 = MULT16_16_Q15(QCONST16(.4f, 15), bins[i]);
251 t3 = MULT16_16_Q15(QCONST16(.15f, 15), bins[i]);
252 for (j=0;j<i;j++)
253 {
254 if (bins[j] < t1)
255 conseq++;
256 if (bins[j] < t2)
257 conseq++;
258 else
259 conseq = 0;
260 }
261 if (conseq>=3)
262 is_transient=1;
263 conseq = 0;
264 for (j=i+1;j<N;j++)
265 {
266 if (bins[j] < t3)
267 conseq++;
268 else
269 conseq = 0;
270 }
271 if (conseq>=7)
272 is_transient=1;
Jean-Marc Valin4a8c1f12010-10-13 18:03:50 -0400273 }
Jean-Marc Valin0ceccb22008-07-03 20:41:06 -0400274 RESTORE_STACK;
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500275 return is_transient;
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000276}
277
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400278/** Apply window and compute the MDCT for all sub-frames and
279 all channels in a frame */
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400280static 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 +1100281{
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400282 const int C = CHANNELS(_C);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000283 if (C==1 && !shortBlocks)
Jean-Marc Valinda721882007-11-30 15:17:42 +1100284 {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000285 const int overlap = OVERLAP(mode);
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400286 clt_mdct_forward(&mode->mdct, in, out, mode->window, overlap, mode->maxLM-LM);
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400287 } else {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000288 const int overlap = OVERLAP(mode);
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400289 int N = mode->shortMdctSize<<LM;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400290 int B = 1;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000291 int b, c;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400292 VARDECL(celt_word32, tmp);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000293 SAVE_STACK;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400294 if (shortBlocks)
295 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400296 /*lookup = &mode->mdct[0];*/
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400297 N = mode->shortMdctSize;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400298 B = shortBlocks;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400299 }
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400300 ALLOC(tmp, N, celt_word32);
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400301 c=0; do {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000302 for (b=0;b<B;b++)
303 {
304 int j;
Jean-Marc Valineedb4222010-10-24 00:22:45 -0400305 clt_mdct_forward(&mode->mdct, in+c*(B*N+overlap)+b*N, tmp, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000306 /* Interleaving the sub-frames */
307 for (j=0;j<N;j++)
Jean-Marc Valin08a82ff2009-06-14 14:05:19 -0400308 out[(j*B+b)+c*N*B] = tmp[j];
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000309 }
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400310 } while (++c<C);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000311 RESTORE_STACK;
Jean-Marc Valinda721882007-11-30 15:17:42 +1100312 }
Jean-Marc Valinda721882007-11-30 15:17:42 +1100313}
314
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400315/** Compute the IMDCT and apply window for all sub-frames and
316 all channels in a frame */
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400317static void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig *X,
Jean-Marc Valin7a08ddd2010-10-18 14:55:42 -0400318 celt_sig * restrict out_mem[],
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400319 celt_sig * restrict overlap_mem[], int _C, int LM)
Jean-Marc Valin1677aa92007-12-08 01:13:34 +1100320{
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -0400321 int c;
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400322 const int C = CHANNELS(_C);
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400323 const int N = mode->shortMdctSize<<LM;
Jean-Marc Valinb18ec0b2008-04-11 04:07:52 +1000324 const int overlap = OVERLAP(mode);
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400325 c=0; do {
Jean-Marc Valinb886ddc2008-03-25 14:38:55 +1100326 int j;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400327 VARDECL(celt_word32, x);
328 VARDECL(celt_word32, tmp);
Jean-Marc Valinde678582009-10-03 10:36:27 -0400329 int b;
330 int N2 = N;
331 int B = 1;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000332 SAVE_STACK;
Jean-Marc Valinde678582009-10-03 10:36:27 -0400333
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400334 ALLOC(x, N+overlap, celt_word32);
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400335 ALLOC(tmp, N, celt_word32);
Jean-Marc Valinde678582009-10-03 10:36:27 -0400336
337 if (shortBlocks)
338 {
Jean-Marc Valinde678582009-10-03 10:36:27 -0400339 N2 = mode->shortMdctSize;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400340 B = shortBlocks;
Jean-Marc Valinde678582009-10-03 10:36:27 -0400341 }
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000342 /* Prevents problems from the imdct doing the overlap-add */
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400343 CELT_MEMSET(x, 0, overlap);
Jean-Marc Valinde678582009-10-03 10:36:27 -0400344
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000345 for (b=0;b<B;b++)
346 {
347 /* De-interleaving the sub-frames */
348 for (j=0;j<N2;j++)
Jean-Marc Valin08a82ff2009-06-14 14:05:19 -0400349 tmp[j] = X[(j*B+b)+c*N2*B];
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400350 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 +1000351 }
Jean-Marc Valinde678582009-10-03 10:36:27 -0400352
Jean-Marc Valin8ddd7f42008-04-22 13:37:16 +1000353 for (j=0;j<overlap;j++)
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400354 out_mem[c][j] = x[j] + overlap_mem[c][j];
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400355 for (;j<N;j++)
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400356 out_mem[c][j] = x[j];
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400357 for (j=0;j<overlap;j++)
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400358 overlap_mem[c][j] = x[N+j];
Jean-Marc Valin8ddd7f42008-04-22 13:37:16 +1000359 RESTORE_STACK;
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400360 } while (++c<C);
Jean-Marc Valin1677aa92007-12-08 01:13:34 +1100361}
362
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400363static 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 -0400364{
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400365 const int C = CHANNELS(_C);
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400366 int c;
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400367 c=0; do {
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400368 int j;
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400369 celt_sig * restrict x;
370 celt_word16 * restrict y;
371 celt_sig m = mem[c];
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400372 x =in[c];
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400373 y = pcm+c;
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400374 for (j=0;j<N;j++)
375 {
Jean-Marc Valinaf1fce92010-07-16 11:05:06 -0400376 celt_sig tmp = *x + m;
377 m = MULT16_32_Q15(coef[0], tmp)
378 - MULT16_32_Q15(coef[1], *x);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400379 tmp = SHL32(MULT16_32_Q15(coef[3], tmp), 2);
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400380 *y = SCALEOUT(SIG2WORD16(tmp));
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400381 x++;
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400382 y+=C;
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400383 }
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400384 mem[c] = m;
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400385 } while (++c<C);
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400386}
387
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400388#ifdef ENABLE_POSTFILTER
389/* FIXME: Handle the case where T = maxperiod */
390static void comb_filter(celt_word32 *y, celt_word32 *x, int T0, int T1, int N,
391 int C, celt_word16 g0, celt_word16 g1, const celt_word16 *window, int overlap)
392{
393 int i;
394 /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
395 celt_word16 g00, g01, g02, g10, g11, g12;
396 celt_word16 t0, t1, t2;
397 /* zeros at theta = +/- 5*pi/6 */
398 t0 = QCONST16(.26795f, 15);
399 t1 = QCONST16(.46410f, 15);
400 t2 = QCONST16(.26795f, 15);
401 g00 = MULT16_16_Q15(g0, t0);
402 g01 = MULT16_16_Q15(g0, t1);
403 g02 = MULT16_16_Q15(g0, t2);
404 g10 = MULT16_16_Q15(g1, t0);
405 g11 = MULT16_16_Q15(g1, t1);
406 g12 = MULT16_16_Q15(g1, t2);
407 for (i=0;i<overlap;i++)
408 {
409 celt_word16 f;
410 f = MULT16_16_Q15(window[i],window[i]);
411 y[i] = x[i]
412 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),x[i-T0])
413 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g00),x[i-T0-1])
414 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),x[i-T0+1])
415 + MULT16_32_Q15(MULT16_16_Q15(f,g11),x[i-T1])
416 + MULT16_32_Q15(MULT16_16_Q15(f,g10),x[i-T1-1])
417 + MULT16_32_Q15(MULT16_16_Q15(f,g12),x[i-T1+1]);
418
419 }
420 for (i=overlap;i<N;i++)
421 y[i] = x[i]
422 + MULT16_32_Q15(g11,x[i-T1])
423 + MULT16_32_Q15(g10,x[i-T1-1])
424 + MULT16_32_Q15(g12,x[i-T1+1]);
425}
426#endif /* ENABLE_POSTFILTER */
427
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400428static const signed char tf_select_table[4][8] = {
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400429 {0, -1, 0, -1, 0,-1, 0,-1},
430 {0, -1, 0, -2, 1, 0, 1 -1},
431 {0, -2, 0, -3, 2, 0, 1 -1},
432 {0, -2, 0, -3, 2, 0, 1 -1},
433};
434
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400435static celt_word32 l1_metric(const celt_norm *tmp, int N, int LM, int width)
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400436{
437 int i, j;
438 static const celt_word16 sqrtM_1[4] = {Q15ONE, QCONST16(0.70711f,15), QCONST16(0.5f,15), QCONST16(0.35355f,15)};
439 celt_word32 L1;
440 celt_word16 bias;
441 L1=0;
442 for (i=0;i<1<<LM;i++)
443 {
444 celt_word32 L2 = 0;
445 for (j=0;j<N>>LM;j++)
446 L2 = MAC16_16(L2, tmp[(j<<LM)+i], tmp[(j<<LM)+i]);
447 L1 += celt_sqrt(L2);
448 }
449 L1 = MULT16_32_Q15(sqrtM_1[LM], L1);
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400450 if (width==1)
451 bias = QCONST16(.12f,15)*LM;
452 else if (width==2)
453 bias = QCONST16(.05f,15)*LM;
454 else
455 bias = QCONST16(.02f,15)*LM;
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400456 L1 = MAC16_32_Q15(L1, bias, L1);
457 return L1;
458}
459
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400460static int tf_analysis(const CELTMode *m, celt_word16 *bandLogE, celt_word16 *oldBandE,
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400461 int len, int C, int isTransient, int *tf_res, int nbCompressedBytes, celt_norm *X,
462 int N0, int LM, int *tf_sum)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400463{
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400464 int i;
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400465 VARDECL(int, metric);
466 int cost0;
467 int cost1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400468 VARDECL(int, path0);
469 VARDECL(int, path1);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400470 VARDECL(celt_norm, tmp);
471 int lambda;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400472 int tf_select=0;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400473 SAVE_STACK;
474
Jean-Marc Valin6bf3b0a2010-07-19 14:32:40 -0400475 /* FIXME: Should check number of bytes *left* */
476 if (nbCompressedBytes<15*C)
477 {
Jean-Marc Valina3a066c2010-11-04 15:15:54 -0400478 *tf_sum = 0;
Jean-Marc Valin6bf3b0a2010-07-19 14:32:40 -0400479 for (i=0;i<len;i++)
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400480 tf_res[i] = isTransient;
Jean-Marc Valin6bf3b0a2010-07-19 14:32:40 -0400481 return 0;
482 }
Jean-Marc Valin73319772010-05-28 21:12:39 -0400483 if (nbCompressedBytes<40)
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400484 lambda = 12;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400485 else if (nbCompressedBytes<60)
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400486 lambda = 6;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400487 else if (nbCompressedBytes<100)
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400488 lambda = 4;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400489 else
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400490 lambda = 3;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400491
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400492 ALLOC(metric, len, int);
493 ALLOC(tmp, (m->eBands[len]-m->eBands[len-1])<<LM, celt_norm);
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400494 ALLOC(path0, len, int);
495 ALLOC(path1, len, int);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400496
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400497 *tf_sum = 0;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400498 for (i=0;i<len;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400499 {
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400500 int j, k, N;
501 celt_word32 L1, best_L1;
502 int best_level=0;
503 N = (m->eBands[i+1]-m->eBands[i])<<LM;
504 for (j=0;j<N;j++)
505 tmp[j] = X[j+(m->eBands[i]<<LM)];
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400506 /* FIXME: Do something with the right channel */
Jean-Marc Valina3a066c2010-11-04 15:15:54 -0400507 if (C==2)
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400508 for (j=0;j<N;j++)
Jean-Marc Valina3a066c2010-11-04 15:15:54 -0400509 tmp[j] = ADD16(tmp[j],X[N0+j+(m->eBands[i]<<LM)]);
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400510 L1 = l1_metric(tmp, N, isTransient ? LM : 0, N>>LM);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400511 best_L1 = L1;
512 /*printf ("%f ", L1);*/
513 for (k=0;k<LM;k++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400514 {
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400515 int B;
516
517 if (isTransient)
518 B = (LM-k-1);
519 else
520 B = k+1;
521
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400522 if (isTransient)
523 haar1(tmp, N>>(LM-k), 1<<(LM-k));
524 else
525 haar1(tmp, N>>k, 1<<k);
526
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400527 L1 = l1_metric(tmp, N, B, N>>LM);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400528
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400529 if (L1 < best_L1)
530 {
531 best_L1 = L1;
532 best_level = k+1;
533 }
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400534 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400535 /*printf ("%d ", isTransient ? LM-best_level : best_level);*/
536 if (isTransient)
537 metric[i] = best_level;
538 else
539 metric[i] = -best_level;
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400540 *tf_sum += metric[i];
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400541 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400542 /*printf("\n");*/
543 /* FIXME: Figure out how to set this */
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400544 tf_select = 0;
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400545
Jean-Marc Valin88232612010-05-28 18:01:02 -0400546 cost0 = 0;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400547 cost1 = isTransient ? 0 : lambda;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400548 /* Viterbi forward pass */
549 for (i=1;i<len;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400550 {
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400551 int curr0, curr1;
552 int from0, from1;
Jean-Marc Valin581fdba2010-05-28 06:56:23 -0400553
Jean-Marc Valin88232612010-05-28 18:01:02 -0400554 from0 = cost0;
555 from1 = cost1 + lambda;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400556 if (from0 < from1)
557 {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400558 curr0 = from0;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400559 path0[i]= 0;
560 } else {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400561 curr0 = from1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400562 path0[i]= 1;
563 }
564
Jean-Marc Valin88232612010-05-28 18:01:02 -0400565 from0 = cost0 + lambda;
566 from1 = cost1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400567 if (from0 < from1)
568 {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400569 curr1 = from0;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400570 path1[i]= 0;
571 } else {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400572 curr1 = from1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400573 path1[i]= 1;
574 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400575 cost0 = curr0 + abs(metric[i]-tf_select_table[LM][4*isTransient+2*tf_select+0]);
576 cost1 = curr1 + abs(metric[i]-tf_select_table[LM][4*isTransient+2*tf_select+1]);
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400577 }
Jean-Marc Valin88232612010-05-28 18:01:02 -0400578 tf_res[len-1] = cost0 < cost1 ? 0 : 1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400579 /* Viterbi backward pass to check the decisions */
580 for (i=len-2;i>=0;i--)
581 {
582 if (tf_res[i+1] == 1)
583 tf_res[i] = path1[i+1];
584 else
585 tf_res[i] = path0[i+1];
586 }
Jean-Marc Valin71ae6d42010-06-27 21:55:08 -0400587 RESTORE_STACK;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400588 return tf_select;
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400589}
590
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -0500591static void tf_encode(int start, int end, int isTransient, int *tf_res, int LM, int tf_select, ec_enc *enc)
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400592{
593 int curr, i;
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400594 ec_enc_bit_prob(enc, tf_res[start], isTransient ? 16384 : 4096);
595 curr = tf_res[start];
596 for (i=start+1;i<end;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400597 {
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400598 ec_enc_bit_prob(enc, tf_res[i] ^ curr, isTransient ? 4096 : 2048);
599 curr = tf_res[i];
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400600 }
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -0500601 if (LM!=0)
602 ec_enc_bits(enc, tf_select, 1);
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400603 for (i=start;i<end;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400604 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400605 /*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 -0400606}
607
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -0500608static void tf_decode(int start, int end, int C, int isTransient, int *tf_res, int LM, ec_dec *dec)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400609{
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400610 int i, curr, tf_select;
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400611 tf_res[start] = ec_dec_bit_prob(dec, isTransient ? 16384 : 4096);
612 curr = tf_res[start];
613 for (i=start+1;i<end;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400614 {
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400615 tf_res[i] = ec_dec_bit_prob(dec, isTransient ? 4096 : 2048) ^ curr;
616 curr = tf_res[i];
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400617 }
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -0500618 if (LM!=0)
619 tf_select = ec_dec_bits(dec, 1);
620 else
621 tf_select = 0;
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400622 for (i=start;i<end;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400623 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400624}
625
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400626static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X,
627 const celt_word16 *bandLogE, int nbEBands, int LM, int C, int N0)
628{
629 int i;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500630 celt_word32 diff=0;
631 int c;
Jean-Marc Valin4b087df2010-11-30 21:08:31 -0500632 int trim_index = 5;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400633 if (C==2)
634 {
635 celt_word16 sum = 0; /* Q10 */
636 /* Compute inter-channel correlation for low frequencies */
637 for (i=0;i<8;i++)
638 {
639 int j;
640 celt_word32 partial = 0;
641 for (j=m->eBands[i]<<LM;j<m->eBands[i+1]<<LM;j++)
642 partial = MAC16_16(partial, X[j], X[N0+j]);
643 sum = ADD16(sum, EXTRACT16(SHR32(partial, 18)));
644 }
645 sum = MULT16_16_Q15(QCONST16(1.f/8, 15), sum);
646 /*printf ("%f\n", sum);*/
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400647 if (sum > QCONST16(.995f,10))
Jean-Marc Valin4b087df2010-11-30 21:08:31 -0500648 trim_index-=4;
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400649 else if (sum > QCONST16(.92f,10))
Jean-Marc Valin4b087df2010-11-30 21:08:31 -0500650 trim_index-=3;
651 else if (sum > QCONST16(.85f,10))
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400652 trim_index-=2;
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400653 else if (sum > QCONST16(.8f,10))
Jean-Marc Valinc40addc2010-10-22 14:57:07 -0400654 trim_index-=1;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400655 }
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500656
657 /* Estimate spectral tilt */
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400658 c=0; do {
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400659 for (i=0;i<nbEBands-1;i++)
660 {
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500661 diff += bandLogE[i+c*nbEBands]*(celt_int32)(2+2*i-nbEBands);
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400662 }
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400663 } while (++c<0);
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400664 diff /= C*(nbEBands-1);
665 /*printf("%f\n", diff);*/
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500666 if (diff > QCONST16(2.f, DB_SHIFT))
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400667 trim_index--;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500668 if (diff > QCONST16(8.f, DB_SHIFT))
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400669 trim_index--;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500670 if (diff < -QCONST16(4.f, DB_SHIFT))
Jean-Marc Valin90377572010-10-22 15:12:01 -0400671 trim_index++;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500672 if (diff < -QCONST16(10.f, DB_SHIFT))
673 trim_index++;
674
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400675 if (trim_index<0)
676 trim_index = 0;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500677 if (trim_index>10)
678 trim_index = 10;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400679 return trim_index;
680}
681
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500682static int stereo_analysis(const CELTMode *m, const celt_norm *X,
683 int nbEBands, int LM, int C, int N0)
684{
685 int i;
686 int thetas;
687 celt_word32 sumLR = EPSILON, sumMS = EPSILON;
688
689 /* Use the L1 norm to model the entropy of the L/R signal vs the M/S signal */
690 for (i=0;i<13;i++)
691 {
692 int j;
693 for (j=m->eBands[i]<<LM;j<m->eBands[i+1]<<LM;j++)
694 {
695 celt_word16 L, R, M, S;
696 L = X[j];
697 R = X[N0+j];
698 M = L+R;
699 S = L-R;
700 sumLR += EXTEND32(ABS16(L)) + EXTEND32(ABS16(R));
701 sumMS += EXTEND32(ABS16(M)) + EXTEND32(ABS16(S));
702 }
703 }
704 sumMS = MULT16_32_Q15(QCONST16(0.707107f, 15), sumMS);
705 thetas = 13;
706 /* We don't need thetas for lower bands with LM<=1 */
707 if (LM<=1)
708 thetas -= 8;
709 return MULT16_32_Q15((m->eBands[13]<<(LM+1))+thetas, sumMS)
710 > MULT16_32_Q15(m->eBands[13]<<(LM+1), sumLR);
711}
712
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400713#ifdef FIXED_POINT
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400714int celt_encode_with_ec(CELTEncoder * restrict st, const celt_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100715{
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400716#else
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400717int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400718{
719#endif
Jean-Marc Valin7a08ddd2010-10-18 14:55:42 -0400720 int i, c, N;
Jean-Marc Valinc890b582008-08-01 22:26:49 -0400721 int bits;
Jean-Marc Valinbc799912008-11-07 22:53:13 -0500722 int has_fold=1;
Jean-Marc Valin8679a802008-10-18 07:44:35 -0400723 ec_byte_buffer buf;
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400724 ec_enc _enc;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400725 VARDECL(celt_sig, in);
726 VARDECL(celt_sig, freq);
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400727 VARDECL(celt_norm, X);
728 VARDECL(celt_ener, bandE);
729 VARDECL(celt_word16, bandLogE);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400730 VARDECL(int, fine_quant);
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400731 VARDECL(celt_word16, error);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400732 VARDECL(int, pulses);
733 VARDECL(int, offsets);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -0400734 VARDECL(int, fine_priority);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400735 VARDECL(int, tf_res);
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400736 celt_sig *_overlap_mem;
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400737 celt_sig *prefilter_mem;
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400738 celt_word16 *oldBandE;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000739 int shortBlocks=0;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400740 int isTransient=0;
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -0400741 int resynth;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400742 const int C = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400743 int LM, M;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400744 int tf_select;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400745 int nbFilledBytes, nbAvailableBytes;
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400746 int effEnd;
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400747 int codedBands;
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400748 int tf_sum;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -0400749 int alloc_trim;
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -0500750 int pitch_index=COMBFILTER_MINPERIOD;
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400751 celt_word16 gain1 = 0;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -0500752 int intensity=0;
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500753 int dual_stereo=0;
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -0500754 int effectiveBytes;
Jean-Marc Valin8600f692008-02-29 15:14:12 +1100755 SAVE_STACK;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100756
Gregory Maxwell0719f6f2009-07-09 17:07:24 -0400757 if (nbCompressedBytes<0 || pcm==NULL)
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400758 return CELT_BAD_ARG;
Gregory Maxwell520eeae2009-02-09 01:33:21 -0500759
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400760 for (LM=0;LM<4;LM++)
761 if (st->mode->shortMdctSize<<LM==frame_size)
762 break;
763 if (LM>=MAX_CONFIG_SIZES)
764 return CELT_BAD_ARG;
765 M=1<<LM;
Jean-Marc Valin8679a802008-10-18 07:44:35 -0400766
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400767 prefilter_mem = st->in_mem+C*(st->overlap);
768 _overlap_mem = prefilter_mem+C*COMBFILTER_MAXPERIOD;
769 /*_overlap_mem = st->in_mem+C*(st->overlap);*/
770 oldBandE = (celt_word16*)(st->in_mem+C*(2*st->overlap+COMBFILTER_MAXPERIOD));
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400771
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400772 if (enc==NULL)
773 {
774 ec_byte_writeinit_buffer(&buf, compressed, nbCompressedBytes);
775 ec_enc_init(&_enc,&buf);
776 enc = &_enc;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400777 nbFilledBytes=0;
778 } else {
Jean-Marc Valinbdcaaf72010-07-05 13:52:41 -0400779 nbFilledBytes=(ec_enc_tell(enc, 0)+4)>>3;
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400780 }
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400781 nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
782
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -0500783 if (st->vbr_rate_norm>0)
784 effectiveBytes = st->vbr_rate_norm>>BITRES<<LM>>3;
785 else
786 effectiveBytes = nbCompressedBytes;
787
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400788 effEnd = st->end;
789 if (effEnd > st->mode->effEBands)
790 effEnd = st->mode->effEBands;
791
Jean-Marc Valin04752672010-05-05 07:21:21 -0400792 N = M*st->mode->shortMdctSize;
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -0400793 ALLOC(in, C*(N+st->overlap), celt_sig);
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100794
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400795 /* Find pitch period and gain */
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +1100796 {
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400797 VARDECL(celt_sig, _pre);
798 celt_sig *pre[2];
799 SAVE_STACK;
800 c = 0;
801 ALLOC(_pre, C*(N+COMBFILTER_MAXPERIOD), celt_sig);
802
803 pre[0] = _pre;
804 pre[1] = _pre + (N+COMBFILTER_MAXPERIOD);
805
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400806 c=0; do {
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400807 const celt_word16 * restrict pcmp = pcm+c;
808 celt_sig * restrict inp = in+c*(N+st->overlap)+st->overlap;
809
810 for (i=0;i<N;i++)
811 {
812 /* Apply pre-emphasis */
813 celt_sig tmp = MULT16_16(st->mode->preemph[2], SCALEIN(*pcmp));
814 *inp = tmp + st->preemph_memE[c];
815 st->preemph_memE[c] = MULT16_32_Q15(st->mode->preemph[1], *inp)
816 - MULT16_32_Q15(st->mode->preemph[0], tmp);
817 inp++;
818 pcmp+=C;
819 }
820 CELT_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD);
821 CELT_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+st->overlap)+st->overlap, N);
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400822 } while (++c<C);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400823
824#ifdef ENABLE_POSTFILTER
Jean-Marc Valincd84e3d2010-12-16 22:29:35 -0500825 if (nbAvailableBytes>12*C)
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400826 {
827 VARDECL(celt_word16, pitch_buf);
828 ALLOC(pitch_buf, (COMBFILTER_MAXPERIOD+N)>>1, celt_word16);
829 celt_word32 tmp=0;
830 celt_word32 mem0[2]={0,0};
831 celt_word16 mem1[2]={0,0};
832
833 pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD+N,
834 C, mem0, mem1);
835 pitch_search(st->mode, pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N,
836 COMBFILTER_MAXPERIOD-COMBFILTER_MINPERIOD, &pitch_index, &tmp, 1<<LM);
837 pitch_index = COMBFILTER_MAXPERIOD-pitch_index;
838
839 gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD,
840 N, &pitch_index, st->prefilter_period, st->prefilter_gain);
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -0500841 if (pitch_index > COMBFILTER_MAXPERIOD)
842 pitch_index = COMBFILTER_MAXPERIOD;
843 gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1);
844 if (gain1 > QCONST16(.6f,15))
845 gain1 = QCONST16(.6f,15);
846 if (ABS16(gain1-st->prefilter_gain)<QCONST16(.1,15))
847 gain1=st->prefilter_gain;
848 } else {
849 gain1 = 0;
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400850 }
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -0500851 if (gain1<QCONST16(.2f,15) || (nbAvailableBytes<30 && gain1<QCONST16(.4f,15)))
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400852 {
853 ec_enc_bit_prob(enc, 0, 32768);
854 gain1 = 0;
855 } else {
856 int qg;
857 int octave;
858#ifdef FIXED_POINT
859 qg = ((gain1+2048)>>12)-2;
860#else
861 qg = floor(.5+gain1*8)-2;
862#endif
863 ec_enc_bit_prob(enc, 1, 32768);
864 octave = EC_ILOG(pitch_index)-5;
865 ec_enc_uint(enc, octave, 6);
866 ec_enc_bits(enc, pitch_index-(16<<octave), 4+octave);
867 ec_enc_bits(enc, qg, 2);
868 gain1 = QCONST16(.125f,15)*(qg+2);
869 }
870 /*printf("%d %f\n", pitch_index, gain1);*/
871#else /* ENABLE_POSTFILTER */
872 ec_enc_bit_prob(enc, 0, 32768);
873#endif /* ENABLE_POSTFILTER */
874
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400875 c=0; do {
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -0500876 st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400877 CELT_COPY(in+c*(N+st->overlap), st->in_mem+c*(st->overlap), st->overlap);
878#ifdef ENABLE_POSTFILTER
879 comb_filter(in+c*(N+st->overlap)+st->overlap, pre[c]+COMBFILTER_MAXPERIOD,
880 st->prefilter_period, pitch_index, N, C, -st->prefilter_gain, -gain1, st->mode->window, st->mode->overlap);
881#endif /* ENABLE_POSTFILTER */
882 CELT_COPY(st->in_mem+c*(st->overlap), in+c*(N+st->overlap)+N, st->overlap);
883
884#ifdef ENABLE_POSTFILTER
885 if (N>COMBFILTER_MAXPERIOD)
886 {
887 CELT_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD);
888 } else {
889 CELT_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, prefilter_mem+c*COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD-N);
890 CELT_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N);
891 }
892#endif /* ENABLE_POSTFILTER */
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400893 } while (++c<C);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400894
895 RESTORE_STACK;
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +1100896 }
Jean-Marc Valin2014ca32009-06-18 23:33:04 -0400897
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400898#ifdef RESYNTH
899 resynth = 1;
900#else
901 resynth = 0;
902#endif
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -0400903
Jean-Marc Valinf9fdbff2010-09-05 21:02:38 -0400904 if (st->complexity > 1 && LM>0)
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400905 {
906 isTransient = M > 1 &&
Jean-Marc Valin7a08ddd2010-10-18 14:55:42 -0400907 transient_analysis(in, N+st->overlap, C, &st->frame_max, st->overlap);
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400908 } else {
909 isTransient = 0;
910 }
Jean-Marc Valinc5f2a9d2008-10-26 22:00:26 -0400911
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400912 if (isTransient)
913 shortBlocks = M;
914 else
915 shortBlocks = 0;
916
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400917 ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
918 ALLOC(bandE,st->mode->nbEBands*C, celt_ener);
919 ALLOC(bandLogE,st->mode->nbEBands*C, celt_word16);
Jean-Marc Valin32ec58c2009-05-01 21:28:58 -0400920 /* Compute MDCTs */
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400921 compute_mdcts(st->mode, shortBlocks, in, freq, C, LM);
Jean-Marc Valin08a82ff2009-06-14 14:05:19 -0400922
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400923 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
Jean-Marc Valin8d4ac152008-02-29 17:24:02 +1100924
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400925 compute_band_energies(st->mode, freq, bandE, effEnd, C, M);
Jean-Marc Valin504fb3c2010-08-06 15:56:22 -0400926
927 amp2Log2(st->mode, effEnd, st->end, bandE, bandLogE, C);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400928
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100929 /* Band normalisation */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400930 normalise_bands(st->mode, freq, X, bandE, effEnd, C, M);
Jean-Marc Valin4c77ea92009-09-14 22:50:41 -0400931
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400932 ALLOC(tf_res, st->mode->nbEBands, int);
933 /* Needs to be before coarse energy quantization because otherwise the energy gets modified */
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -0500934 tf_select = tf_analysis(st->mode, bandLogE, oldBandE, effEnd, C, isTransient, tf_res, effectiveBytes, X, N, LM, &tf_sum);
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400935 for (i=effEnd;i<st->end;i++)
936 tf_res[i] = tf_res[effEnd-1];
937
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400938 ALLOC(error, C*st->mode->nbEBands, celt_word16);
Jean-Marc Valin5e7f02d2010-08-08 09:48:22 -0400939 quant_coarse_energy(st->mode, st->start, st->end, effEnd, bandLogE,
Timothy B. Terriberryef2e6502010-11-09 01:43:18 -0800940 oldBandE, nbCompressedBytes*8, error, enc,
941 C, LM, nbAvailableBytes, st->force_intra,
Jean-Marc Valin1b36d6c2010-08-31 17:21:52 -0400942 &st->delayedIntra, st->complexity >= 4);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400943
Jean-Marc Valinf9fdbff2010-09-05 21:02:38 -0400944 if (LM > 0)
945 ec_enc_bit_prob(enc, shortBlocks!=0, 8192);
Jean-Marc Valin4c77ea92009-09-14 22:50:41 -0400946
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -0500947 tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc);
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -0400948
Jean-Marc Valin5c803912010-12-16 14:11:48 -0500949 if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C)
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -0400950 {
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400951 if (st->complexity == 0)
952 {
953 has_fold = 0;
954 st->fold_decision = 3;
955 } else {
956 has_fold = 1;
957 st->fold_decision = 1;
958 }
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -0400959 } else {
960 has_fold = folding_decision(st->mode, X, &st->tonal_average, &st->fold_decision, effEnd, C, M);
961 }
Jean-Marc Valin9099bc32010-08-07 21:50:01 -0400962 ec_enc_bit_prob(enc, has_fold>>1, 8192);
963 ec_enc_bit_prob(enc, has_fold&1, (has_fold>>1) ? 32768 : 49152);
964
Jean-Marc Valinf1fea662010-10-09 22:58:52 -0400965 ALLOC(offsets, st->mode->nbEBands, int);
966
967 for (i=0;i<st->mode->nbEBands;i++)
968 offsets[i] = 0;
969 /* Dynamic allocation code */
970 /* Make sure that dynamic allocation can't make us bust the budget */
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -0500971 if (effectiveBytes > 50 && LM>=1)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -0400972 {
973 int t1, t2;
974 if (LM <= 1)
975 {
976 t1 = 3;
977 t2 = 5;
978 } else {
979 t1 = 2;
980 t2 = 4;
981 }
982 for (i=1;i<st->mode->nbEBands-1;i++)
983 {
Jean-Marc Valina3a066c2010-11-04 15:15:54 -0400984 celt_word32 d2;
985 d2 = 2*bandLogE[i]-bandLogE[i-1]-bandLogE[i+1];
986 if (C==2)
987 d2 = HALF32(d2 + 2*bandLogE[i+st->mode->nbEBands]-
988 bandLogE[i-1+st->mode->nbEBands]-bandLogE[i+1+st->mode->nbEBands]);
989 if (d2 > SHL16(t1,DB_SHIFT))
Jean-Marc Valinf1fea662010-10-09 22:58:52 -0400990 offsets[i] += 1;
Jean-Marc Valina3a066c2010-11-04 15:15:54 -0400991 if (d2 > SHL16(t2,DB_SHIFT))
Jean-Marc Valinf1fea662010-10-09 22:58:52 -0400992 offsets[i] += 1;
993 }
994 }
995 for (i=0;i<st->mode->nbEBands;i++)
996 {
997 int j;
998 ec_enc_bit_prob(enc, offsets[i]!=0, 1024);
999 if (offsets[i]!=0)
1000 {
1001 for (j=0;j<offsets[i]-1;j++)
1002 ec_enc_bit_prob(enc, 1, 32768);
1003 ec_enc_bit_prob(enc, 0, 32768);
1004 }
1005 offsets[i] *= (6<<BITRES);
1006 }
Jean-Marc Valinc40addc2010-10-22 14:57:07 -04001007 alloc_trim = alloc_trim_analysis(st->mode, X, bandLogE, st->mode->nbEBands, LM, C, N);
1008 ec_encode_bin(enc, trim_cdf[alloc_trim], trim_cdf[alloc_trim+1], 7);
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001009
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001010 /* Variable bitrate */
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001011 if (st->vbr_rate_norm>0)
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001012 {
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001013 celt_word16 alpha;
Jean-Marc Valina4badac2010-12-03 15:20:11 -05001014 celt_int32 delta, tell;
Gregory Maxwella9411472010-10-28 03:52:21 -04001015 /* The target rate in 8th bits per frame */
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001016 celt_int32 vbr_rate;
1017 celt_int32 target;
Jean-Marc Valina4badac2010-12-03 15:20:11 -05001018 celt_int32 vbr_bound, max_allowed, min_allowed;
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001019
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001020 target = vbr_rate = M*st->vbr_rate_norm;
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001021
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001022 target = target + st->vbr_offset - ((40*C+20)<<BITRES);
1023
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001024 /* Shortblocks get a large boost in bitrate, but since they
Jean-Marc Valinccd5a612010-10-13 01:11:55 -04001025 are uncommon long blocks are not greatly affected */
1026 if (shortBlocks || tf_sum < -2*(st->end-st->start))
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001027 target = 7*target/4;
Jean-Marc Valinccd5a612010-10-13 01:11:55 -04001028 else if (tf_sum < -(st->end-st->start))
1029 target = 3*target/2;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001030 else if (M > 1)
Jean-Marc Valinccd5a612010-10-13 01:11:55 -04001031 target-=(target+14)/28;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001032
Jean-Marc Valina4badac2010-12-03 15:20:11 -05001033 tell = ec_enc_tell(enc, BITRES);
1034
Gregory Maxwella9411472010-10-28 03:52:21 -04001035 /* The current offset is removed from the target and the space used
1036 so far is added*/
Jean-Marc Valina4badac2010-12-03 15:20:11 -05001037 target=target+tell;
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001038 /* By how much did we "miss" the target on that frame */
1039 delta = target - vbr_rate;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001040
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001041 /* Computes the max bit-rate allowed in VBR more to avoid violating the target rate and buffering */
1042 vbr_bound = vbr_rate;
Jean-Marc Valin9faf7402010-12-04 10:27:22 -05001043 if (st->constrained_vbr)
1044 max_allowed = IMIN(vbr_rate+vbr_bound-st->vbr_reservoir>>(BITRES+3),nbAvailableBytes);
1045 else
1046 max_allowed = nbAvailableBytes;
Jean-Marc Valina4badac2010-12-03 15:20:11 -05001047 min_allowed = (tell>>(BITRES+3)) + 2 - nbFilledBytes;
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001048
1049 /* In VBR mode the frame size must not be reduced so much that it would result in the encoder running out of bits */
1050 nbAvailableBytes = target+(1<<(BITRES+2))>>(BITRES+3);
Jean-Marc Valina4badac2010-12-03 15:20:11 -05001051 nbAvailableBytes=IMAX(min_allowed,IMIN(max_allowed,nbAvailableBytes));
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001052 target=nbAvailableBytes<<(BITRES+3);
1053
Gregory Maxwella9411472010-10-28 03:52:21 -04001054 if (st->vbr_count < 970)
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001055 {
1056 st->vbr_count++;
Gregory Maxwella9411472010-10-28 03:52:21 -04001057 alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+20),16));
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001058 } else
1059 alpha = QCONST16(.001f,15);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001060 /* How many bits have we used in excess of what we're allowed */
Jean-Marc Valin9faf7402010-12-04 10:27:22 -05001061 if (st->constrained_vbr)
1062 st->vbr_reservoir += target - vbr_rate;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001063 /*printf ("%d\n", st->vbr_reservoir);*/
1064
1065 /* Compute the offset we need to apply in order to reach the target */
Jean-Marc Valin736efd62010-08-31 11:52:45 -04001066 st->vbr_drift += (celt_int32)MULT16_32_Q15(alpha,delta-st->vbr_offset-st->vbr_drift);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001067 st->vbr_offset = -st->vbr_drift;
1068 /*printf ("%d\n", st->vbr_drift);*/
1069
1070 /* We could use any multiple of vbr_rate as bound (depending on the delay) */
Jean-Marc Valin9faf7402010-12-04 10:27:22 -05001071 if (st->constrained_vbr && st->vbr_reservoir < 0)
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001072 {
1073 /* We're under the min value -- increase rate */
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001074 int adjust = (-st->vbr_reservoir)/(8<<BITRES);
1075 nbAvailableBytes += adjust;
1076 st->vbr_reservoir = 0;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001077 /*printf ("+%d\n", adjust);*/
1078 }
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001079 nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes);
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04001080
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001081 /* This moves the raw bits to take into account the new compressed size */
Jean-Marc Valine6108642009-08-01 23:05:47 +02001082 ec_byte_shrink(&buf, nbCompressedBytes);
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001083 }
1084
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001085 if (C==2)
1086 {
Jean-Marc Valincd84e3d2010-12-16 22:29:35 -05001087 /* Always use MS for 2.5 ms frames until we can do a better analysis */
1088 if (LM==0)
1089 dual_stereo = 0;
1090 else
1091 dual_stereo = stereo_analysis(st->mode, X, st->mode->nbEBands, LM, C, N);
Jean-Marc Valine65978f2010-12-02 13:46:48 -05001092 ec_enc_bit_prob(enc, dual_stereo, 32768);
1093 }
1094 if (C==2)
1095 {
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001096 int effectiveRate;
1097
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001098 /* Account for coarse energy */
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001099 effectiveRate = (8*effectiveBytes - 80)>>LM;
1100
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001101 /* effectiveRate in kb/s */
1102 effectiveRate = 2*effectiveRate/5;
1103 if (effectiveRate<35)
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -05001104 intensity = 8;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001105 else if (effectiveRate<50)
1106 intensity = 12;
1107 else if (effectiveRate<68)
1108 intensity = 16;
1109 else if (effectiveRate<84)
1110 intensity = 18;
1111 else if (effectiveRate<102)
1112 intensity = 19;
1113 else if (effectiveRate<130)
1114 intensity = 20;
1115 else
1116 intensity = 100;
1117 intensity = IMIN(st->end,IMAX(st->start, intensity));
1118 ec_enc_uint(enc, intensity, 1+st->end-st->start);
1119 }
1120
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001121 /* Bit allocation */
1122 ALLOC(fine_quant, st->mode->nbEBands, int);
1123 ALLOC(pulses, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04001124 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +11001125
Timothy B. Terriberry76ea41e2010-12-16 14:39:58 -08001126 /* bits = packet size - where we are - safety */
1127 bits = (nbCompressedBytes*8<<BITRES) - ec_enc_tell(enc, BITRES) - 1;
Jean-Marc Valindfd6e712010-12-09 23:23:34 -05001128 codedBands = compute_allocation(st->mode, st->start, st->end, offsets,
Timothy B. Terriberryb2f59002010-12-15 05:12:43 -08001129 alloc_trim, bits, pulses, fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands);
Jean-Marc Valindfd6e712010-12-09 23:23:34 -05001130 st->lastCodedBands = codedBands;
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -05001131
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001132 quant_fine_energy(st->mode, st->start, st->end, bandE, oldBandE, error, fine_quant, enc, C);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001133
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +02001134#ifdef MEASURE_NORM_MSE
Jean-Marc Valin44092242010-07-29 18:32:54 +02001135 float X0[3000];
1136 float bandE0[60];
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001137 c=0; do
Jean-Marc Valin44092242010-07-29 18:32:54 +02001138 for (i=0;i<N;i++)
1139 X0[i+c*N] = X[i+c*N];
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001140 while (++c<C);
Jean-Marc Valin44092242010-07-29 18:32:54 +02001141 for (i=0;i<C*st->mode->nbEBands;i++)
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +02001142 bandE0[i] = bandE[i];
1143#endif
1144
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11001145 /* Residual quantisation */
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001146 quant_all_bands(1, st->mode, st->start, st->end, X, C==2 ? X+N : NULL,
Jean-Marc Valine65978f2010-12-02 13:46:48 -05001147 bandE, pulses, shortBlocks, has_fold, dual_stereo, intensity, tf_res, resynth,
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001148 nbCompressedBytes*8, enc, LM, codedBands);
Jean-Marc Valin39710532009-06-09 00:10:32 -04001149
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001150 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 -04001151
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001152#ifdef RESYNTH
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -05001153 /* Re-synthesis of the coded audio if required */
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -04001154 if (resynth)
Jean-Marc Valin18ddc022008-02-22 14:24:50 +11001155 {
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001156 celt_sig *out_mem[2];
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001157 celt_sig *overlap_mem[2];
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001158
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001159 log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04001160
1161#ifdef MEASURE_NORM_MSE
1162 measure_norm_mse(st->mode, X, X0, bandE, bandE0, M, N, C);
1163#endif
1164
Jean-Marc Valin88619552009-10-04 21:35:36 -04001165 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001166 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valin88619552009-10-04 21:35:36 -04001167
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001168 CELT_MOVE(st->syn_mem[0], st->syn_mem[0]+N, MAX_PERIOD);
1169 if (C==2)
1170 CELT_MOVE(st->syn_mem[1], st->syn_mem[1]+N, MAX_PERIOD);
1171
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001172 c=0; do
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -04001173 for (i=0;i<M*st->mode->eBands[st->start];i++)
1174 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001175 while (++c<C);
1176 c=0; do
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -04001177 for (i=M*st->mode->eBands[st->end];i<N;i++)
1178 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001179 while (++c<C);
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -04001180
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001181 out_mem[0] = st->syn_mem[0]+MAX_PERIOD;
1182 if (C==2)
1183 out_mem[1] = st->syn_mem[1]+MAX_PERIOD;
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001184
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001185 c=0; do
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001186 overlap_mem[c] = _overlap_mem + c*st->overlap;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001187 while (++c<C);
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001188
Jean-Marc Valin7a08ddd2010-10-18 14:55:42 -04001189 compute_inv_mdcts(st->mode, shortBlocks, freq, out_mem, overlap_mem, C, LM);
Jean-Marc Valine12017e2009-10-03 13:57:31 -04001190
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001191#ifdef ENABLE_POSTFILTER
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001192 c=0; do {
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001193 st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);
1194 st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD);
1195 if (LM!=0)
1196 {
1197 comb_filter(out_mem[c], out_mem[c], st->prefilter_period, st->prefilter_period, st->overlap, C,
1198 st->prefilter_gain, st->prefilter_gain, NULL, 0);
1199 comb_filter(out_mem[c]+st->overlap, out_mem[c]+st->overlap, st->prefilter_period, pitch_index, N-st->overlap, C,
1200 st->prefilter_gain, gain1, st->mode->window, st->mode->overlap);
1201 } else {
1202 comb_filter(out_mem[c], out_mem[c], st->prefilter_period_old, st->prefilter_period, N, C,
1203 st->prefilter_gain_old, st->prefilter_gain, st->mode->window, st->mode->overlap);
1204 }
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001205 } while (++c<C);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001206#endif /* ENABLE_POSTFILTER */
1207
1208 deemphasis(out_mem, (celt_word16*)pcm, N, C, st->mode->preemph, st->preemph_memD);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001209 st->prefilter_period_old = st->prefilter_period;
1210 st->prefilter_gain_old = st->prefilter_gain;
Jean-Marc Valind9b95652008-08-31 23:34:47 -04001211 }
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001212#endif
1213
1214 st->prefilter_period = pitch_index;
1215 st->prefilter_gain = gain1;
Gregory Maxwell54547f12009-02-16 18:56:44 -05001216
Jean-Marc Valin30d51252010-06-21 17:55:28 -04001217 /* If there's any room left (can only happen for very high rates),
1218 fill it with zeros */
Jean-Marc Valin5d774e02010-08-04 17:17:18 -04001219 while (ec_enc_tell(enc,0) + 8 <= nbCompressedBytes*8)
Jean-Marc Valin30d51252010-06-21 17:55:28 -04001220 ec_enc_bits(enc, 0, 8);
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001221 ec_enc_done(enc);
Jean-Marc Valinc871c8d2009-06-09 00:57:00 -04001222
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001223 RESTORE_STACK;
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001224 if (ec_enc_get_error(enc))
Jean-Marc Valin9d785af2010-07-18 09:42:05 -04001225 return CELT_CORRUPTED_DATA;
1226 else
1227 return nbCompressedBytes;
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11001228}
1229
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001230#ifdef FIXED_POINT
1231#ifndef DISABLE_FLOAT_API
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001232int celt_encode_with_ec_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001233{
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001234 int j, ret, C, N, LM, M;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001235 VARDECL(celt_int16, in);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -04001236 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001237
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001238 if (pcm==NULL)
1239 return CELT_BAD_ARG;
1240
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001241 for (LM=0;LM<4;LM++)
1242 if (st->mode->shortMdctSize<<LM==frame_size)
1243 break;
1244 if (LM>=MAX_CONFIG_SIZES)
1245 return CELT_BAD_ARG;
1246 M=1<<LM;
1247
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001248 C = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001249 N = M*st->mode->shortMdctSize;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001250 ALLOC(in, C*N, celt_int16);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001251
1252 for (j=0;j<C*N;j++)
1253 in[j] = FLOAT2INT16(pcm[j]);
1254
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001255 ret=celt_encode_with_ec(st,in,frame_size,compressed,nbCompressedBytes, enc);
1256#ifdef RESYNTH
1257 for (j=0;j<C*N;j++)
1258 ((float*)pcm)[j]=in[j]*(1.f/32768.f);
1259#endif
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001260 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001261 return ret;
1262
1263}
1264#endif /*DISABLE_FLOAT_API*/
1265#else
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001266int celt_encode_with_ec(CELTEncoder * restrict st, const celt_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001267{
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001268 int j, ret, C, N, LM, M;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001269 VARDECL(celt_sig, in);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -04001270 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001271
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001272 if (pcm==NULL)
1273 return CELT_BAD_ARG;
1274
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001275 for (LM=0;LM<4;LM++)
1276 if (st->mode->shortMdctSize<<LM==frame_size)
1277 break;
1278 if (LM>=MAX_CONFIG_SIZES)
1279 return CELT_BAD_ARG;
1280 M=1<<LM;
1281
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001282 C=CHANNELS(st->channels);
Jean-Marc Valin04752672010-05-05 07:21:21 -04001283 N=M*st->mode->shortMdctSize;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001284 ALLOC(in, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001285 for (j=0;j<C*N;j++) {
1286 in[j] = SCALEOUT(pcm[j]);
1287 }
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001288
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001289 ret = celt_encode_with_ec_float(st,in,frame_size,compressed,nbCompressedBytes, enc);
1290#ifdef RESYNTH
1291 for (j=0;j<C*N;j++)
1292 ((celt_int16*)pcm)[j] = FLOAT2INT16(in[j]);
1293#endif
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001294 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001295 return ret;
1296}
1297#endif
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +11001298
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001299int celt_encode(CELTEncoder * restrict st, const celt_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1300{
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001301 return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001302}
1303
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001304#ifndef DISABLE_FLOAT_API
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001305int celt_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1306{
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001307 return celt_encode_with_ec_float(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001308}
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001309#endif /* DISABLE_FLOAT_API */
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001310
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001311int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...)
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001312{
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001313 va_list ap;
Gregory Maxwell17169992009-06-04 15:15:34 -04001314
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001315 va_start(ap, request);
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001316 switch (request)
1317 {
Gregory Maxwellf3b44ef2009-06-03 13:37:45 -04001318 case CELT_GET_MODE_REQUEST:
1319 {
1320 const CELTMode ** value = va_arg(ap, const CELTMode**);
1321 if (value==0)
1322 goto bad_arg;
1323 *value=st->mode;
1324 }
1325 break;
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001326 case CELT_SET_COMPLEXITY_REQUEST:
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001327 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001328 int value = va_arg(ap, celt_int32);
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001329 if (value<0 || value>10)
1330 goto bad_arg;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001331 st->complexity = value;
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001332 }
1333 break;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001334 case CELT_SET_START_BAND_REQUEST:
1335 {
1336 celt_int32 value = va_arg(ap, celt_int32);
1337 if (value<0 || value>=st->mode->nbEBands)
1338 goto bad_arg;
1339 st->start = value;
1340 }
1341 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001342 case CELT_SET_END_BAND_REQUEST:
1343 {
1344 celt_int32 value = va_arg(ap, celt_int32);
1345 if (value<0 || value>=st->mode->nbEBands)
1346 goto bad_arg;
1347 st->end = value;
1348 }
1349 break;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001350 case CELT_SET_PREDICTION_REQUEST:
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001351 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001352 int value = va_arg(ap, celt_int32);
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001353 if (value<0 || value>2)
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001354 goto bad_arg;
1355 if (value==0)
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001356 {
1357 st->force_intra = 1;
Gregory Maxwella80958b2009-06-29 12:48:57 -04001358 } else if (value==1) {
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001359 st->force_intra = 0;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001360 } else {
1361 st->force_intra = 0;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001362 }
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001363 }
1364 break;
Jean-Marc Valin79b34eb2010-12-05 17:22:06 -05001365 case CELT_SET_VBR_CONSTRAINT_REQUEST:
1366 {
1367 celt_int32 value = va_arg(ap, celt_int32);
1368 st->constrained_vbr = value;
1369 }
1370 break;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001371 case CELT_SET_VBR_RATE_REQUEST:
1372 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001373 celt_int32 value = va_arg(ap, celt_int32);
Jean-Marc Valin8cc945c2010-05-29 08:07:18 -04001374 int frame_rate;
1375 int N = st->mode->shortMdctSize;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001376 if (value<0)
1377 goto bad_arg;
1378 if (value>3072000)
1379 value = 3072000;
Jean-Marc Valin8cc945c2010-05-29 08:07:18 -04001380 frame_rate = ((st->mode->Fs<<3)+(N>>1))/N;
1381 st->vbr_rate_norm = ((value<<(BITRES+3))+(frame_rate>>1))/frame_rate;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001382 }
1383 break;
John Ridges454d1d02009-05-21 22:38:39 -04001384 case CELT_RESET_STATE:
1385 {
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001386 CELT_MEMSET((char*)&st->ENCODER_RESET_START, 0,
1387 celt_encoder_get_size(st->mode, st->channels)-
1388 ((char*)&st->ENCODER_RESET_START - (char*)st));
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001389 st->vbr_offset = 0;
John Ridges454d1d02009-05-21 22:38:39 -04001390 st->delayedIntra = 1;
John Ridges5378bf82010-02-12 07:08:01 -05001391 st->fold_decision = 1;
Jean-Marc Valin628c0252010-04-16 20:57:56 -04001392 st->tonal_average = QCONST16(1.f,8);
John Ridges454d1d02009-05-21 22:38:39 -04001393 }
1394 break;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001395 default:
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001396 goto bad_request;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001397 }
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001398 va_end(ap);
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001399 return CELT_OK;
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001400bad_arg:
1401 va_end(ap);
1402 return CELT_BAD_ARG;
1403bad_request:
1404 va_end(ap);
1405 return CELT_UNIMPLEMENTED;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001406}
1407
Jean-Marc Valin56522ad2009-06-05 17:17:25 -04001408/**********************************************************************/
1409/* */
1410/* DECODER */
1411/* */
1412/**********************************************************************/
Jean-Marc Valineafbdd52009-04-27 19:35:09 -04001413#define DECODE_BUFFER_SIZE 2048
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001414
Jean-Marc Valin276de722008-02-20 17:45:51 +11001415/** Decoder state
1416 @brief Decoder state
1417 */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001418struct CELTDecoder {
1419 const CELTMode *mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001420 int overlap;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001421 int channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001422
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001423 int start, end;
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001424
1425 /* Everything beyond this point gets cleared on a reset */
1426#define DECODER_RESET_START last_pitch_index
1427
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001428 int last_pitch_index;
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001429 int loss_count;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001430 int postfilter_period;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001431 int postfilter_period_old;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001432 celt_word16 postfilter_gain;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001433 celt_word16 postfilter_gain_old;
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001434
1435 celt_sig preemph_memD[2];
1436
Jean-Marc Valinca8b9922010-08-27 16:23:03 -04001437 celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */
1438 /* celt_word16 lpc[], Size = channels*LPC_ORDER */
1439 /* celt_word16 oldEBands[], Size = channels*mode->nbEBands */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001440};
1441
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001442int celt_decoder_get_size(const CELTMode *mode, int channels)
1443{
1444 int size = sizeof(struct CELTDecoder)
1445 + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig)
1446 + channels*LPC_ORDER*sizeof(celt_word16)
1447 + channels*mode->nbEBands*sizeof(celt_word16);
1448 return size;
1449}
1450
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001451CELTDecoder *celt_decoder_create(const CELTMode *mode, int channels, int *error)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001452{
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -04001453 return celt_decoder_init(
1454 (CELTDecoder *)celt_alloc(celt_decoder_get_size(mode, channels)),
1455 mode, channels, error);
1456}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001457
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -04001458CELTDecoder *celt_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels, int *error)
1459{
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001460 if (channels < 0 || channels > 2)
1461 {
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001462 if (error)
1463 *error = CELT_BAD_ARG;
1464 return NULL;
1465 }
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001466
Gregory Maxwell17169992009-06-04 15:15:34 -04001467 if (st==NULL)
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001468 {
1469 if (error)
1470 *error = CELT_ALLOC_FAIL;
Gregory Maxwell17169992009-06-04 15:15:34 -04001471 return NULL;
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001472 }
1473
Jean-Marc Valin6d3829f2010-08-27 17:52:38 -04001474 CELT_MEMSET((char*)st, 0, celt_decoder_get_size(mode, channels));
1475
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001476 st->mode = mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001477 st->overlap = mode->overlap;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001478 st->channels = channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001479
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001480 st->start = 0;
Jean-Marc Valin8952c452010-07-16 21:48:44 -04001481 st->end = st->mode->effEBands;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001482
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001483 st->loss_count = 0;
Gregory Maxwell17169992009-06-04 15:15:34 -04001484
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001485 if (error)
1486 *error = CELT_OK;
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001487 return st;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001488}
1489
Peter Kirk19f9dc92008-06-06 14:38:38 +02001490void celt_decoder_destroy(CELTDecoder *st)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001491{
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001492 celt_free(st);
1493}
1494
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001495static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict pcm, int N, int LM)
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001496{
Jean-Marc Valin04752672010-05-05 07:21:21 -04001497 int c;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11001498 int pitch_index;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001499 int overlap = st->mode->overlap;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001500 celt_word16 fade = Q15ONE;
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001501 int i, len;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001502 const int C = CHANNELS(st->channels);
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001503 int offset;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001504 celt_sig *out_mem[2];
1505 celt_sig *decode_mem[2];
1506 celt_sig *overlap_mem[2];
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001507 celt_word16 *lpc;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001508 SAVE_STACK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001509
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001510 c=0; do {
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001511 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
1512 out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
1513 overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001514 } while (++c<C);
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001515 lpc = (celt_word16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C);
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001516
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001517 len = N+st->mode->overlap;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001518
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001519 if (st->loss_count == 0)
1520 {
Jean-Marc Valin7a7c42a2009-11-25 20:38:52 -05001521 celt_word16 pitch_buf[MAX_PERIOD>>1];
Jean-Marc Valin294863b2009-11-08 22:29:54 +09001522 celt_word32 tmp=0;
Jean-Marc Valine465c142009-11-26 00:39:36 -05001523 celt_word32 mem0[2]={0,0};
1524 celt_word16 mem1[2]={0,0};
Jean-Marc Valin6202c742010-06-01 00:30:37 -04001525 int len2 = len;
1526 /* FIXME: This is a kludge */
1527 if (len2>MAX_PERIOD>>1)
1528 len2 = MAX_PERIOD>>1;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001529 pitch_downsample(out_mem, pitch_buf, MAX_PERIOD, MAX_PERIOD,
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001530 C, mem0, mem1);
Jean-Marc Valin6202c742010-06-01 00:30:37 -04001531 pitch_search(st->mode, pitch_buf+((MAX_PERIOD-len2)>>1), pitch_buf, len2,
1532 MAX_PERIOD-len2-100, &pitch_index, &tmp, 1<<LM);
1533 pitch_index = MAX_PERIOD-len2-pitch_index;
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001534 st->last_pitch_index = pitch_index;
1535 } else {
1536 pitch_index = st->last_pitch_index;
1537 if (st->loss_count < 5)
1538 fade = QCONST16(.8f,15);
1539 else
1540 fade = 0;
1541 }
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001542
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001543 c=0; do {
Jean-Marc Valin6202c742010-06-01 00:30:37 -04001544 /* FIXME: This is more memory than necessary */
1545 celt_word32 e[2*MAX_PERIOD];
1546 celt_word16 exc[2*MAX_PERIOD];
Jean-Marc Valin456eab22010-06-16 22:38:57 -04001547 celt_word32 ac[LPC_ORDER+1];
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001548 celt_word16 decay = 1;
1549 celt_word32 S1=0;
Jean-Marc Valin74128be2010-01-01 09:33:17 -05001550 celt_word16 mem[LPC_ORDER]={0};
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001551
Jean-Marc Valind5f99302009-12-16 22:42:32 -05001552 offset = MAX_PERIOD-pitch_index;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001553 for (i=0;i<MAX_PERIOD;i++)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001554 exc[i] = ROUND16(out_mem[c][i], SIG_SHIFT);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001555
1556 if (st->loss_count == 0)
1557 {
1558 _celt_autocorr(exc, ac, st->mode->window, st->mode->overlap,
1559 LPC_ORDER, MAX_PERIOD);
1560
Jean-Marc Valin456eab22010-06-16 22:38:57 -04001561 /* Noise floor -40 dB */
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001562#ifdef FIXED_POINT
1563 ac[0] += SHR32(ac[0],13);
1564#else
Jean-Marc Valinae01e112010-08-03 21:43:41 -04001565 ac[0] *= 1.0001f;
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001566#endif
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001567 /* Lag windowing */
1568 for (i=1;i<=LPC_ORDER;i++)
1569 {
1570 /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001571#ifdef FIXED_POINT
1572 ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);
1573#else
Jean-Marc Valinae01e112010-08-03 21:43:41 -04001574 ac[i] -= ac[i]*(.008f*i)*(.008f*i);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001575#endif
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001576 }
1577
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001578 _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001579 }
Jean-Marc Valinbc4a0022010-11-06 18:11:06 -04001580 for (i=0;i<LPC_ORDER;i++)
Jean-Marc Valine53c4bc2010-11-06 21:41:40 -04001581 mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001582 fir(exc, lpc+c*LPC_ORDER, exc, MAX_PERIOD, LPC_ORDER, mem);
Jean-Marc Valin74128be2010-01-01 09:33:17 -05001583 /*for (i=0;i<MAX_PERIOD;i++)printf("%d ", exc[i]); printf("\n");*/
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001584 /* Check if the waveform is decaying (and if so how fast) */
1585 {
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001586 celt_word32 E1=1, E2=1;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001587 int period;
1588 if (pitch_index <= MAX_PERIOD/2)
1589 period = pitch_index;
1590 else
1591 period = MAX_PERIOD/2;
1592 for (i=0;i<period;i++)
1593 {
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001594 E1 += SHR32(MULT16_16(exc[MAX_PERIOD-period+i],exc[MAX_PERIOD-period+i]),8);
1595 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 -05001596 }
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001597 if (E1 > E2)
1598 E1 = E2;
1599 decay = celt_sqrt(frac_div32(SHR(E1,1),E2));
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001600 }
1601
1602 /* Copy excitation, taking decay into account */
1603 for (i=0;i<len+st->mode->overlap;i++)
1604 {
Jean-Marc Valin1ad93cf2010-11-06 22:02:32 -04001605 celt_word16 tmp;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001606 if (offset+i >= MAX_PERIOD)
1607 {
1608 offset -= pitch_index;
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001609 decay = MULT16_16_Q15(decay, decay);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001610 }
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001611 e[i] = SHL32(EXTEND32(MULT16_16_Q15(decay, exc[offset+i])), SIG_SHIFT);
Jean-Marc Valin1ad93cf2010-11-06 22:02:32 -04001612 tmp = ROUND16(out_mem[c][offset+i],SIG_SHIFT);
1613 S1 += SHR32(MULT16_16(tmp,tmp),8);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001614 }
Jean-Marc Valinbc2c4542010-10-28 14:27:05 -04001615 for (i=0;i<LPC_ORDER;i++)
Jean-Marc Valine53c4bc2010-11-06 21:41:40 -04001616 mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
Jean-Marc Valinbc2c4542010-10-28 14:27:05 -04001617 for (i=0;i<len+st->mode->overlap;i++)
1618 e[i] = MULT16_32_Q15(fade, e[i]);
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001619 iir(e, lpc+c*LPC_ORDER, e, len+st->mode->overlap, LPC_ORDER, mem);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001620
1621 {
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04001622 celt_word32 S2=0;
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001623 for (i=0;i<len+overlap;i++)
Jean-Marc Valin1ad93cf2010-11-06 22:02:32 -04001624 {
1625 celt_word16 tmp = ROUND16(e[i],SIG_SHIFT);
1626 S2 += SHR32(MULT16_16(tmp,tmp),8);
1627 }
Jean-Marc Valinfeca0952010-06-17 20:25:51 -04001628 /* This checks for an "explosion" in the synthesis */
1629#ifdef FIXED_POINT
1630 if (!(S1 > SHR32(S2,2)))
1631#else
1632 /* Float test is written this way to catch NaNs at the same time */
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05001633 if (!(S1 > 0.2f*S2))
Jean-Marc Valinfeca0952010-06-17 20:25:51 -04001634#endif
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05001635 {
1636 for (i=0;i<len+overlap;i++)
1637 e[i] = 0;
1638 } else if (S1 < S2)
1639 {
Jean-Marc Valin12996402010-08-04 09:13:24 -04001640 celt_word16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05001641 for (i=0;i<len+overlap;i++)
Jean-Marc Valin1ad93cf2010-11-06 22:02:32 -04001642 e[i] = MULT16_32_Q15(ratio, e[i]);
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05001643 }
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001644 }
1645
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001646#ifdef ENABLE_POSTFILTER
1647 /* Apply post-filter to the MDCT overlap of the previous frame */
1648 comb_filter(out_mem[c]+MAX_PERIOD, out_mem[c]+MAX_PERIOD, st->postfilter_period, st->postfilter_period, st->overlap, C,
1649 st->postfilter_gain, st->postfilter_gain, NULL, 0);
1650#endif /* ENABLE_POSTFILTER */
1651
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001652 for (i=0;i<MAX_PERIOD+st->mode->overlap-N;i++)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001653 out_mem[c][i] = out_mem[c][N+i];
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001654
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001655 /* Apply TDAC to the concealed audio so that it blends with the
1656 previous and next frames */
1657 for (i=0;i<overlap/2;i++)
1658 {
Jean-Marc Valind7231dd2010-11-06 20:30:17 -04001659 celt_word32 tmp;
1660 tmp = MULT16_32_Q15(st->mode->window[i], e[N+overlap-1-i]) +
1661 MULT16_32_Q15(st->mode->window[overlap-i-1], e[N+i ]);
1662 out_mem[c][MAX_PERIOD+i] = MULT16_32_Q15(st->mode->window[overlap-i-1], tmp);
1663 out_mem[c][MAX_PERIOD+overlap-i-1] = MULT16_32_Q15(st->mode->window[i], tmp);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001664 }
Jean-Marc Valinbc4a0022010-11-06 18:11:06 -04001665 for (i=0;i<N;i++)
1666 out_mem[c][MAX_PERIOD-N+i] = e[i];
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001667
1668#ifdef ENABLE_POSTFILTER
1669 /* Apply pre-filter to the MDCT overlap for the next frame (post-filter will be applied then) */
1670 comb_filter(e, out_mem[c]+MAX_PERIOD, st->postfilter_period, st->postfilter_period, st->overlap, C,
1671 -st->postfilter_gain, -st->postfilter_gain, NULL, 0);
1672#endif /* ENABLE_POSTFILTER */
1673 for (i=0;i<overlap;i++)
1674 out_mem[c][MAX_PERIOD+i] = e[i];
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001675 } while (++c<C);
Jean-Marc Valin1677aa92007-12-08 01:13:34 +11001676
Jean-Marc Valinbc2c4542010-10-28 14:27:05 -04001677 {
1678 celt_word32 *out_syn[2];
1679 out_syn[0] = out_mem[0]+MAX_PERIOD-N;
1680 if (C==2)
1681 out_syn[1] = out_mem[1]+MAX_PERIOD-N;
1682 deemphasis(out_syn, pcm, N, C, st->mode->preemph, st->preemph_memD);
1683 }
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001684
1685 st->loss_count++;
1686
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001687 RESTORE_STACK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001688}
1689
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001690#ifdef FIXED_POINT
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001691int 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 +11001692{
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001693#else
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001694int 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 -04001695{
1696#endif
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -04001697 int c, i, N;
Jean-Marc Valin8cbea172010-08-05 15:22:57 -04001698 int has_fold;
Jean-Marc Valinc890b582008-08-01 22:26:49 -04001699 int bits;
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001700 ec_dec _dec;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11001701 ec_byte_buffer buf;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001702 VARDECL(celt_sig, freq);
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001703 VARDECL(celt_norm, X);
1704 VARDECL(celt_ener, bandE);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001705 VARDECL(int, fine_quant);
1706 VARDECL(int, pulses);
1707 VARDECL(int, offsets);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04001708 VARDECL(int, fine_priority);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -04001709 VARDECL(int, tf_res);
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001710 celt_sig *out_mem[2];
1711 celt_sig *decode_mem[2];
1712 celt_sig *overlap_mem[2];
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04001713 celt_sig *out_syn[2];
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001714 celt_word16 *lpc;
1715 celt_word16 *oldBandE;
Jean-Marc Valinc890b582008-08-01 22:26:49 -04001716
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +10001717 int shortBlocks;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001718 int isTransient;
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -04001719 int intra_ener;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001720 const int C = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001721 int LM, M;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04001722 int nbFilledBytes, nbAvailableBytes;
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001723 int effEnd;
Jean-Marc Valinb801da52010-09-28 14:56:20 -04001724 int codedBands;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001725 int alloc_trim;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001726 int postfilter_pitch;
1727 celt_word16 postfilter_gain;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001728 int intensity=0;
Jean-Marc Valine65978f2010-12-02 13:46:48 -05001729 int dual_stereo=0;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001730 SAVE_STACK;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001731
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001732 if (pcm==NULL)
1733 return CELT_BAD_ARG;
1734
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001735 for (LM=0;LM<4;LM++)
1736 if (st->mode->shortMdctSize<<LM==frame_size)
1737 break;
1738 if (LM>=MAX_CONFIG_SIZES)
1739 return CELT_BAD_ARG;
1740 M=1<<LM;
1741
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001742 c=0; do {
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001743 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
1744 out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
1745 overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001746 } while (++c<C);
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001747 lpc = (celt_word16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C);
1748 oldBandE = lpc+C*LPC_ORDER;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001749
Jean-Marc Valin04752672010-05-05 07:21:21 -04001750 N = M*st->mode->shortMdctSize;
Jean-Marc Valin01417232008-03-03 13:59:55 +11001751
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001752 effEnd = st->end;
1753 if (effEnd > st->mode->effEBands)
1754 effEnd = st->mode->effEBands;
1755
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001756 ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
1757 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
1758 ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001759 c=0; do
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001760 for (i=0;i<M*st->mode->eBands[st->start];i++)
1761 X[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001762 while (++c<C);
1763 c=0; do
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001764 for (i=M*st->mode->eBands[effEnd];i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001765 X[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001766 while (++c<C);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001767
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001768 if (data == NULL)
1769 {
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001770 celt_decode_lost(st, pcm, N, LM);
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001771 RESTORE_STACK;
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001772 return CELT_OK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001773 }
Gregory Maxwell520eeae2009-02-09 01:33:21 -05001774 if (len<0) {
1775 RESTORE_STACK;
1776 return CELT_BAD_ARG;
1777 }
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001778
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001779 if (dec == NULL)
1780 {
1781 ec_byte_readinit(&buf,(unsigned char*)data,len);
1782 ec_dec_init(&_dec,&buf);
1783 dec = &_dec;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04001784 nbFilledBytes = 0;
1785 } else {
Jean-Marc Valinbdcaaf72010-07-05 13:52:41 -04001786 nbFilledBytes = (ec_dec_tell(dec, 0)+4)>>3;
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001787 }
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04001788 nbAvailableBytes = len-nbFilledBytes;
1789
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001790 if (ec_dec_bit_prob(dec, 32768))
1791 {
1792#ifdef ENABLE_POSTFILTER
1793 int qg, octave;
1794 octave = ec_dec_uint(dec, 6);
1795 postfilter_pitch = (16<<octave)+ec_dec_bits(dec, 4+octave);
1796 qg = ec_dec_bits(dec, 2);
1797 postfilter_gain = QCONST16(.125f,15)*(qg+2);
1798#else /* ENABLE_POSTFILTER */
1799 RESTORE_STACK;
1800 return CELT_CORRUPTED_DATA;
1801#endif /* ENABLE_POSTFILTER */
1802
1803 } else {
1804 postfilter_gain = 0;
1805 postfilter_pitch = 0;
1806 }
1807
Jean-Marc Valin017001a2010-08-05 15:42:50 -04001808 /* Decode the global flags (first symbols in the stream) */
1809 intra_ener = ec_dec_bit_prob(dec, 8192);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001810 /* Get band energies */
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001811 unquant_coarse_energy(st->mode, st->start, st->end, bandE, oldBandE,
Timothy B. Terriberryef2e6502010-11-09 01:43:18 -08001812 intra_ener, dec, C, LM);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001813
Jean-Marc Valinf9fdbff2010-09-05 21:02:38 -04001814 if (LM > 0)
1815 isTransient = ec_dec_bit_prob(dec, 8192);
1816 else
1817 isTransient = 0;
Jean-Marc Valin017001a2010-08-05 15:42:50 -04001818
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001819 if (isTransient)
1820 shortBlocks = M;
1821 else
1822 shortBlocks = 0;
1823
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04001824 ALLOC(tf_res, st->mode->nbEBands, int);
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001825 tf_decode(st->start, st->end, C, isTransient, tf_res, LM, dec);
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04001826
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001827 has_fold = ec_dec_bit_prob(dec, 8192)<<1;
1828 has_fold |= ec_dec_bit_prob(dec, (has_fold>>1) ? 32768 : 49152);
1829
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001830 ALLOC(pulses, st->mode->nbEBands, int);
1831 ALLOC(offsets, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04001832 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001833
1834 for (i=0;i<st->mode->nbEBands;i++)
1835 offsets[i] = 0;
Jean-Marc Valind74c8512010-09-29 17:39:54 -04001836 for (i=0;i<st->mode->nbEBands;i++)
1837 {
1838 if (ec_dec_bit_prob(dec, 1024))
1839 {
1840 while (ec_dec_bit_prob(dec, 32768))
1841 offsets[i]++;
1842 offsets[i]++;
1843 offsets[i] *= (6<<BITRES);
1844 }
1845 }
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001846
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001847 ALLOC(fine_quant, st->mode->nbEBands, int);
Jean-Marc Valin6bf04622010-09-30 10:16:22 -04001848 {
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001849 int fl;
Jean-Marc Valinc40addc2010-10-22 14:57:07 -04001850 alloc_trim = 0;
Jean-Marc Valin6bf04622010-09-30 10:16:22 -04001851 fl = ec_decode_bin(dec, 7);
Jean-Marc Valinc40addc2010-10-22 14:57:07 -04001852 while (trim_cdf[alloc_trim+1] <= fl)
1853 alloc_trim++;
1854 ec_dec_update(dec, trim_cdf[alloc_trim], trim_cdf[alloc_trim+1], 128);
Jean-Marc Valin6bf04622010-09-30 10:16:22 -04001855 }
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001856
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001857 if (C==2)
Jean-Marc Valine65978f2010-12-02 13:46:48 -05001858 {
1859 dual_stereo = ec_dec_bit_prob(dec, 32768);
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001860 intensity = ec_dec_uint(dec, 1+st->end-st->start);
Jean-Marc Valine65978f2010-12-02 13:46:48 -05001861 }
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001862
Timothy B. Terriberry76ea41e2010-12-16 14:39:58 -08001863 bits = (len*8<<BITRES) - ec_dec_tell(dec, BITRES) - 1;
Jean-Marc Valindfd6e712010-12-09 23:23:34 -05001864 codedBands = compute_allocation(st->mode, st->start, st->end, offsets,
Timothy B. Terriberryb2f59002010-12-15 05:12:43 -08001865 alloc_trim, bits, pulses, fine_quant, fine_priority, C, LM, dec, 0, 0);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001866
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001867 unquant_fine_energy(st->mode, st->start, st->end, bandE, oldBandE, fine_quant, dec, C);
Jean-Marc Valin827f9312008-05-06 23:21:55 +10001868
Jean-Marc Valin8cbea172010-08-05 15:22:57 -04001869 /* Decode fixed codebook */
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001870 quant_all_bands(0, st->mode, st->start, st->end, X, C==2 ? X+N : NULL,
Jean-Marc Valine65978f2010-12-02 13:46:48 -05001871 NULL, pulses, shortBlocks, has_fold, dual_stereo, intensity, tf_res, 1,
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001872 len*8, dec, LM, codedBands);
Jean-Marc Valin746b2a82010-05-14 22:12:33 -04001873
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001874 unquant_energy_finalise(st->mode, st->start, st->end, bandE, oldBandE,
1875 fine_quant, fine_priority, len*8-ec_dec_tell(dec, 0), dec, C);
Jean-Marc Valin30d51252010-06-21 17:55:28 -04001876
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001877 log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04001878
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11001879 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001880 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11001881
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001882 CELT_MOVE(decode_mem[0], decode_mem[0]+N, DECODE_BUFFER_SIZE-N);
Jean-Marc Valin903dbf72010-08-26 20:06:49 -04001883 if (C==2)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001884 CELT_MOVE(decode_mem[1], decode_mem[1]+N, DECODE_BUFFER_SIZE-N);
Jean-Marc Valin88619552009-10-04 21:35:36 -04001885
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001886 c=0; do
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001887 for (i=0;i<M*st->mode->eBands[st->start];i++)
1888 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001889 while (++c<C);
1890 c=0; do
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001891 for (i=M*st->mode->eBands[effEnd];i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001892 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001893 while (++c<C);
Jean-Marc Valin3a0bc3d2010-02-21 15:10:22 -05001894
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001895 out_syn[0] = out_mem[0]+MAX_PERIOD-N;
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04001896 if (C==2)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001897 out_syn[1] = out_mem[1]+MAX_PERIOD-N;
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04001898
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001899 /* Compute inverse MDCTs */
Jean-Marc Valin7a08ddd2010-10-18 14:55:42 -04001900 compute_inv_mdcts(st->mode, shortBlocks, freq, out_syn, overlap_mem, C, LM);
Jean-Marc Valinffa13472007-12-10 16:54:17 +11001901
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001902#ifdef ENABLE_POSTFILTER
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001903 c=0; do {
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001904 st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD);
1905 st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD);
1906 if (LM!=0)
1907 {
1908 comb_filter(out_syn[c], out_syn[c], st->postfilter_period, st->postfilter_period, st->overlap, C,
1909 st->postfilter_gain, st->postfilter_gain, NULL, 0);
1910 comb_filter(out_syn[c]+st->overlap, out_syn[c]+st->overlap, st->postfilter_period, postfilter_pitch, N-st->overlap, C,
1911 st->postfilter_gain, postfilter_gain, st->mode->window, st->mode->overlap);
1912 } else {
1913 comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, N-st->overlap, C,
1914 st->postfilter_gain_old, st->postfilter_gain, st->mode->window, st->mode->overlap);
1915 }
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001916 } while (++c<C);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001917 st->postfilter_period_old = st->postfilter_period;
1918 st->postfilter_gain_old = st->postfilter_gain;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001919 st->postfilter_period = postfilter_pitch;
1920 st->postfilter_gain = postfilter_gain;
1921#endif /* ENABLE_POSTFILTER */
1922
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04001923 deemphasis(out_syn, pcm, N, C, st->mode->preemph, st->preemph_memD);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001924 st->loss_count = 0;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001925 RESTORE_STACK;
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001926 if (ec_dec_get_error(dec))
1927 return CELT_CORRUPTED_DATA;
1928 else
1929 return CELT_OK;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001930}
1931
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001932#ifdef FIXED_POINT
1933#ifndef DISABLE_FLOAT_API
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001934int 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 -04001935{
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001936 int j, ret, C, N, LM, M;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001937 VARDECL(celt_int16, out);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -04001938 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001939
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001940 if (pcm==NULL)
1941 return CELT_BAD_ARG;
1942
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001943 for (LM=0;LM<4;LM++)
1944 if (st->mode->shortMdctSize<<LM==frame_size)
1945 break;
1946 if (LM>=MAX_CONFIG_SIZES)
1947 return CELT_BAD_ARG;
1948 M=1<<LM;
1949
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001950 C = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001951 N = M*st->mode->shortMdctSize;
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001952
Jean-Marc Valin30f7f812009-10-17 14:35:13 -04001953 ALLOC(out, C*N, celt_int16);
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001954 ret=celt_decode_with_ec(st, data, len, out, frame_size, dec);
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001955 if (ret==0)
1956 for (j=0;j<C*N;j++)
Jean-Marc Valinae01e112010-08-03 21:43:41 -04001957 pcm[j]=out[j]*(1.f/32768.f);
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001958
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001959 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001960 return ret;
1961}
1962#endif /*DISABLE_FLOAT_API*/
1963#else
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001964int 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 -04001965{
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001966 int j, ret, C, N, LM, M;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001967 VARDECL(celt_sig, out);
Jean-Marc Valincb8780c2009-07-20 23:40:35 -04001968 SAVE_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001969
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001970 if (pcm==NULL)
1971 return CELT_BAD_ARG;
1972
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001973 for (LM=0;LM<4;LM++)
1974 if (st->mode->shortMdctSize<<LM==frame_size)
1975 break;
1976 if (LM>=MAX_CONFIG_SIZES)
1977 return CELT_BAD_ARG;
1978 M=1<<LM;
1979
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001980 C = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04001981 N = M*st->mode->shortMdctSize;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001982 ALLOC(out, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001983
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001984 ret=celt_decode_with_ec_float(st, data, len, out, frame_size, dec);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001985
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04001986 if (ret==0)
1987 for (j=0;j<C*N;j++)
1988 pcm[j] = FLOAT2INT16 (out[j]);
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001989
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001990 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001991 return ret;
1992}
1993#endif
John Ridges454d1d02009-05-21 22:38:39 -04001994
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04001995int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, celt_int16 * restrict pcm, int frame_size)
1996{
1997 return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL);
1998}
1999
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04002000#ifndef DISABLE_FLOAT_API
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002001int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size)
2002{
2003 return celt_decode_with_ec_float(st, data, len, pcm, frame_size, NULL);
2004}
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04002005#endif /* DISABLE_FLOAT_API */
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002006
John Ridges454d1d02009-05-21 22:38:39 -04002007int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
2008{
2009 va_list ap;
Gregory Maxwell17169992009-06-04 15:15:34 -04002010
John Ridges454d1d02009-05-21 22:38:39 -04002011 va_start(ap, request);
2012 switch (request)
2013 {
Gregory Maxwellf3b44ef2009-06-03 13:37:45 -04002014 case CELT_GET_MODE_REQUEST:
2015 {
2016 const CELTMode ** value = va_arg(ap, const CELTMode**);
2017 if (value==0)
2018 goto bad_arg;
2019 *value=st->mode;
2020 }
2021 break;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002022 case CELT_SET_START_BAND_REQUEST:
2023 {
2024 celt_int32 value = va_arg(ap, celt_int32);
2025 if (value<0 || value>=st->mode->nbEBands)
2026 goto bad_arg;
2027 st->start = value;
2028 }
2029 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002030 case CELT_SET_END_BAND_REQUEST:
2031 {
2032 celt_int32 value = va_arg(ap, celt_int32);
2033 if (value<0 || value>=st->mode->nbEBands)
2034 goto bad_arg;
2035 st->end = value;
2036 }
2037 break;
John Ridges454d1d02009-05-21 22:38:39 -04002038 case CELT_RESET_STATE:
2039 {
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04002040 CELT_MEMSET((char*)&st->DECODER_RESET_START, 0,
2041 celt_decoder_get_size(st->mode, st->channels)-
2042 ((char*)&st->DECODER_RESET_START - (char*)st));
John Ridges454d1d02009-05-21 22:38:39 -04002043 }
2044 break;
2045 default:
2046 goto bad_request;
2047 }
2048 va_end(ap);
2049 return CELT_OK;
John Ridges454d1d02009-05-21 22:38:39 -04002050bad_arg:
2051 va_end(ap);
2052 return CELT_BAD_ARG;
John Ridges454d1d02009-05-21 22:38:39 -04002053bad_request:
2054 va_end(ap);
2055 return CELT_UNIMPLEMENTED;
2056}
Jean-Marc Valinece94a02009-10-16 07:30:14 -04002057
2058const char *celt_strerror(int error)
2059{
2060 static const char *error_strings[8] = {
2061 "success",
2062 "invalid argument",
2063 "invalid mode",
2064 "internal error",
2065 "corrupted stream",
2066 "request not implemented",
2067 "invalid state",
2068 "memory allocation failed"
2069 };
2070 if (error > 0 || error < -7)
2071 return "unknown error";
2072 else
2073 return error_strings[-error];
2074}
2075