blob: 19d020e674ed3442d17a5653b06c80dd67a5e3b8 [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
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04003 Copyright (c) 2008 Gregory Maxwell
Jean-Marc Valin8b2ff0d2009-10-17 21:40:10 -04004 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:
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04009
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +110010 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
Gregory Maxwell71d39ad2011-07-30 00:00:29 -040012
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +110013 - 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.
Gregory Maxwell71d39ad2011-07-30 00:00:29 -040016
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +110017 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
21 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
Jean-Marc Valin02fa9132008-02-20 12:09:29 +110030#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
Jean-Marc Valin8600f692008-02-29 15:14:12 +110034#define CELT_C
35
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +110036#include "os_support.h"
Jean-Marc Valinf02ba112007-11-30 01:10:42 +110037#include "mdct.h"
38#include <math.h>
Jean-Marc Valin013c31d2007-11-30 11:36:46 +110039#include "celt.h"
Jean-Marc Valin14191b32007-11-30 12:15:49 +110040#include "pitch.h"
Jean-Marc Valin991c0f02007-11-30 16:07:46 +110041#include "bands.h"
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110042#include "modes.h"
Jean-Marc Valin6238bc02008-01-28 22:28:54 +110043#include "entcode.h"
Jean-Marc Valin98d2a492007-12-07 22:46:47 +110044#include "quant_bands.h"
Jean-Marc Valin4fbd18d2008-01-17 14:07:55 +110045#include "rate.h"
Jean-Marc Valinc7e0b762008-03-16 07:55:29 +110046#include "stack_alloc.h"
Jean-Marc Valine4aeb472008-06-29 12:06:05 +100047#include "mathops.h"
Jean-Marc Valind9b95652008-08-31 23:34:47 -040048#include "float_cast.h"
Jean-Marc Valinb6f90612008-10-05 22:39:13 -040049#include <stdarg.h>
Jean-Marc Valin6c3788c2010-06-20 22:48:50 -040050#include "plc.h"
Jean-Marc Valineafd8a72011-01-23 00:24:45 -050051#include "vq.h"
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -050052
Timothy B. Terriberry845dfa12011-01-02 16:53:28 -080053static const unsigned char trim_icdf[11] = {126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0};
54/* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */
55static const unsigned char spread_icdf[4] = {25, 23, 2, 0};
Jean-Marc Valin4b087df2010-11-30 21:08:31 -050056
Jean-Marc Valin2ce5c632011-01-17 20:50:18 -050057static const unsigned char tapset_icdf[3]={2,1,0};
58
Jean-Marc Valind6bf19d2011-03-21 07:06:09 -040059static const unsigned char toOpusTable[20] = {
60 0xE0, 0xE8, 0xF0, 0xF8,
61 0xC0, 0xC8, 0xD0, 0xD8,
62 0xA0, 0xA8, 0xB0, 0xB8,
63 0x00, 0x00, 0x00, 0x00,
64 0x80, 0x88, 0x90, 0x98,
65};
66
67static const unsigned char fromOpusTable[16] = {
68 0x80, 0x88, 0x90, 0x98,
69 0x40, 0x48, 0x50, 0x58,
70 0x20, 0x28, 0x30, 0x38,
71 0x00, 0x08, 0x10, 0x18
72};
73
74static inline int toOpus(unsigned char c)
75{
76 int ret=0;
77 if (c<0xA0)
78 ret = toOpusTable[c>>3];
79 if (ret == 0)
80 return -1;
81 else
82 return ret|(c&0x7);
83}
84
85static inline int fromOpus(unsigned char c)
86{
87 if (c<0x80)
88 return -1;
89 else
90 return fromOpusTable[(c>>3)-16] | (c&0x7);
91}
92
Jean-Marc Valin35095c62010-11-04 13:24:44 -040093#define COMBFILTER_MAXPERIOD 1024
Jean-Marc Valind1212602011-01-25 13:11:36 -050094#define COMBFILTER_MINPERIOD 15
Jean-Marc Valin6bf04622010-09-30 10:16:22 -040095
Jean-Marc Valind77d6a52011-07-29 17:33:06 -040096static int resampling_factor(opus_int32 rate)
Jean-Marc Valin913a1742011-01-29 10:00:20 -050097{
98 int ret;
99 switch (rate)
100 {
101 case 48000:
102 ret = 1;
103 break;
104 case 24000:
105 ret = 2;
106 break;
107 case 16000:
108 ret = 3;
109 break;
110 case 12000:
111 ret = 4;
112 break;
113 case 8000:
114 ret = 6;
115 break;
116 default:
117 ret = 0;
Jean-Marc Valinbe89c392011-08-30 12:39:51 -0400118 break;
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500119 }
120 return ret;
121}
122
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400123/** Encoder state
Jean-Marc Valin276de722008-02-20 17:45:51 +1100124 @brief Encoder state
125 */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +1100126struct CELTEncoder {
Jean-Marc Valin276de722008-02-20 17:45:51 +1100127 const CELTMode *mode; /**< Mode used by the encoder */
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100128 int overlap;
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100129 int channels;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -0500130 int stream_channels;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400131
Gregory Maxwell2dd3d322009-06-05 14:05:51 -0400132 int force_intra;
Jean-Marc Valin0b405d12011-02-04 01:03:42 -0500133 int clip;
Jean-Marc Valind539c6b2011-02-03 13:36:03 -0500134 int disable_pf;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400135 int complexity;
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500136 int upsample;
Jean-Marc Valinc09807d2010-08-27 17:17:50 -0400137 int start, end;
138
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400139 opus_int32 bitrate;
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500140 int vbr;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -0500141 int signalling;
Jean-Marc Valin9faf7402010-12-04 10:27:22 -0500142 int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */
Jean-Marc Valin69653882011-04-21 10:41:13 -0400143 int loss_rate;
Jean-Marc Valinc09807d2010-08-27 17:17:50 -0400144
145 /* Everything beyond this point gets cleared on a reset */
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -0500146#define ENCODER_RESET_START rng
Jean-Marc Valinc09807d2010-08-27 17:17:50 -0400147
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400148 opus_uint32 rng;
Timothy B. Terriberry320cf2e2010-12-17 05:52:06 -0800149 int spread_decision;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400150 opus_val32 delayedIntra;
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -0400151 int tonal_average;
Jean-Marc Valindfd6e712010-12-09 23:23:34 -0500152 int lastCodedBands;
Jean-Marc Valin8d367022011-01-17 16:37:51 -0500153 int hf_average;
154 int tapset_decision;
Jean-Marc Valin527db5c2009-06-02 07:56:19 -0400155
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400156 int prefilter_period;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400157 opus_val16 prefilter_gain;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500158 int prefilter_tapset;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -0500159#ifdef RESYNTH
160 int prefilter_period_old;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400161 opus_val16 prefilter_gain_old;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500162 int prefilter_tapset_old;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -0500163#endif
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -0500164 int consec_transient;
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400165
Gregory Maxwell86dd9842011-08-12 19:03:29 -0400166 opus_val32 preemph_memE[2];
167 opus_val32 preemph_memD[2];
168
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400169 /* VBR-related parameters */
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400170 opus_int32 vbr_reservoir;
171 opus_int32 vbr_drift;
172 opus_int32 vbr_offset;
173 opus_int32 vbr_count;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400174
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400175#ifdef RESYNTH
176 celt_sig syn_mem[2][2*MAX_PERIOD];
177#endif
178
Jean-Marc Valinca8b9922010-08-27 16:23:03 -0400179 celt_sig in_mem[1]; /* Size = channels*mode->overlap */
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400180 /* celt_sig prefilter_mem[], Size = channels*COMBFILTER_PERIOD */
Jean-Marc Valinca8b9922010-08-27 16:23:03 -0400181 /* celt_sig overlap_mem[], Size = channels*mode->overlap */
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400182 /* opus_val16 oldEBands[], Size = 2*channels*mode->nbEBands */
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100183};
184
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -0500185int celt_encoder_get_size(int channels)
186{
187 CELTMode *mode = celt_mode_create(48000, 960, NULL);
188 return celt_encoder_get_size_custom(mode, channels);
189}
190
191int celt_encoder_get_size_custom(const CELTMode *mode, int channels)
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400192{
193 int size = sizeof(struct CELTEncoder)
194 + (2*channels*mode->overlap-1)*sizeof(celt_sig)
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400195 + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig)
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400196 + 3*channels*mode->nbEBands*sizeof(opus_val16);
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400197 return size;
198}
199
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500200CELTEncoder *celt_encoder_create_custom(const CELTMode *mode, int channels, int *error)
201{
Jean-Marc Valin875f8db2011-08-31 16:43:08 -0400202 int ret;
Jean-Marc Valin07f88402011-08-29 15:08:51 -0400203 CELTEncoder *st = (CELTEncoder *)opus_alloc(celt_encoder_get_size_custom(mode, channels));
Jean-Marc Valin875f8db2011-08-31 16:43:08 -0400204 /* init will handle the NULL case */
205 ret = celt_encoder_init_custom(st, mode, channels);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400206 if (ret != OPUS_OK)
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -0500207 {
208 celt_encoder_destroy(st);
209 st = NULL;
Jean-Marc Valin875f8db2011-08-31 16:43:08 -0400210 if (error)
211 *error = ret;
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -0500212 }
213 return st;
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -0400214}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100215
Jean-Marc Valin875f8db2011-08-31 16:43:08 -0400216int celt_encoder_init(CELTEncoder *st, int sampling_rate, int channels)
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500217{
Jean-Marc Valin875f8db2011-08-31 16:43:08 -0400218 int ret;
219 ret = celt_encoder_init_custom(st, celt_mode_create(48000, 960, NULL), channels);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400220 if (ret != OPUS_OK)
Jean-Marc Valin875f8db2011-08-31 16:43:08 -0400221 return ret;
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500222 st->upsample = resampling_factor(sampling_rate);
223 if (st->upsample==0)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400224 return OPUS_BAD_ARG;
Jean-Marc Valin875f8db2011-08-31 16:43:08 -0400225 else
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400226 return OPUS_OK;
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500227}
228
Jean-Marc Valin875f8db2011-08-31 16:43:08 -0400229int celt_encoder_init_custom(CELTEncoder *st, const CELTMode *mode, int channels)
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -0400230{
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400231 if (channels < 0 || channels > 2)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400232 return OPUS_BAD_ARG;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100233
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -0500234 if (st==NULL || mode==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400235 return OPUS_ALLOC_FAIL;
Jean-Marc Valin6d3829f2010-08-27 17:52:38 -0400236
Jean-Marc Valinbe89c392011-08-30 12:39:51 -0400237 OPUS_CLEAR((char*)st, celt_encoder_get_size_custom(mode, channels));
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400238
Jean-Marc Valin73e51b32007-12-05 17:48:24 +1100239 st->mode = mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100240 st->overlap = mode->overlap;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -0500241 st->stream_channels = st->channels = channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100242
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500243 st->upsample = 1;
Jean-Marc Valin5f961462010-05-19 13:38:10 -0400244 st->start = 0;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400245 st->end = st->mode->effEBands;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -0500246 st->signalling = 1;
247
Jean-Marc Valin9faf7402010-12-04 10:27:22 -0500248 st->constrained_vbr = 1;
Jean-Marc Valin0b405d12011-02-04 01:03:42 -0500249 st->clip = 1;
Jean-Marc Valin5f961462010-05-19 13:38:10 -0400250
Jean-Marc Valin5e36e192011-08-16 09:12:14 -0400251 st->bitrate = -1;
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500252 st->vbr = 0;
Jean-Marc Valin30165bb2010-12-03 14:35:59 -0500253 st->vbr_offset = 0;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -0400254 st->force_intra = 0;
Gregory Maxwell8842fde2009-05-04 15:58:40 -0400255 st->delayedIntra = 1;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400256 st->tonal_average = 256;
Timothy B. Terriberry320cf2e2010-12-17 05:52:06 -0800257 st->spread_decision = SPREAD_NORMAL;
Jean-Marc Valin8d367022011-01-17 16:37:51 -0500258 st->hf_average = 0;
259 st->tapset_decision = 0;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400260 st->complexity = 5;
Jean-Marc Valina76a0b22008-01-17 22:43:05 +1100261
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400262 return OPUS_OK;
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100263}
264
Peter Kirk19f9dc92008-06-06 14:38:38 +0200265void celt_encoder_destroy(CELTEncoder *st)
Jean-Marc Valin14191b32007-11-30 12:15:49 +1100266{
Jean-Marc Valin07f88402011-08-29 15:08:51 -0400267 opus_free(st);
Jean-Marc Valin14191b32007-11-30 12:15:49 +1100268}
269
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400270static inline opus_val16 SIG2WORD16(celt_sig x)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400271{
272#ifdef FIXED_POINT
Jean-Marc Valin42074382008-02-27 11:08:53 +1100273 x = PSHR32(x, SIG_SHIFT);
Jean-Marc Valinabdfc382008-04-18 15:57:18 +1000274 x = MAX32(x, -32768);
275 x = MIN32(x, 32767);
Jean-Marc Valin42074382008-02-27 11:08:53 +1100276 return EXTRACT16(x);
277#else
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400278 return (opus_val16)x;
Jean-Marc Valin42074382008-02-27 11:08:53 +1100279#endif
280}
281
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400282static int transient_analysis(const opus_val32 * restrict in, int len, int C,
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -0500283 int overlap)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000284{
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500285 int i;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400286 VARDECL(opus_val16, tmp);
287 opus_val32 mem0=0,mem1=0;
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500288 int is_transient = 0;
289 int block;
290 int N;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400291 VARDECL(opus_val16, bins);
Jean-Marc Valin0ceccb22008-07-03 20:41:06 -0400292 SAVE_STACK;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400293 ALLOC(tmp, len, opus_val16);
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400294
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500295 block = overlap/2;
296 N=len/block;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400297 ALLOC(bins, N, opus_val16);
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400298 if (C==1)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000299 {
300 for (i=0;i<len;i++)
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400301 tmp[i] = SHR32(in[i],SIG_SHIFT);
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400302 } else {
303 for (i=0;i<len;i++)
Jean-Marc Valin933dd832010-10-24 00:08:16 -0400304 tmp[i] = SHR32(ADD32(in[i],in[i+len]), SIG_SHIFT+1);
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000305 }
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400306
307 /* High-pass filter: (1 - 2*z^-1 + z^-2) / (1 - z^-1 + .5*z^-2) */
308 for (i=0;i<len;i++)
309 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400310 opus_val32 x,y;
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400311 x = tmp[i];
312 y = ADD32(mem0, x);
313#ifdef FIXED_POINT
314 mem0 = mem1 + y - SHL32(x,1);
315 mem1 = x - SHR32(y,1);
316#else
317 mem0 = mem1 + y - 2*x;
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400318 mem1 = x - .5f*y;
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400319#endif
320 tmp[i] = EXTRACT16(SHR(y,2));
321 }
322 /* First few samples are bad because we don't propagate the memory */
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500323 for (i=0;i<12;i++)
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400324 tmp[i] = 0;
325
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500326 for (i=0;i<N;i++)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000327 {
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500328 int j;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400329 opus_val16 max_abs=0;
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500330 for (j=0;j<block;j++)
Jean-Marc Valin168888f2011-03-02 17:26:48 -0500331 max_abs = MAX16(max_abs, ABS16(tmp[i*block+j]));
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500332 bins[i] = max_abs;
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000333 }
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500334 for (i=0;i<N;i++)
Jean-Marc Valin4a8c1f12010-10-13 18:03:50 -0400335 {
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500336 int j;
337 int conseq=0;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400338 opus_val16 t1, t2, t3;
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500339
340 t1 = MULT16_16_Q15(QCONST16(.15f, 15), bins[i]);
341 t2 = MULT16_16_Q15(QCONST16(.4f, 15), bins[i]);
342 t3 = MULT16_16_Q15(QCONST16(.15f, 15), bins[i]);
343 for (j=0;j<i;j++)
344 {
345 if (bins[j] < t1)
346 conseq++;
347 if (bins[j] < t2)
348 conseq++;
349 else
350 conseq = 0;
351 }
352 if (conseq>=3)
353 is_transient=1;
354 conseq = 0;
355 for (j=i+1;j<N;j++)
356 {
357 if (bins[j] < t3)
358 conseq++;
359 else
360 conseq = 0;
361 }
362 if (conseq>=7)
363 is_transient=1;
Jean-Marc Valin4a8c1f12010-10-13 18:03:50 -0400364 }
Jean-Marc Valin0ceccb22008-07-03 20:41:06 -0400365 RESTORE_STACK;
Jean-Marc Valinf334c822011-08-11 16:21:58 -0400366#ifdef FUZZING
367 is_transient = rand()&0x1;
368#endif
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500369 return is_transient;
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000370}
371
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400372/** Apply window and compute the MDCT for all sub-frames and
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400373 all channels in a frame */
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400374static 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 +1100375{
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400376 const int C = CHANNELS(_C);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000377 if (C==1 && !shortBlocks)
Jean-Marc Valinda721882007-11-30 15:17:42 +1100378 {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000379 const int overlap = OVERLAP(mode);
Jean-Marc Valina6b4e252011-08-15 10:20:06 -0400380 clt_mdct_forward(&mode->mdct, in, out, mode->window, overlap, mode->maxLM-LM, 1);
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400381 } else {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000382 const int overlap = OVERLAP(mode);
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400383 int N = mode->shortMdctSize<<LM;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400384 int B = 1;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000385 int b, c;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400386 if (shortBlocks)
387 {
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400388 N = mode->shortMdctSize;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400389 B = shortBlocks;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400390 }
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400391 c=0; do {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000392 for (b=0;b<B;b++)
393 {
Jean-Marc Valina6b4e252011-08-15 10:20:06 -0400394 /* Interleaving the sub-frames while doing the MDCTs */
395 clt_mdct_forward(&mode->mdct, in+c*(B*N+overlap)+b*N, &out[b+c*N*B], mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM, B);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000396 }
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400397 } while (++c<C);
Jean-Marc Valinda721882007-11-30 15:17:42 +1100398 }
Jean-Marc Valinda721882007-11-30 15:17:42 +1100399}
400
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400401/** Compute the IMDCT and apply window for all sub-frames and
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400402 all channels in a frame */
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400403static void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig *X,
Jean-Marc Valin7a08ddd2010-10-18 14:55:42 -0400404 celt_sig * restrict out_mem[],
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400405 celt_sig * restrict overlap_mem[], int _C, int LM)
Jean-Marc Valin1677aa92007-12-08 01:13:34 +1100406{
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -0400407 int c;
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400408 const int C = CHANNELS(_C);
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400409 const int N = mode->shortMdctSize<<LM;
Jean-Marc Valinb18ec0b2008-04-11 04:07:52 +1000410 const int overlap = OVERLAP(mode);
Jean-Marc Valindbeb86f2011-08-15 10:01:00 -0400411 VARDECL(opus_val32, x);
412 SAVE_STACK;
413
414 ALLOC(x, N+overlap, opus_val32);
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400415 c=0; do {
Jean-Marc Valinb886ddc2008-03-25 14:38:55 +1100416 int j;
Jean-Marc Valindbeb86f2011-08-15 10:01:00 -0400417 int b;
418 int N2 = N;
419 int B = 1;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400420
Jean-Marc Valindbeb86f2011-08-15 10:01:00 -0400421 if (shortBlocks)
422 {
423 N2 = mode->shortMdctSize;
424 B = shortBlocks;
425 }
426 /* Prevents problems from the imdct doing the overlap-add */
Jean-Marc Valinbe89c392011-08-30 12:39:51 -0400427 OPUS_CLEAR(x, overlap);
Jean-Marc Valinde678582009-10-03 10:36:27 -0400428
Jean-Marc Valindbeb86f2011-08-15 10:01:00 -0400429 for (b=0;b<B;b++)
430 {
431 /* IMDCT on the interleaved the sub-frames */
432 clt_mdct_backward(&mode->mdct, &X[b+c*N2*B], x+N2*b, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM, B);
433 }
Jean-Marc Valinde678582009-10-03 10:36:27 -0400434
Jean-Marc Valindbeb86f2011-08-15 10:01:00 -0400435 for (j=0;j<overlap;j++)
436 out_mem[c][j] = x[j] + overlap_mem[c][j];
437 for (;j<N;j++)
438 out_mem[c][j] = x[j];
439 for (j=0;j<overlap;j++)
440 overlap_mem[c][j] = x[N+j];
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400441 } while (++c<C);
Jean-Marc Valindbeb86f2011-08-15 10:01:00 -0400442 RESTORE_STACK;
Jean-Marc Valin1677aa92007-12-08 01:13:34 +1100443}
444
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400445static void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int _C, int downsample, const opus_val16 *coef, celt_sig *mem)
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400446{
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400447 const int C = CHANNELS(_C);
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400448 int c;
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500449 int count=0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400450 c=0; do {
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400451 int j;
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400452 celt_sig * restrict x;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400453 opus_val16 * restrict y;
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400454 celt_sig m = mem[c];
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400455 x =in[c];
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400456 y = pcm+c;
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400457 for (j=0;j<N;j++)
458 {
Jean-Marc Valinaf1fce92010-07-16 11:05:06 -0400459 celt_sig tmp = *x + m;
460 m = MULT16_32_Q15(coef[0], tmp)
461 - MULT16_32_Q15(coef[1], *x);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400462 tmp = SHL32(MULT16_32_Q15(coef[3], tmp), 2);
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400463 x++;
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500464 /* Technically the store could be moved outside of the if because
465 the stores we don't want will just be overwritten */
466 if (++count==downsample)
467 {
468 *y = SCALEOUT(SIG2WORD16(tmp));
469 y+=C;
470 count=0;
471 }
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400472 }
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400473 mem[c] = m;
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400474 } while (++c<C);
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400475}
476
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400477static void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
478 opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
479 const opus_val16 *window, int overlap)
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400480{
481 int i;
482 /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400483 opus_val16 g00, g01, g02, g10, g11, g12;
484 static const opus_val16 gains[3][3] = {
Jean-Marc Valin61f40412011-01-27 17:14:33 -0500485 {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
486 {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
487 {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500488 g00 = MULT16_16_Q15(g0, gains[tapset0][0]);
489 g01 = MULT16_16_Q15(g0, gains[tapset0][1]);
490 g02 = MULT16_16_Q15(g0, gains[tapset0][2]);
491 g10 = MULT16_16_Q15(g1, gains[tapset1][0]);
492 g11 = MULT16_16_Q15(g1, gains[tapset1][1]);
493 g12 = MULT16_16_Q15(g1, gains[tapset1][2]);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400494 for (i=0;i<overlap;i++)
495 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400496 opus_val16 f;
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400497 f = MULT16_16_Q15(window[i],window[i]);
498 y[i] = x[i]
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500499 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g00),x[i-T0])
500 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),x[i-T0-1])
501 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),x[i-T0+1])
502 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),x[i-T0-2])
503 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),x[i-T0+2])
504 + MULT16_32_Q15(MULT16_16_Q15(f,g10),x[i-T1])
505 + MULT16_32_Q15(MULT16_16_Q15(f,g11),x[i-T1-1])
506 + MULT16_32_Q15(MULT16_16_Q15(f,g11),x[i-T1+1])
507 + MULT16_32_Q15(MULT16_16_Q15(f,g12),x[i-T1-2])
508 + MULT16_32_Q15(MULT16_16_Q15(f,g12),x[i-T1+2]);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400509
510 }
511 for (i=overlap;i<N;i++)
512 y[i] = x[i]
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500513 + MULT16_32_Q15(g10,x[i-T1])
514 + MULT16_32_Q15(g11,x[i-T1-1])
515 + MULT16_32_Q15(g11,x[i-T1+1])
516 + MULT16_32_Q15(g12,x[i-T1-2])
517 + MULT16_32_Q15(g12,x[i-T1+2]);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400518}
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400519
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400520static const signed char tf_select_table[4][8] = {
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400521 {0, -1, 0, -1, 0,-1, 0,-1},
Jean-Marc Valin41a15e62010-12-27 16:33:38 -0500522 {0, -1, 0, -2, 1, 0, 1,-1},
523 {0, -2, 0, -3, 2, 0, 1,-1},
Jean-Marc Valin2b134012011-01-12 16:13:46 -0500524 {0, -2, 0, -3, 3, 0, 1,-1},
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400525};
526
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400527static opus_val32 l1_metric(const celt_norm *tmp, int N, int LM, int width)
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400528{
529 int i, j;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400530 static const opus_val16 sqrtM_1[4] = {Q15ONE, QCONST16(.70710678f,15), QCONST16(0.5f,15), QCONST16(0.35355339f,15)};
531 opus_val32 L1;
532 opus_val16 bias;
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400533 L1=0;
534 for (i=0;i<1<<LM;i++)
535 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400536 opus_val32 L2 = 0;
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400537 for (j=0;j<N>>LM;j++)
538 L2 = MAC16_16(L2, tmp[(j<<LM)+i], tmp[(j<<LM)+i]);
539 L1 += celt_sqrt(L2);
540 }
541 L1 = MULT16_32_Q15(sqrtM_1[LM], L1);
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400542 if (width==1)
543 bias = QCONST16(.12f,15)*LM;
544 else if (width==2)
545 bias = QCONST16(.05f,15)*LM;
546 else
547 bias = QCONST16(.02f,15)*LM;
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400548 L1 = MAC16_32_Q15(L1, bias, L1);
549 return L1;
550}
551
Gregory Maxwell06d57b22011-08-01 22:02:25 -0400552static int tf_analysis(const CELTMode *m, int len, int C, int isTransient,
553 int *tf_res, int nbCompressedBytes, celt_norm *X, int N0, int LM,
554 int *tf_sum)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400555{
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400556 int i;
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400557 VARDECL(int, metric);
558 int cost0;
559 int cost1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400560 VARDECL(int, path0);
561 VARDECL(int, path1);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400562 VARDECL(celt_norm, tmp);
563 int lambda;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400564 int tf_select=0;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400565 SAVE_STACK;
566
Jean-Marc Valin6bf3b0a2010-07-19 14:32:40 -0400567 if (nbCompressedBytes<15*C)
568 {
Jean-Marc Valina3a066c2010-11-04 15:15:54 -0400569 *tf_sum = 0;
Jean-Marc Valin6bf3b0a2010-07-19 14:32:40 -0400570 for (i=0;i<len;i++)
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400571 tf_res[i] = isTransient;
Jean-Marc Valin6bf3b0a2010-07-19 14:32:40 -0400572 return 0;
573 }
Jean-Marc Valin73319772010-05-28 21:12:39 -0400574 if (nbCompressedBytes<40)
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400575 lambda = 12;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400576 else if (nbCompressedBytes<60)
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400577 lambda = 6;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400578 else if (nbCompressedBytes<100)
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400579 lambda = 4;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400580 else
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400581 lambda = 3;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400582
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400583 ALLOC(metric, len, int);
584 ALLOC(tmp, (m->eBands[len]-m->eBands[len-1])<<LM, celt_norm);
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400585 ALLOC(path0, len, int);
586 ALLOC(path1, len, int);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400587
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400588 *tf_sum = 0;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400589 for (i=0;i<len;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400590 {
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400591 int j, k, N;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400592 opus_val32 L1, best_L1;
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400593 int best_level=0;
594 N = (m->eBands[i+1]-m->eBands[i])<<LM;
595 for (j=0;j<N;j++)
596 tmp[j] = X[j+(m->eBands[i]<<LM)];
Jean-Marc Valin20e4c6a2010-12-21 22:27:08 -0500597 /* Just add the right channel if we're in stereo */
Jean-Marc Valina3a066c2010-11-04 15:15:54 -0400598 if (C==2)
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400599 for (j=0;j<N;j++)
Jean-Marc Valina3a066c2010-11-04 15:15:54 -0400600 tmp[j] = ADD16(tmp[j],X[N0+j+(m->eBands[i]<<LM)]);
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400601 L1 = l1_metric(tmp, N, isTransient ? LM : 0, N>>LM);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400602 best_L1 = L1;
603 /*printf ("%f ", L1);*/
604 for (k=0;k<LM;k++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400605 {
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400606 int B;
607
608 if (isTransient)
609 B = (LM-k-1);
610 else
611 B = k+1;
612
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400613 if (isTransient)
614 haar1(tmp, N>>(LM-k), 1<<(LM-k));
615 else
616 haar1(tmp, N>>k, 1<<k);
617
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400618 L1 = l1_metric(tmp, N, B, N>>LM);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400619
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400620 if (L1 < best_L1)
621 {
622 best_L1 = L1;
623 best_level = k+1;
624 }
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400625 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400626 /*printf ("%d ", isTransient ? LM-best_level : best_level);*/
627 if (isTransient)
628 metric[i] = best_level;
629 else
630 metric[i] = -best_level;
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400631 *tf_sum += metric[i];
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400632 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400633 /*printf("\n");*/
Jean-Marc Valin27169ca2011-05-16 14:10:04 -0400634 /* TODO: Detect the extreme transients that require tf_select = 1 */
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400635 tf_select = 0;
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400636
Jean-Marc Valin88232612010-05-28 18:01:02 -0400637 cost0 = 0;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400638 cost1 = isTransient ? 0 : lambda;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400639 /* Viterbi forward pass */
640 for (i=1;i<len;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400641 {
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400642 int curr0, curr1;
643 int from0, from1;
Jean-Marc Valin581fdba2010-05-28 06:56:23 -0400644
Jean-Marc Valin88232612010-05-28 18:01:02 -0400645 from0 = cost0;
646 from1 = cost1 + lambda;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400647 if (from0 < from1)
648 {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400649 curr0 = from0;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400650 path0[i]= 0;
651 } else {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400652 curr0 = from1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400653 path0[i]= 1;
654 }
655
Jean-Marc Valin88232612010-05-28 18:01:02 -0400656 from0 = cost0 + lambda;
657 from1 = cost1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400658 if (from0 < from1)
659 {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400660 curr1 = from0;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400661 path1[i]= 0;
662 } else {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400663 curr1 = from1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400664 path1[i]= 1;
665 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400666 cost0 = curr0 + abs(metric[i]-tf_select_table[LM][4*isTransient+2*tf_select+0]);
667 cost1 = curr1 + abs(metric[i]-tf_select_table[LM][4*isTransient+2*tf_select+1]);
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400668 }
Jean-Marc Valin88232612010-05-28 18:01:02 -0400669 tf_res[len-1] = cost0 < cost1 ? 0 : 1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400670 /* Viterbi backward pass to check the decisions */
671 for (i=len-2;i>=0;i--)
672 {
673 if (tf_res[i+1] == 1)
674 tf_res[i] = path1[i+1];
675 else
676 tf_res[i] = path0[i+1];
677 }
Jean-Marc Valin71ae6d42010-06-27 21:55:08 -0400678 RESTORE_STACK;
Jean-Marc Valinf334c822011-08-11 16:21:58 -0400679#ifdef FUZZING
680 tf_select = rand()&0x1;
681 tf_res[0] = rand()&0x1;
682 for (i=1;i<len;i++)
683 tf_res[i] = tf_res[i-1] ^ ((rand()&0xF) == 0);
684#endif
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400685 return tf_select;
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400686}
687
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -0500688static 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 -0400689{
690 int curr, i;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800691 int tf_select_rsv;
692 int tf_changed;
693 int logp;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400694 opus_uint32 budget;
695 opus_uint32 tell;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800696 budget = enc->storage*8;
697 tell = ec_tell(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800698 logp = isTransient ? 2 : 4;
699 /* Reserve space to code the tf_select decision. */
700 tf_select_rsv = LM>0 && tell+logp+1 <= budget;
701 budget -= tf_select_rsv;
702 curr = tf_changed = 0;
703 for (i=start;i<end;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400704 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800705 if (tell+logp<=budget)
706 {
707 ec_enc_bit_logp(enc, tf_res[i] ^ curr, logp);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800708 tell = ec_tell(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800709 curr = tf_res[i];
710 tf_changed |= curr;
711 }
712 else
713 tf_res[i] = curr;
714 logp = isTransient ? 4 : 5;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400715 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800716 /* Only code tf_select if it would actually make a difference. */
717 if (tf_select_rsv &&
718 tf_select_table[LM][4*isTransient+0+tf_changed]!=
719 tf_select_table[LM][4*isTransient+2+tf_changed])
720 ec_enc_bit_logp(enc, tf_select, 1);
721 else
722 tf_select = 0;
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400723 for (i=start;i<end;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400724 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400725 /*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 -0400726}
727
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -0500728static void tf_decode(int start, int end, int isTransient, int *tf_res, int LM, ec_dec *dec)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400729{
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400730 int i, curr, tf_select;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800731 int tf_select_rsv;
732 int tf_changed;
733 int logp;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400734 opus_uint32 budget;
735 opus_uint32 tell;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800736
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800737 budget = dec->storage*8;
738 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800739 logp = isTransient ? 2 : 4;
740 tf_select_rsv = LM>0 && tell+logp+1<=budget;
741 budget -= tf_select_rsv;
742 tf_changed = curr = 0;
743 for (i=start;i<end;i++)
Timothy B. Terriberry509ad202010-12-27 18:20:20 -0800744 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800745 if (tell+logp<=budget)
746 {
747 curr ^= ec_dec_bit_logp(dec, logp);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800748 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800749 tf_changed |= curr;
750 }
751 tf_res[i] = curr;
752 logp = isTransient ? 4 : 5;
753 }
754 tf_select = 0;
755 if (tf_select_rsv &&
756 tf_select_table[LM][4*isTransient+0+tf_changed] !=
757 tf_select_table[LM][4*isTransient+2+tf_changed])
758 {
759 tf_select = ec_dec_bit_logp(dec, 1);
760 }
761 for (i=start;i<end;i++)
762 {
763 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
Timothy B. Terriberry509ad202010-12-27 18:20:20 -0800764 }
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400765}
766
Timothy B. Terriberryce6d0902011-02-01 17:41:12 -0800767static void init_caps(const CELTMode *m,int *cap,int LM,int C)
768{
769 int i;
770 for (i=0;i<m->nbEBands;i++)
771 {
772 int N;
773 N=(m->eBands[i+1]-m->eBands[i])<<LM;
774 cap[i] = (m->cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2;
775 }
776}
777
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400778static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X,
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400779 const opus_val16 *bandLogE, int end, int LM, int C, int N0)
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400780{
781 int i;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400782 opus_val32 diff=0;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500783 int c;
Jean-Marc Valin4b087df2010-11-30 21:08:31 -0500784 int trim_index = 5;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400785 if (C==2)
786 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400787 opus_val16 sum = 0; /* Q10 */
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400788 /* Compute inter-channel correlation for low frequencies */
789 for (i=0;i<8;i++)
790 {
791 int j;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400792 opus_val32 partial = 0;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400793 for (j=m->eBands[i]<<LM;j<m->eBands[i+1]<<LM;j++)
794 partial = MAC16_16(partial, X[j], X[N0+j]);
795 sum = ADD16(sum, EXTRACT16(SHR32(partial, 18)));
796 }
797 sum = MULT16_16_Q15(QCONST16(1.f/8, 15), sum);
798 /*printf ("%f\n", sum);*/
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400799 if (sum > QCONST16(.995f,10))
Jean-Marc Valin4b087df2010-11-30 21:08:31 -0500800 trim_index-=4;
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400801 else if (sum > QCONST16(.92f,10))
Jean-Marc Valin4b087df2010-11-30 21:08:31 -0500802 trim_index-=3;
803 else if (sum > QCONST16(.85f,10))
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400804 trim_index-=2;
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400805 else if (sum > QCONST16(.8f,10))
Jean-Marc Valinc40addc2010-10-22 14:57:07 -0400806 trim_index-=1;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400807 }
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500808
809 /* Estimate spectral tilt */
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400810 c=0; do {
Gregory Maxwell7007f1b2011-02-08 16:17:47 -0500811 for (i=0;i<end-1;i++)
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400812 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400813 diff += bandLogE[i+c*m->nbEBands]*(opus_int32)(2+2*i-m->nbEBands);
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400814 }
Gregory Maxwellf93d81b2011-08-07 00:57:31 -0400815 } while (++c<C);
Jean-Marc Valin817220e2011-08-08 11:33:17 -0400816 /* We divide by two here to avoid making the tilt larger for stereo as a
817 result of a bug in the loop above */
818 diff /= 2*C*(end-1);
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400819 /*printf("%f\n", diff);*/
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500820 if (diff > QCONST16(2.f, DB_SHIFT))
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400821 trim_index--;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500822 if (diff > QCONST16(8.f, DB_SHIFT))
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400823 trim_index--;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500824 if (diff < -QCONST16(4.f, DB_SHIFT))
Jean-Marc Valin90377572010-10-22 15:12:01 -0400825 trim_index++;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500826 if (diff < -QCONST16(10.f, DB_SHIFT))
827 trim_index++;
828
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400829 if (trim_index<0)
830 trim_index = 0;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500831 if (trim_index>10)
832 trim_index = 10;
Jean-Marc Valinf334c822011-08-11 16:21:58 -0400833#ifdef FUZZING
834 trim_index = rand()%11;
835#endif
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400836 return trim_index;
837}
838
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500839static int stereo_analysis(const CELTMode *m, const celt_norm *X,
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -0500840 int LM, int N0)
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500841{
842 int i;
843 int thetas;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400844 opus_val32 sumLR = EPSILON, sumMS = EPSILON;
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500845
846 /* Use the L1 norm to model the entropy of the L/R signal vs the M/S signal */
847 for (i=0;i<13;i++)
848 {
849 int j;
850 for (j=m->eBands[i]<<LM;j<m->eBands[i+1]<<LM;j++)
851 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400852 opus_val16 L, R, M, S;
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500853 L = X[j];
854 R = X[N0+j];
855 M = L+R;
856 S = L-R;
857 sumLR += EXTEND32(ABS16(L)) + EXTEND32(ABS16(R));
858 sumMS += EXTEND32(ABS16(M)) + EXTEND32(ABS16(S));
859 }
860 }
861 sumMS = MULT16_32_Q15(QCONST16(0.707107f, 15), sumMS);
862 thetas = 13;
863 /* We don't need thetas for lower bands with LM<=1 */
864 if (LM<=1)
865 thetas -= 8;
866 return MULT16_32_Q15((m->eBands[13]<<(LM+1))+thetas, sumMS)
867 > MULT16_32_Q15(m->eBands[13]<<(LM+1), sumLR);
868}
869
Jean-Marc Valin3a8f04d2011-02-02 23:02:25 -0500870CELT_STATIC
Jean-Marc Valin222494f2011-08-17 15:53:37 -0400871int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100872{
Jean-Marc Valin7a08ddd2010-10-18 14:55:42 -0400873 int i, c, N;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400874 opus_int32 bits;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800875 ec_enc _enc;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400876 VARDECL(celt_sig, in);
877 VARDECL(celt_sig, freq);
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400878 VARDECL(celt_norm, X);
879 VARDECL(celt_ener, bandE);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400880 VARDECL(opus_val16, bandLogE);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400881 VARDECL(int, fine_quant);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400882 VARDECL(opus_val16, error);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400883 VARDECL(int, pulses);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -0800884 VARDECL(int, cap);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400885 VARDECL(int, offsets);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -0400886 VARDECL(int, fine_priority);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400887 VARDECL(int, tf_res);
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -0800888 VARDECL(unsigned char, collapse_masks);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400889 celt_sig *prefilter_mem;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400890 opus_val16 *oldBandE, *oldLogE, *oldLogE2;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000891 int shortBlocks=0;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400892 int isTransient=0;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -0500893 const int CC = CHANNELS(st->channels);
894 const int C = CHANNELS(st->stream_channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400895 int LM, M;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400896 int tf_select;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400897 int nbFilledBytes, nbAvailableBytes;
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400898 int effEnd;
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400899 int codedBands;
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400900 int tf_sum;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -0400901 int alloc_trim;
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -0500902 int pitch_index=COMBFILTER_MINPERIOD;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400903 opus_val16 gain1 = 0;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -0500904 int intensity=0;
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500905 int dual_stereo=0;
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -0500906 int effectiveBytes;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400907 opus_val16 pf_threshold;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800908 int dynalloc_logp;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400909 opus_int32 vbr_rate;
910 opus_int32 total_bits;
911 opus_int32 total_boost;
912 opus_int32 balance;
913 opus_int32 tell;
Jean-Marc Valin8d367022011-01-17 16:37:51 -0500914 int prefilter_tapset=0;
915 int pf_on;
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -0800916 int anti_collapse_rsv;
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -0500917 int anti_collapse_on=0;
Jean-Marc Valinde79c372011-01-26 09:24:33 -0500918 int silence=0;
Jean-Marc Valinf62b3bb2011-03-09 11:56:29 -0500919 ALLOC_STACK;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100920
Jean-Marc Valinb3dae4b2011-02-04 21:50:54 -0500921 if (nbCompressedBytes<2 || pcm==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400922 return OPUS_BAD_ARG;
Gregory Maxwell520eeae2009-02-09 01:33:21 -0500923
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500924 frame_size *= st->upsample;
Gregory Maxwell95becbe2011-02-03 21:06:43 -0500925 for (LM=0;LM<=st->mode->maxLM;LM++)
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400926 if (st->mode->shortMdctSize<<LM==frame_size)
927 break;
Gregory Maxwell95becbe2011-02-03 21:06:43 -0500928 if (LM>st->mode->maxLM)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400929 return OPUS_BAD_ARG;
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400930 M=1<<LM;
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500931 N = M*st->mode->shortMdctSize;
Jean-Marc Valin8679a802008-10-18 07:44:35 -0400932
Jean-Marc Valin00a98f52011-01-31 11:19:03 -0500933 prefilter_mem = st->in_mem+CC*(st->overlap);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400934 oldBandE = (opus_val16*)(st->in_mem+CC*(2*st->overlap+COMBFILTER_MAXPERIOD));
Jean-Marc Valin00a98f52011-01-31 11:19:03 -0500935 oldLogE = oldBandE + CC*st->mode->nbEBands;
936 oldLogE2 = oldLogE + CC*st->mode->nbEBands;
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400937
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400938 if (enc==NULL)
939 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800940 tell=1;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400941 nbFilledBytes=0;
942 } else {
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800943 tell=ec_tell(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800944 nbFilledBytes=(tell+4)>>3;
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400945 }
Jean-Marc Valine6acfe02011-03-11 16:31:24 -0500946
947 if (st->signalling && enc==NULL)
948 {
949 int tmp = (st->mode->effEBands-st->end)>>1;
950 st->end = IMAX(1, st->mode->effEBands-tmp);
951 compressed[0] = tmp<<5;
952 compressed[0] |= LM<<3;
953 compressed[0] |= (C==2)<<2;
Jean-Marc Valind6bf19d2011-03-21 07:06:09 -0400954 /* Convert "standard mode" to Opus header */
955 if (st->mode->Fs==48000 && st->mode->shortMdctSize==120)
956 {
957 int c0 = toOpus(compressed[0]);
958 if (c0<0)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400959 return OPUS_BAD_ARG;
Jean-Marc Valind6bf19d2011-03-21 07:06:09 -0400960 compressed[0] = c0;
961 }
Jean-Marc Valine6acfe02011-03-11 16:31:24 -0500962 compressed++;
963 nbCompressedBytes--;
964 }
965
966 /* Can't produce more than 1275 output bytes */
967 nbCompressedBytes = IMIN(nbCompressedBytes,1275);
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400968 nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
969
Jean-Marc Valin66ff26f2011-08-15 22:37:11 -0400970 if (st->vbr && st->bitrate!=-1)
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500971 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400972 opus_int32 den=st->mode->Fs>>BITRES;
Jean-Marc Valin23340e22011-02-03 23:21:00 -0500973 vbr_rate=(st->bitrate*frame_size+(den>>1))/den;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -0500974 if (st->signalling)
975 vbr_rate -= 8<<BITRES;
Jean-Marc Valin3beb70e2011-03-01 18:08:15 -0500976 effectiveBytes = vbr_rate>>(3+BITRES);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500977 } else {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400978 opus_int32 tmp;
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500979 vbr_rate = 0;
980 tmp = st->bitrate*frame_size;
981 if (tell>1)
982 tmp += tell;
Jean-Marc Valin66ff26f2011-08-15 22:37:11 -0400983 if (st->bitrate!=-1)
984 nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes,
985 (tmp+4*st->mode->Fs)/(8*st->mode->Fs)-!!st->signalling));
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500986 effectiveBytes = nbCompressedBytes;
987 }
988
989 if (enc==NULL)
990 {
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800991 ec_enc_init(&_enc, compressed, nbCompressedBytes);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500992 enc = &_enc;
993 }
994
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800995 if (vbr_rate>0)
996 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800997 /* Computes the max bit-rate allowed in VBR mode to avoid violating the
998 target rate and buffering.
999 We must do this up front so that bust-prevention logic triggers
1000 correctly if we don't have enough bits. */
1001 if (st->constrained_vbr)
1002 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001003 opus_int32 vbr_bound;
1004 opus_int32 max_allowed;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001005 /* We could use any multiple of vbr_rate as bound (depending on the
1006 delay).
Gregory Maxwell420c3252011-01-27 22:35:50 -05001007 This is clamped to ensure we use at least two bytes if the encoder
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001008 was entirely empty, but to allow 0 in hybrid mode. */
1009 vbr_bound = vbr_rate;
Gregory Maxwell420c3252011-01-27 22:35:50 -05001010 max_allowed = IMIN(IMAX(tell==1?2:0,
Gregory Maxwell75d27802011-08-30 14:02:41 -04001011 (vbr_rate+vbr_bound-st->vbr_reservoir)>>(BITRES+3)),
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001012 nbAvailableBytes);
1013 if(max_allowed < nbAvailableBytes)
1014 {
1015 nbCompressedBytes = nbFilledBytes+max_allowed;
1016 nbAvailableBytes = max_allowed;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001017 ec_enc_shrink(enc, nbCompressedBytes);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001018 }
1019 }
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001020 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001021 total_bits = nbCompressedBytes*8;
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001022
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001023 effEnd = st->end;
1024 if (effEnd > st->mode->effEBands)
1025 effEnd = st->mode->effEBands;
1026
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001027 ALLOC(in, CC*(N+st->overlap), celt_sig);
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001028
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001029 /* Find pitch period and gain */
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +11001030 {
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001031 VARDECL(celt_sig, _pre);
1032 celt_sig *pre[2];
1033 SAVE_STACK;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001034 ALLOC(_pre, CC*(N+COMBFILTER_MAXPERIOD), celt_sig);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001035
1036 pre[0] = _pre;
1037 pre[1] = _pre + (N+COMBFILTER_MAXPERIOD);
1038
Jean-Marc Valinde79c372011-01-26 09:24:33 -05001039 silence = 1;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001040 c=0; do {
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001041 int count = 0;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001042 const opus_val16 * restrict pcmp = pcm+c;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001043 celt_sig * restrict inp = in+c*(N+st->overlap)+st->overlap;
1044
1045 for (i=0;i<N;i++)
1046 {
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001047 celt_sig x, tmp;
1048
1049 x = SCALEIN(*pcmp);
Jean-Marc Valin0b405d12011-02-04 01:03:42 -05001050#ifndef FIXED_POINT
Gregory Maxwell58ecb1a2011-05-09 13:16:30 -04001051 if (!(x==x))
1052 x = 0;
Jean-Marc Valin0b405d12011-02-04 01:03:42 -05001053 if (st->clip)
1054 x = MAX32(-65536.f, MIN32(65536.f,x));
1055#endif
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001056 if (++count==st->upsample)
1057 {
1058 count=0;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001059 pcmp+=CC;
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001060 } else {
1061 x = 0;
1062 }
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001063 /* Apply pre-emphasis */
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001064 tmp = MULT16_16(st->mode->preemph[2], x);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001065 *inp = tmp + st->preemph_memE[c];
1066 st->preemph_memE[c] = MULT16_32_Q15(st->mode->preemph[1], *inp)
1067 - MULT16_32_Q15(st->mode->preemph[0], tmp);
Jean-Marc Valinde79c372011-01-26 09:24:33 -05001068 silence = silence && *inp == 0;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001069 inp++;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001070 }
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001071 OPUS_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD);
1072 OPUS_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+st->overlap)+st->overlap, N);
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001073 } while (++c<CC);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001074
Jean-Marc Valinf334c822011-08-11 16:21:58 -04001075#ifdef FUZZING
1076 if ((rand()&0x3F)==0)
1077 silence = 1;
1078#endif
Jean-Marc Valin65d35a32011-01-26 22:04:59 -05001079 if (tell==1)
1080 ec_enc_bit_logp(enc, silence, 15);
1081 else
1082 silence=0;
Jean-Marc Valinde79c372011-01-26 09:24:33 -05001083 if (silence)
1084 {
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001085 /*In VBR mode there is no need to send more than the minimum. */
1086 if (vbr_rate>0)
1087 {
Jean-Marc Valin65d35a32011-01-26 22:04:59 -05001088 effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2);
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001089 total_bits=nbCompressedBytes*8;
1090 nbAvailableBytes=2;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001091 ec_enc_shrink(enc, nbCompressedBytes);
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001092 }
Jean-Marc Valin13a7c262011-01-26 10:58:33 -05001093 /* Pretend we've filled all the remaining bits with zeros
1094 (that's what the initialiser did anyway) */
Jean-Marc Valinde79c372011-01-26 09:24:33 -05001095 tell = nbCompressedBytes*8;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001096 enc->nbits_total+=tell-ec_tell(enc);
Jean-Marc Valinde79c372011-01-26 09:24:33 -05001097 }
Jean-Marc Valind539c6b2011-02-03 13:36:03 -05001098 if (nbAvailableBytes>12*C && st->start==0 && !silence && !st->disable_pf && st->complexity >= 5)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001099 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001100 VARDECL(opus_val16, pitch_buf);
1101 ALLOC(pitch_buf, (COMBFILTER_MAXPERIOD+N)>>1, opus_val16);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001102
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001103 pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC);
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05001104 pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N,
Jean-Marc Valine3e2c262011-01-26 13:09:53 -05001105 COMBFILTER_MAXPERIOD-COMBFILTER_MINPERIOD, &pitch_index);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001106 pitch_index = COMBFILTER_MAXPERIOD-pitch_index;
1107
1108 gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD,
1109 N, &pitch_index, st->prefilter_period, st->prefilter_gain);
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001110 if (pitch_index > COMBFILTER_MAXPERIOD-2)
1111 pitch_index = COMBFILTER_MAXPERIOD-2;
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -05001112 gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1);
Jean-Marc Valin69653882011-04-21 10:41:13 -04001113 if (st->loss_rate>2)
1114 gain1 = HALF32(gain1);
1115 if (st->loss_rate>4)
1116 gain1 = HALF32(gain1);
1117 if (st->loss_rate>8)
1118 gain1 = 0;
Jean-Marc Valin8d367022011-01-17 16:37:51 -05001119 prefilter_tapset = st->tapset_decision;
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -05001120 } else {
1121 gain1 = 0;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001122 }
Jean-Marc Valin6ba0b352010-12-20 11:40:30 -05001123
1124 /* Gain threshold for enabling the prefilter/postfilter */
1125 pf_threshold = QCONST16(.2f,15);
1126
1127 /* Adjusting the threshold based on rate and continuity */
1128 if (abs(pitch_index-st->prefilter_period)*10>pitch_index)
1129 pf_threshold += QCONST16(.2f,15);
1130 if (nbAvailableBytes<25)
1131 pf_threshold += QCONST16(.1f,15);
1132 if (nbAvailableBytes<35)
1133 pf_threshold += QCONST16(.1f,15);
1134 if (st->prefilter_gain > QCONST16(.4f,15))
1135 pf_threshold -= QCONST16(.1f,15);
1136 if (st->prefilter_gain > QCONST16(.55f,15))
1137 pf_threshold -= QCONST16(.1f,15);
1138
1139 /* Hard threshold at 0.2 */
1140 pf_threshold = MAX16(pf_threshold, QCONST16(.2f,15));
1141 if (gain1<pf_threshold)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001142 {
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001143 if(st->start==0 && tell+16<=total_bits)
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001144 ec_enc_bit_logp(enc, 0, 1);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001145 gain1 = 0;
Jean-Marc Valin8d367022011-01-17 16:37:51 -05001146 pf_on = 0;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001147 } else {
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001148 /*This block is not gated by a total bits check only because
1149 of the nbAvailableBytes check above.*/
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001150 int qg;
1151 int octave;
Jean-Marc Valin6ba0b352010-12-20 11:40:30 -05001152
Jean-Marc Valinb417d832011-01-27 17:19:49 -05001153 if (ABS16(gain1-st->prefilter_gain)<QCONST16(.1f,15))
Jean-Marc Valin6ba0b352010-12-20 11:40:30 -05001154 gain1=st->prefilter_gain;
1155
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001156#ifdef FIXED_POINT
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001157 qg = ((gain1+1536)>>10)/3-1;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001158#else
Gregory Maxwell662587d2011-08-01 20:41:54 -04001159 qg = (int)floor(.5f+gain1*32/3)-1;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001160#endif
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001161 qg = IMAX(0, IMIN(7, qg));
Timothy B. Terriberrye86fb262010-12-17 14:50:19 -08001162 ec_enc_bit_logp(enc, 1, 1);
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001163 pitch_index += 1;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001164 octave = EC_ILOG(pitch_index)-5;
1165 ec_enc_uint(enc, octave, 6);
1166 ec_enc_bits(enc, pitch_index-(16<<octave), 4+octave);
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001167 pitch_index -= 1;
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001168 ec_enc_bits(enc, qg, 3);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001169 if (ec_tell(enc)+2<=total_bits)
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001170 ec_enc_icdf(enc, prefilter_tapset, tapset_icdf, 2);
1171 else
1172 prefilter_tapset = 0;
1173 gain1 = QCONST16(0.09375f,15)*(qg+1);
Jean-Marc Valin8d367022011-01-17 16:37:51 -05001174 pf_on = 1;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001175 }
1176 /*printf("%d %f\n", pitch_index, gain1);*/
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001177
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001178 c=0; do {
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05001179 int offset = st->mode->shortMdctSize-st->mode->overlap;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001180 st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001181 OPUS_COPY(in+c*(N+st->overlap), st->in_mem+c*(st->overlap), st->overlap);
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05001182 if (offset)
1183 comb_filter(in+c*(N+st->overlap)+st->overlap, pre[c]+COMBFILTER_MAXPERIOD,
1184 st->prefilter_period, st->prefilter_period, offset, -st->prefilter_gain, -st->prefilter_gain,
1185 st->prefilter_tapset, st->prefilter_tapset, NULL, 0);
1186
1187 comb_filter(in+c*(N+st->overlap)+st->overlap+offset, pre[c]+COMBFILTER_MAXPERIOD+offset,
1188 st->prefilter_period, pitch_index, N-offset, -st->prefilter_gain, -gain1,
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001189 st->prefilter_tapset, prefilter_tapset, st->mode->window, st->mode->overlap);
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001190 OPUS_COPY(st->in_mem+c*(st->overlap), in+c*(N+st->overlap)+N, st->overlap);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001191
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001192 if (N>COMBFILTER_MAXPERIOD)
1193 {
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001194 OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001195 } else {
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001196 OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, prefilter_mem+c*COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD-N);
1197 OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001198 }
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001199 } while (++c<CC);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001200
1201 RESTORE_STACK;
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +11001202 }
Jean-Marc Valin2014ca32009-06-18 23:33:04 -04001203
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001204 isTransient = 0;
1205 shortBlocks = 0;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001206 if (LM>0 && ec_tell(enc)+3<=total_bits)
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001207 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001208 if (st->complexity > 1)
1209 {
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001210 isTransient = transient_analysis(in, N+st->overlap, CC,
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05001211 st->overlap);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001212 if (isTransient)
1213 shortBlocks = M;
1214 }
1215 ec_enc_bit_logp(enc, isTransient, 3);
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001216 }
Jean-Marc Valinc5f2a9d2008-10-26 22:00:26 -04001217
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001218 ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */
1219 ALLOC(bandE,st->mode->nbEBands*CC, celt_ener);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001220 ALLOC(bandLogE,st->mode->nbEBands*CC, opus_val16);
Jean-Marc Valin32ec58c2009-05-01 21:28:58 -04001221 /* Compute MDCTs */
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001222 compute_mdcts(st->mode, shortBlocks, in, freq, CC, LM);
Jean-Marc Valin08a82ff2009-06-14 14:05:19 -04001223
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001224 if (CC==2&&C==1)
1225 {
1226 for (i=0;i<N;i++)
1227 freq[i] = ADD32(HALF32(freq[i]), HALF32(freq[N+i]));
1228 }
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001229 if (st->upsample != 1)
1230 {
1231 c=0; do
1232 {
1233 int bound = N/st->upsample;
1234 for (i=0;i<bound;i++)
1235 freq[c*N+i] *= st->upsample;
1236 for (;i<N;i++)
1237 freq[c*N+i] = 0;
1238 } while (++c<C);
1239 }
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001240 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
Jean-Marc Valin8d4ac152008-02-29 17:24:02 +11001241
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001242 compute_band_energies(st->mode, freq, bandE, effEnd, C, M);
Jean-Marc Valin504fb3c2010-08-06 15:56:22 -04001243
1244 amp2Log2(st->mode, effEnd, st->end, bandE, bandLogE, C);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001245
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11001246 /* Band normalisation */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001247 normalise_bands(st->mode, freq, X, bandE, effEnd, C, M);
Jean-Marc Valin4c77ea92009-09-14 22:50:41 -04001248
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -04001249 ALLOC(tf_res, st->mode->nbEBands, int);
Gregory Maxwell06d57b22011-08-01 22:02:25 -04001250 tf_select = tf_analysis(st->mode, effEnd, C, isTransient, tf_res, effectiveBytes, X, N, LM, &tf_sum);
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -04001251 for (i=effEnd;i<st->end;i++)
1252 tf_res[i] = tf_res[effEnd-1];
1253
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001254 ALLOC(error, C*st->mode->nbEBands, opus_val16);
Jean-Marc Valin5e7f02d2010-08-08 09:48:22 -04001255 quant_coarse_energy(st->mode, st->start, st->end, effEnd, bandLogE,
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001256 oldBandE, total_bits, error, enc,
Timothy B. Terriberryef2e6502010-11-09 01:43:18 -08001257 C, LM, nbAvailableBytes, st->force_intra,
Jean-Marc Valineda2dee2011-04-21 16:04:27 -04001258 &st->delayedIntra, st->complexity >= 4, st->loss_rate);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001259
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001260 tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc);
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001261
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001262 st->spread_decision = SPREAD_NORMAL;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001263 if (ec_tell(enc)+4<=total_bits)
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -04001264 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001265 if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C)
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001266 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001267 if (st->complexity == 0)
1268 st->spread_decision = SPREAD_NONE;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001269 } else {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001270 st->spread_decision = spreading_decision(st->mode, X,
Jean-Marc Valin8d367022011-01-17 16:37:51 -05001271 &st->tonal_average, st->spread_decision, &st->hf_average,
1272 &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M);
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001273 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001274 ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5);
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -04001275 }
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001276
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001277 ALLOC(cap, st->mode->nbEBands, int);
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001278 ALLOC(offsets, st->mode->nbEBands, int);
1279
Timothy B. Terriberryce6d0902011-02-01 17:41:12 -08001280 init_caps(st->mode,cap,LM,C);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001281 for (i=0;i<st->mode->nbEBands;i++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001282 offsets[i] = 0;
1283 /* Dynamic allocation code */
1284 /* Make sure that dynamic allocation can't make us bust the budget */
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001285 if (effectiveBytes > 50 && LM>=1)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001286 {
1287 int t1, t2;
1288 if (LM <= 1)
1289 {
1290 t1 = 3;
1291 t2 = 5;
1292 } else {
1293 t1 = 2;
1294 t2 = 4;
1295 }
Gregory Maxwell7007f1b2011-02-08 16:17:47 -05001296 for (i=st->start+1;i<st->end-1;i++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001297 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001298 opus_val32 d2;
Jean-Marc Valina3a066c2010-11-04 15:15:54 -04001299 d2 = 2*bandLogE[i]-bandLogE[i-1]-bandLogE[i+1];
1300 if (C==2)
1301 d2 = HALF32(d2 + 2*bandLogE[i+st->mode->nbEBands]-
1302 bandLogE[i-1+st->mode->nbEBands]-bandLogE[i+1+st->mode->nbEBands]);
Jean-Marc Valinf334c822011-08-11 16:21:58 -04001303#ifdef FUZZING
1304 if((rand()&0xF)==0)
1305 {
1306 offsets[i] += 1;
1307 if((rand()&0x3)==0)
1308 offsets[i] += 1+(rand()&0x3);
1309 }
1310#else
Jean-Marc Valina3a066c2010-11-04 15:15:54 -04001311 if (d2 > SHL16(t1,DB_SHIFT))
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001312 offsets[i] += 1;
Jean-Marc Valina3a066c2010-11-04 15:15:54 -04001313 if (d2 > SHL16(t2,DB_SHIFT))
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001314 offsets[i] += 1;
Jean-Marc Valinf334c822011-08-11 16:21:58 -04001315#endif
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001316 }
1317 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001318 dynalloc_logp = 6;
1319 total_bits<<=BITRES;
1320 total_boost = 0;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001321 tell = ec_tell_frac(enc);
Timothy B. Terriberryd6f61572010-12-30 09:04:16 -08001322 for (i=st->start;i<st->end;i++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001323 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001324 int width, quanta;
1325 int dynalloc_loop_logp;
1326 int boost;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001327 int j;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001328 width = C*(st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
1329 /* quanta is 6 bits, but no more than 1 bit/sample
1330 and no less than 1/8 bit/sample */
1331 quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));
1332 dynalloc_loop_logp = dynalloc_logp;
1333 boost = 0;
1334 for (j = 0; tell+(dynalloc_loop_logp<<BITRES) < total_bits-total_boost
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001335 && boost < cap[i]; j++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001336 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001337 int flag;
1338 flag = j<offsets[i];
1339 ec_enc_bit_logp(enc, flag, dynalloc_loop_logp);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001340 tell = ec_tell_frac(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001341 if (!flag)
1342 break;
1343 boost += quanta;
1344 total_boost += quanta;
1345 dynalloc_loop_logp = 1;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001346 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001347 /* Making dynalloc more likely */
1348 if (j)
1349 dynalloc_logp = IMAX(2, dynalloc_logp-1);
1350 offsets[i] = boost;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001351 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001352 alloc_trim = 5;
1353 if (tell+(6<<BITRES) <= total_bits - total_boost)
1354 {
1355 alloc_trim = alloc_trim_analysis(st->mode, X, bandLogE,
Gregory Maxwell7007f1b2011-02-08 16:17:47 -05001356 st->end, LM, C, N);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001357 ec_enc_icdf(enc, alloc_trim, trim_icdf, 7);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001358 tell = ec_tell_frac(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001359 }
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001360
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001361 /* Variable bitrate */
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001362 if (vbr_rate>0)
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001363 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001364 opus_val16 alpha;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001365 opus_int32 delta;
Gregory Maxwella9411472010-10-28 03:52:21 -04001366 /* The target rate in 8th bits per frame */
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001367 opus_int32 target;
1368 opus_int32 min_allowed;
Gregory Maxwellde0b9772011-08-23 02:00:55 -04001369 int lm_diff = st->mode->maxLM - LM;
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001370
Gregory Maxwellde0b9772011-08-23 02:00:55 -04001371 target = vbr_rate + (st->vbr_offset>>lm_diff) - ((40*C+20)<<BITRES);
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001372
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001373 /* Shortblocks get a large boost in bitrate, but since they
Jean-Marc Valinccd5a612010-10-13 01:11:55 -04001374 are uncommon long blocks are not greatly affected */
1375 if (shortBlocks || tf_sum < -2*(st->end-st->start))
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001376 target = 7*target/4;
Jean-Marc Valinccd5a612010-10-13 01:11:55 -04001377 else if (tf_sum < -(st->end-st->start))
1378 target = 3*target/2;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001379 else if (M > 1)
Jean-Marc Valinccd5a612010-10-13 01:11:55 -04001380 target-=(target+14)/28;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001381
Gregory Maxwella9411472010-10-28 03:52:21 -04001382 /* The current offset is removed from the target and the space used
1383 so far is added*/
Jean-Marc Valina4badac2010-12-03 15:20:11 -05001384 target=target+tell;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001385
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001386 /* In VBR mode the frame size must not be reduced so much that it would
1387 result in the encoder running out of bits.
1388 The margin of 2 bytes ensures that none of the bust-prevention logic
1389 in the decoder will have triggered so far. */
Gregory Maxwell75d27802011-08-30 14:02:41 -04001390 min_allowed = ((tell+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3)) + 2 - nbFilledBytes;
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001391
Gregory Maxwell75d27802011-08-30 14:02:41 -04001392 nbAvailableBytes = (target+(1<<(BITRES+2)))>>(BITRES+3);
Gregory Maxwelld85018c2011-01-13 14:38:24 -05001393 nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes);
1394 nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes) - nbFilledBytes;
Jean-Marc Valin6b565262011-01-12 11:27:03 -05001395
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001396 /* By how much did we "miss" the target on that frame */
1397 delta = target - vbr_rate;
1398
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001399 target=nbAvailableBytes<<(BITRES+3);
1400
Gregory Maxwellfdd86752011-04-13 17:08:22 -04001401 /*If the frame is silent we don't adjust our drift, otherwise
1402 the encoder will shoot to very high rates after hitting a
1403 span of silence, but we do allow the bitres to refill.
1404 This means that we'll undershoot our target in CVBR/VBR modes
1405 on files with lots of silence. */
1406 if(silence)
1407 {
1408 nbAvailableBytes = 2;
1409 target = 2*8<<BITRES;
1410 delta = 0;
1411 }
1412
Gregory Maxwella9411472010-10-28 03:52:21 -04001413 if (st->vbr_count < 970)
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001414 {
1415 st->vbr_count++;
Gregory Maxwella9411472010-10-28 03:52:21 -04001416 alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+20),16));
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001417 } else
1418 alpha = QCONST16(.001f,15);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001419 /* How many bits have we used in excess of what we're allowed */
Jean-Marc Valin9faf7402010-12-04 10:27:22 -05001420 if (st->constrained_vbr)
1421 st->vbr_reservoir += target - vbr_rate;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001422 /*printf ("%d\n", st->vbr_reservoir);*/
1423
1424 /* Compute the offset we need to apply in order to reach the target */
Gregory Maxwellde0b9772011-08-23 02:00:55 -04001425 st->vbr_drift += (opus_int32)MULT16_32_Q15(alpha,(delta<<lm_diff)-st->vbr_offset-st->vbr_drift);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001426 st->vbr_offset = -st->vbr_drift;
1427 /*printf ("%d\n", st->vbr_drift);*/
1428
Jean-Marc Valin9faf7402010-12-04 10:27:22 -05001429 if (st->constrained_vbr && st->vbr_reservoir < 0)
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001430 {
1431 /* We're under the min value -- increase rate */
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001432 int adjust = (-st->vbr_reservoir)/(8<<BITRES);
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001433 /* Unless we're just coding silence */
1434 nbAvailableBytes += silence?0:adjust;
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001435 st->vbr_reservoir = 0;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001436 /*printf ("+%d\n", adjust);*/
1437 }
Gregory Maxwelld85018c2011-01-13 14:38:24 -05001438 nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001439 /* This moves the raw bits to take into account the new compressed size */
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001440 ec_enc_shrink(enc, nbCompressedBytes);
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001441 }
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001442 if (C==2)
1443 {
1444 int effectiveRate;
1445
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001446 /* Always use MS for 2.5 ms frames until we can do a better analysis */
1447 if (LM!=0)
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05001448 dual_stereo = stereo_analysis(st->mode, X, LM, N);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001449
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001450 /* Account for coarse energy */
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001451 effectiveRate = (8*effectiveBytes - 80)>>LM;
1452
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001453 /* effectiveRate in kb/s */
1454 effectiveRate = 2*effectiveRate/5;
1455 if (effectiveRate<35)
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -05001456 intensity = 8;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001457 else if (effectiveRate<50)
1458 intensity = 12;
1459 else if (effectiveRate<68)
1460 intensity = 16;
1461 else if (effectiveRate<84)
1462 intensity = 18;
1463 else if (effectiveRate<102)
1464 intensity = 19;
1465 else if (effectiveRate<130)
1466 intensity = 20;
1467 else
1468 intensity = 100;
1469 intensity = IMIN(st->end,IMAX(st->start, intensity));
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001470 }
1471
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001472 /* Bit allocation */
1473 ALLOC(fine_quant, st->mode->nbEBands, int);
1474 ALLOC(pulses, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04001475 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +11001476
Timothy B. Terriberry285bc372011-02-06 13:29:00 -08001477 /* bits = packet size - where we are - safety*/
Gregory Maxwell75d27802011-08-30 14:02:41 -04001478 bits = (((opus_int32)nbCompressedBytes*8)<<BITRES) - ec_tell_frac(enc) - 1;
1479 anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0;
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08001480 bits -= anti_collapse_rsv;
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001481 codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08001482 alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
1483 fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands);
Jean-Marc Valindfd6e712010-12-09 23:23:34 -05001484 st->lastCodedBands = codedBands;
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -05001485
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05001486 quant_fine_energy(st->mode, st->start, st->end, oldBandE, error, fine_quant, enc, C);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001487
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +02001488#ifdef MEASURE_NORM_MSE
Jean-Marc Valin44092242010-07-29 18:32:54 +02001489 float X0[3000];
1490 float bandE0[60];
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001491 c=0; do
Jean-Marc Valin44092242010-07-29 18:32:54 +02001492 for (i=0;i<N;i++)
1493 X0[i+c*N] = X[i+c*N];
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001494 while (++c<C);
Jean-Marc Valin44092242010-07-29 18:32:54 +02001495 for (i=0;i<C*st->mode->nbEBands;i++)
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +02001496 bandE0[i] = bandE[i];
1497#endif
1498
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11001499 /* Residual quantisation */
Jean-Marc Valin7e983192011-02-01 18:00:29 -05001500 ALLOC(collapse_masks, C*st->mode->nbEBands, unsigned char);
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08001501 quant_all_bands(1, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks,
Gregory Maxwelld830d082011-08-15 16:05:40 -04001502 bandE, pulses, shortBlocks, st->spread_decision, dual_stereo, intensity, tf_res,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08001503 nbCompressedBytes*(8<<BITRES)-anti_collapse_rsv, balance, enc, LM, codedBands, &st->rng);
Jean-Marc Valin39710532009-06-09 00:10:32 -04001504
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08001505 if (anti_collapse_rsv > 0)
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001506 {
1507 anti_collapse_on = st->consec_transient<2;
Jean-Marc Valinf334c822011-08-11 16:21:58 -04001508#ifdef FUZZING
1509 anti_collapse_on = rand()&0x1;
1510#endif
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001511 ec_enc_bits(enc, anti_collapse_on, 1);
1512 }
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001513 quant_energy_finalise(st->mode, st->start, st->end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C);
Jean-Marc Valin39710532009-06-09 00:10:32 -04001514
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001515 if (silence)
1516 {
1517 for (i=0;i<C*st->mode->nbEBands;i++)
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001518 oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001519 }
1520
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001521#ifdef RESYNTH
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -05001522 /* Re-synthesis of the coded audio if required */
Jean-Marc Valin18ddc022008-02-22 14:24:50 +11001523 {
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001524 celt_sig *out_mem[2];
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001525 celt_sig *overlap_mem[2];
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001526
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001527 log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
Jean-Marc Valin4b000c32011-01-26 20:30:21 -05001528 if (silence)
1529 {
1530 for (i=0;i<C*st->mode->nbEBands;i++)
1531 bandE[i] = 0;
1532 }
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04001533
1534#ifdef MEASURE_NORM_MSE
1535 measure_norm_mse(st->mode, X, X0, bandE, bandE0, M, N, C);
1536#endif
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001537 if (anti_collapse_on)
1538 {
Timothy B. Terriberry682b6cf2011-01-31 13:34:54 -08001539 anti_collapse(st->mode, X, collapse_masks, LM, C, CC, N,
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05001540 st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001541 }
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04001542
Jean-Marc Valin88619552009-10-04 21:35:36 -04001543 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001544 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valin88619552009-10-04 21:35:36 -04001545
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001546 OPUS_MOVE(st->syn_mem[0], st->syn_mem[0]+N, MAX_PERIOD);
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001547 if (CC==2)
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001548 OPUS_MOVE(st->syn_mem[1], st->syn_mem[1]+N, MAX_PERIOD);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001549
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001550 c=0; do
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -04001551 for (i=0;i<M*st->mode->eBands[st->start];i++)
1552 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001553 while (++c<C);
1554 c=0; do
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -04001555 for (i=M*st->mode->eBands[st->end];i<N;i++)
1556 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001557 while (++c<C);
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -04001558
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001559 if (CC==2&&C==1)
1560 {
1561 for (i=0;i<N;i++)
1562 freq[N+i] = freq[i];
1563 }
1564
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001565 out_mem[0] = st->syn_mem[0]+MAX_PERIOD;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001566 if (CC==2)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001567 out_mem[1] = st->syn_mem[1]+MAX_PERIOD;
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001568
Gregory Maxwella45724e2011-07-29 11:53:45 -04001569 overlap_mem[0] = prefilter_mem+CC*COMBFILTER_MAXPERIOD;
1570 if (CC==2)
1571 overlap_mem[1] = overlap_mem[0] + st->overlap;
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001572
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001573 compute_inv_mdcts(st->mode, shortBlocks, freq, out_mem, overlap_mem, CC, LM);
Jean-Marc Valine12017e2009-10-03 13:57:31 -04001574
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001575 c=0; do {
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001576 st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);
1577 st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD);
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05001578 comb_filter(out_mem[c], out_mem[c], st->prefilter_period_old, st->prefilter_period, st->mode->shortMdctSize,
Jean-Marc Valina14e86d2011-02-11 16:27:27 -05001579 st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset,
1580 st->mode->window, st->overlap);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001581 if (LM!=0)
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05001582 comb_filter(out_mem[c]+st->mode->shortMdctSize, out_mem[c]+st->mode->shortMdctSize, st->prefilter_period, pitch_index, N-st->mode->shortMdctSize,
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001583 st->prefilter_gain, gain1, st->prefilter_tapset, prefilter_tapset,
1584 st->mode->window, st->mode->overlap);
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001585 } while (++c<CC);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001586
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001587 deemphasis(out_mem, (opus_val16*)pcm, N, CC, st->upsample, st->mode->preemph, st->preemph_memD);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001588 st->prefilter_period_old = st->prefilter_period;
1589 st->prefilter_gain_old = st->prefilter_gain;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001590 st->prefilter_tapset_old = st->prefilter_tapset;
Jean-Marc Valind9b95652008-08-31 23:34:47 -04001591 }
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001592#endif
1593
1594 st->prefilter_period = pitch_index;
1595 st->prefilter_gain = gain1;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001596 st->prefilter_tapset = prefilter_tapset;
Jean-Marc Valina14e86d2011-02-11 16:27:27 -05001597#ifdef RESYNTH
1598 if (LM!=0)
1599 {
1600 st->prefilter_period_old = st->prefilter_period;
1601 st->prefilter_gain_old = st->prefilter_gain;
1602 st->prefilter_tapset_old = st->prefilter_tapset;
1603 }
1604#endif
Gregory Maxwell54547f12009-02-16 18:56:44 -05001605
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001606 if (CC==2&&C==1) {
1607 for (i=0;i<st->mode->nbEBands;i++)
1608 oldBandE[st->mode->nbEBands+i]=oldBandE[i];
1609 }
1610
Jean-Marc Valin5677e342011-01-13 16:15:53 -05001611 /* In case start or end were to change */
Jean-Marc Valin5c2ac2b2011-01-22 14:48:20 -05001612 c=0; do
1613 {
1614 for (i=0;i<st->start;i++)
1615 oldBandE[c*st->mode->nbEBands+i]=0;
1616 for (i=st->end;i<st->mode->nbEBands;i++)
1617 oldBandE[c*st->mode->nbEBands+i]=0;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001618 } while (++c<CC);
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001619 if (!isTransient)
1620 {
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001621 for (i=0;i<CC*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001622 oldLogE2[i] = oldLogE[i];
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001623 for (i=0;i<CC*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001624 oldLogE[i] = oldBandE[i];
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05001625 } else {
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001626 for (i=0;i<CC*st->mode->nbEBands;i++)
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05001627 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001628 }
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001629 if (isTransient)
1630 st->consec_transient++;
1631 else
1632 st->consec_transient=0;
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05001633 st->rng = enc->rng;
Jean-Marc Valin5677e342011-01-13 16:15:53 -05001634
Jean-Marc Valin30d51252010-06-21 17:55:28 -04001635 /* If there's any room left (can only happen for very high rates),
Jean-Marc Valin13a7c262011-01-26 10:58:33 -05001636 it's already filled with zeros */
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001637 ec_enc_done(enc);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001638
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05001639 if (st->signalling)
1640 nbCompressedBytes++;
1641
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001642 RESTORE_STACK;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001643 if (ec_get_error(enc))
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001644 return OPUS_INTERNAL_ERROR;
Jean-Marc Valin9d785af2010-07-18 09:42:05 -04001645 else
1646 return nbCompressedBytes;
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11001647}
1648
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001649
1650
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001651#ifdef FIXED_POINT
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001652int celt_encode(CELTEncoder * restrict st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1653{
1654 return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
1655}
1656
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001657#ifndef DISABLE_FLOAT_API
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001658int celt_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001659{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001660 int j, ret, C, N;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001661 VARDECL(opus_int16, in);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05001662 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001663
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001664 if (pcm==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001665 return OPUS_BAD_ARG;
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001666
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001667 C = CHANNELS(st->channels);
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001668 N = frame_size;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001669 ALLOC(in, C*N, opus_int16);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001670
1671 for (j=0;j<C*N;j++)
1672 in[j] = FLOAT2INT16(pcm[j]);
1673
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001674 ret=celt_encode_with_ec(st,in,frame_size,compressed,nbCompressedBytes, NULL);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001675#ifdef RESYNTH
1676 for (j=0;j<C*N;j++)
1677 ((float*)pcm)[j]=in[j]*(1.f/32768.f);
1678#endif
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001679 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001680 return ret;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001681}
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001682#endif /* DISABLE_FLOAT_API */
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001683#else
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001684
1685int celt_encode(CELTEncoder * restrict st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001686{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001687 int j, ret, C, N;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001688 VARDECL(celt_sig, in);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05001689 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001690
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001691 if (pcm==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001692 return OPUS_BAD_ARG;
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001693
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001694 C=CHANNELS(st->channels);
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001695 N=frame_size;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001696 ALLOC(in, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001697 for (j=0;j<C*N;j++) {
1698 in[j] = SCALEOUT(pcm[j]);
1699 }
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001700
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001701 ret = celt_encode_with_ec(st,in,frame_size,compressed,nbCompressedBytes, NULL);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001702#ifdef RESYNTH
1703 for (j=0;j<C*N;j++)
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001704 ((opus_int16*)pcm)[j] = FLOAT2INT16(in[j]);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001705#endif
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001706 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001707 return ret;
1708}
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +11001709
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001710int celt_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001711{
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001712 return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001713}
1714
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001715
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001716#endif
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001717int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...)
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001718{
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001719 va_list ap;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001720
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001721 va_start(ap, request);
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001722 switch (request)
1723 {
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001724 case OPUS_SET_COMPLEXITY_REQUEST:
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001725 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001726 int value = va_arg(ap, opus_int32);
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001727 if (value<0 || value>10)
1728 goto bad_arg;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001729 st->complexity = value;
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001730 }
1731 break;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001732 case CELT_SET_START_BAND_REQUEST:
1733 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001734 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001735 if (value<0 || value>=st->mode->nbEBands)
1736 goto bad_arg;
1737 st->start = value;
1738 }
1739 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001740 case CELT_SET_END_BAND_REQUEST:
1741 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001742 opus_int32 value = va_arg(ap, opus_int32);
Timothy B. Terriberry8893e532010-12-30 08:56:49 -08001743 if (value<1 || value>st->mode->nbEBands)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001744 goto bad_arg;
1745 st->end = value;
1746 }
1747 break;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001748 case CELT_SET_PREDICTION_REQUEST:
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001749 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001750 int value = va_arg(ap, opus_int32);
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001751 if (value<0 || value>2)
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001752 goto bad_arg;
Jean-Marc Valind539c6b2011-02-03 13:36:03 -05001753 st->disable_pf = value<=1;
1754 st->force_intra = value==0;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001755 }
1756 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001757 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
Jean-Marc Valin69653882011-04-21 10:41:13 -04001758 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001759 int value = va_arg(ap, opus_int32);
Jean-Marc Valin69653882011-04-21 10:41:13 -04001760 if (value<0 || value>100)
1761 goto bad_arg;
1762 st->loss_rate = value;
1763 }
1764 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001765 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
Jean-Marc Valin79b34eb2010-12-05 17:22:06 -05001766 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001767 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin79b34eb2010-12-05 17:22:06 -05001768 st->constrained_vbr = value;
1769 }
1770 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001771 case OPUS_SET_VBR_REQUEST:
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001772 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001773 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001774 st->vbr = value;
1775 }
1776 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001777 case OPUS_SET_BITRATE_REQUEST:
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001778 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001779 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin66ff26f2011-08-15 22:37:11 -04001780 if (value<=500 && value!=-1)
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001781 goto bad_arg;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05001782 value = IMIN(value, 260000*st->channels);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001783 st->bitrate = value;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001784 }
1785 break;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001786 case CELT_SET_CHANNELS_REQUEST:
1787 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001788 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001789 if (value<1 || value>2)
1790 goto bad_arg;
1791 st->stream_channels = value;
1792 }
1793 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001794 case OPUS_RESET_STATE:
John Ridges454d1d02009-05-21 22:38:39 -04001795 {
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001796 OPUS_CLEAR((char*)&st->ENCODER_RESET_START,
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05001797 celt_encoder_get_size_custom(st->mode, st->channels)-
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001798 ((char*)&st->ENCODER_RESET_START - (char*)st));
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001799 st->vbr_offset = 0;
John Ridges454d1d02009-05-21 22:38:39 -04001800 st->delayedIntra = 1;
Timothy B. Terriberry320cf2e2010-12-17 05:52:06 -08001801 st->spread_decision = SPREAD_NORMAL;
Gregory Maxwellec8008b2011-08-30 16:50:01 -04001802 st->tonal_average = 256;
John Ridges454d1d02009-05-21 22:38:39 -04001803 }
1804 break;
Jean-Marc Valin0b405d12011-02-04 01:03:42 -05001805 case CELT_SET_INPUT_CLIPPING_REQUEST:
1806 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001807 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin0b405d12011-02-04 01:03:42 -05001808 st->clip = value;
1809 }
1810 break;
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04001811#ifdef OPUS_BUILD
1812 case CELT_SET_SIGNALLING_REQUEST:
1813 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001814 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04001815 st->signalling = value;
1816 }
1817 break;
1818 case CELT_GET_MODE_REQUEST:
1819 {
1820 const CELTMode ** value = va_arg(ap, const CELTMode**);
1821 if (value==0)
1822 goto bad_arg;
1823 *value=st->mode;
1824 }
1825 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001826 case OPUS_GET_FINAL_RANGE_REQUEST:
Jean-Marc Valin06cee2b2011-08-19 16:11:41 -04001827 {
1828 opus_uint32 * value = va_arg(ap, opus_uint32 *);
1829 if (value==0)
1830 goto bad_arg;
1831 *value=st->rng;
1832 }
1833 break;
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04001834#endif
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001835 default:
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001836 goto bad_request;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001837 }
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001838 va_end(ap);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001839 return OPUS_OK;
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001840bad_arg:
1841 va_end(ap);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001842 return OPUS_BAD_ARG;
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001843bad_request:
1844 va_end(ap);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001845 return OPUS_UNIMPLEMENTED;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001846}
1847
Jean-Marc Valin56522ad2009-06-05 17:17:25 -04001848/**********************************************************************/
1849/* */
1850/* DECODER */
1851/* */
1852/**********************************************************************/
Jean-Marc Valineafbdd52009-04-27 19:35:09 -04001853#define DECODE_BUFFER_SIZE 2048
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001854
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001855/** Decoder state
Jean-Marc Valin276de722008-02-20 17:45:51 +11001856 @brief Decoder state
1857 */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001858struct CELTDecoder {
1859 const CELTMode *mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001860 int overlap;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001861 int channels;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05001862 int stream_channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001863
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001864 int downsample;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001865 int start, end;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05001866 int signalling;
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001867
1868 /* Everything beyond this point gets cleared on a reset */
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05001869#define DECODER_RESET_START rng
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001870
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001871 opus_uint32 rng;
Jean-Marc Valinef20e392011-03-18 15:34:11 -04001872 int error;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001873 int last_pitch_index;
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001874 int loss_count;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001875 int postfilter_period;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001876 int postfilter_period_old;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001877 opus_val16 postfilter_gain;
1878 opus_val16 postfilter_gain_old;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001879 int postfilter_tapset;
1880 int postfilter_tapset_old;
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001881
1882 celt_sig preemph_memD[2];
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001883
Jean-Marc Valinca8b9922010-08-27 16:23:03 -04001884 celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001885 /* opus_val16 lpc[], Size = channels*LPC_ORDER */
1886 /* opus_val16 oldEBands[], Size = 2*mode->nbEBands */
1887 /* opus_val16 oldLogE[], Size = 2*mode->nbEBands */
1888 /* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */
1889 /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001890};
1891
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05001892int celt_decoder_get_size(int channels)
1893{
1894 const CELTMode *mode = celt_mode_create(48000, 960, NULL);
1895 return celt_decoder_get_size_custom(mode, channels);
1896}
1897
1898int celt_decoder_get_size_custom(const CELTMode *mode, int channels)
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001899{
1900 int size = sizeof(struct CELTDecoder)
1901 + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig)
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001902 + channels*LPC_ORDER*sizeof(opus_val16)
1903 + 4*2*mode->nbEBands*sizeof(opus_val16);
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001904 return size;
1905}
1906
Jean-Marc Valinc97b2582011-01-28 23:07:32 -05001907CELTDecoder *celt_decoder_create_custom(const CELTMode *mode, int channels, int *error)
1908{
Jean-Marc Valin875f8db2011-08-31 16:43:08 -04001909 int ret;
Jean-Marc Valin07f88402011-08-29 15:08:51 -04001910 CELTDecoder *st = (CELTDecoder *)opus_alloc(celt_decoder_get_size_custom(mode, channels));
Jean-Marc Valin875f8db2011-08-31 16:43:08 -04001911 ret = celt_decoder_init_custom(st, mode, channels);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001912 if (ret != OPUS_OK)
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -05001913 {
1914 celt_decoder_destroy(st);
1915 st = NULL;
Jean-Marc Valin875f8db2011-08-31 16:43:08 -04001916 if (error)
1917 *error = ret;
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -05001918 }
1919 return st;
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -04001920}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001921
Jean-Marc Valin875f8db2011-08-31 16:43:08 -04001922int celt_decoder_init(CELTDecoder *st, int sampling_rate, int channels)
Jean-Marc Valinc97b2582011-01-28 23:07:32 -05001923{
Jean-Marc Valin875f8db2011-08-31 16:43:08 -04001924 int ret;
1925 ret = celt_decoder_init_custom(st, celt_mode_create(48000, 960, NULL), channels);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001926 if (ret != OPUS_OK)
Jean-Marc Valin875f8db2011-08-31 16:43:08 -04001927 return ret;
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001928 st->downsample = resampling_factor(sampling_rate);
1929 if (st->downsample==0)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001930 return OPUS_BAD_ARG;
Jean-Marc Valin875f8db2011-08-31 16:43:08 -04001931 else
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001932 return OPUS_OK;
Jean-Marc Valinc97b2582011-01-28 23:07:32 -05001933}
1934
Jean-Marc Valin875f8db2011-08-31 16:43:08 -04001935int celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int channels)
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -04001936{
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001937 if (channels < 0 || channels > 2)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001938 return OPUS_BAD_ARG;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001939
Gregory Maxwell17169992009-06-04 15:15:34 -04001940 if (st==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001941 return OPUS_ALLOC_FAIL;
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001942
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001943 OPUS_CLEAR((char*)st, celt_decoder_get_size_custom(mode, channels));
Jean-Marc Valin6d3829f2010-08-27 17:52:38 -04001944
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001945 st->mode = mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001946 st->overlap = mode->overlap;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05001947 st->stream_channels = st->channels = channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001948
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001949 st->downsample = 1;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001950 st->start = 0;
Jean-Marc Valin8952c452010-07-16 21:48:44 -04001951 st->end = st->mode->effEBands;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05001952 st->signalling = 1;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001953
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001954 st->loss_count = 0;
Gregory Maxwell17169992009-06-04 15:15:34 -04001955
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001956 return OPUS_OK;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001957}
1958
Peter Kirk19f9dc92008-06-06 14:38:38 +02001959void celt_decoder_destroy(CELTDecoder *st)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001960{
Jean-Marc Valin07f88402011-08-29 15:08:51 -04001961 opus_free(st);
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001962}
1963
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001964static void celt_decode_lost(CELTDecoder * restrict st, opus_val16 * restrict pcm, int N, int LM)
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001965{
Jean-Marc Valin04752672010-05-05 07:21:21 -04001966 int c;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11001967 int pitch_index;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001968 int overlap = st->mode->overlap;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001969 opus_val16 fade = Q15ONE;
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001970 int i, len;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001971 const int C = CHANNELS(st->channels);
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001972 int offset;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001973 celt_sig *out_mem[2];
1974 celt_sig *decode_mem[2];
1975 celt_sig *overlap_mem[2];
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001976 opus_val16 *lpc;
1977 opus_val32 *out_syn[2];
1978 opus_val16 *oldBandE, *oldLogE2, *backgroundLogE;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05001979 int plc=1;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001980 SAVE_STACK;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001981
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001982 c=0; do {
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001983 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
1984 out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
1985 overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001986 } while (++c<C);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001987 lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C);
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05001988 oldBandE = lpc+C*LPC_ORDER;
1989 oldLogE2 = oldBandE + C*st->mode->nbEBands;
1990 backgroundLogE = oldLogE2 + C*st->mode->nbEBands;
1991
1992 out_syn[0] = out_mem[0]+MAX_PERIOD-N;
1993 if (C==2)
1994 out_syn[1] = out_mem[1]+MAX_PERIOD-N;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04001995
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001996 len = N+st->mode->overlap;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001997
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05001998 if (st->loss_count >= 5)
1999 {
2000 VARDECL(celt_sig, freq);
2001 VARDECL(celt_norm, X);
2002 VARDECL(celt_ener, bandE);
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002003 opus_uint32 seed;
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002004 int effEnd;
2005
2006 effEnd = st->end;
2007 if (effEnd > st->mode->effEBands)
2008 effEnd = st->mode->effEBands;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002009
2010 ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
2011 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
2012 ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
2013
2014 log2Amp(st->mode, st->start, st->end, bandE, backgroundLogE, C);
2015
2016 seed = st->rng;
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002017 for (c=0;c<C;c++)
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002018 {
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002019 for (i=0;i<(st->mode->eBands[st->start]<<LM);i++)
2020 X[c*N+i] = 0;
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002021 for (i=0;i<st->mode->effEBands;i++)
2022 {
2023 int j;
2024 int boffs;
2025 int blen;
2026 boffs = N*c+(st->mode->eBands[i]<<LM);
2027 blen = (st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
2028 for (j=0;j<blen;j++)
2029 {
2030 seed = lcg_rand(seed);
Gregory Maxwellec8008b2011-08-30 16:50:01 -04002031 X[boffs+j] = (celt_norm)((opus_int32)seed>>20);
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002032 }
2033 renormalise_vector(X+boffs, blen, Q15ONE);
2034 }
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002035 for (i=(st->mode->eBands[st->end]<<LM);i<N;i++)
2036 X[c*N+i] = 0;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002037 }
2038 st->rng = seed;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002039
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002040 denormalise_bands(st->mode, X, freq, bandE, st->mode->effEBands, C, 1<<LM);
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002041
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002042 c=0; do
2043 for (i=0;i<st->mode->eBands[st->start]<<LM;i++)
2044 freq[c*N+i] = 0;
2045 while (++c<C);
2046 c=0; do {
2047 int bound = st->mode->eBands[effEnd]<<LM;
2048 if (st->downsample!=1)
2049 bound = IMIN(bound, N/st->downsample);
2050 for (i=bound;i<N;i++)
2051 freq[c*N+i] = 0;
2052 } while (++c<C);
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002053 compute_inv_mdcts(st->mode, 0, freq, out_syn, overlap_mem, C, LM);
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002054 plc = 0;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002055 } else if (st->loss_count == 0)
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04002056 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002057 opus_val16 pitch_buf[DECODE_BUFFER_SIZE>>1];
Jean-Marc Valin5f3d1af2011-05-13 17:24:25 -04002058 /* Corresponds to a min pitch of 67 Hz. It's possible to save CPU in this
2059 search by using only part of the decode buffer */
2060 int poffset = 720;
2061 pitch_downsample(decode_mem, pitch_buf, DECODE_BUFFER_SIZE, C);
2062 /* Max pitch is 100 samples (480 Hz) */
2063 pitch_search(pitch_buf+((poffset)>>1), pitch_buf, DECODE_BUFFER_SIZE-poffset,
2064 poffset-100, &pitch_index);
2065 pitch_index = poffset-pitch_index;
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04002066 st->last_pitch_index = pitch_index;
2067 } else {
2068 pitch_index = st->last_pitch_index;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002069 fade = QCONST16(.8f,15);
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04002070 }
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002071
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002072 if (plc)
2073 {
2074 c=0; do {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002075 VARDECL(opus_val32, e);
2076 opus_val16 exc[MAX_PERIOD];
2077 opus_val32 ac[LPC_ORDER+1];
2078 opus_val16 decay = 1;
2079 opus_val32 S1=0;
Gregory Maxwell06d57b22011-08-01 22:02:25 -04002080 opus_val16 mem[LPC_ORDER]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002081
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002082 ALLOC(e, MAX_PERIOD+2*st->mode->overlap, opus_val32);
Jean-Marc Valinf54a0a32011-05-13 17:36:31 -04002083
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002084 offset = MAX_PERIOD-pitch_index;
2085 for (i=0;i<MAX_PERIOD;i++)
2086 exc[i] = ROUND16(out_mem[c][i], SIG_SHIFT);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05002087
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002088 if (st->loss_count == 0)
2089 {
2090 _celt_autocorr(exc, ac, st->mode->window, st->mode->overlap,
2091 LPC_ORDER, MAX_PERIOD);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05002092
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002093 /* Noise floor -40 dB */
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002094#ifdef FIXED_POINT
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002095 ac[0] += SHR32(ac[0],13);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002096#else
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002097 ac[0] *= 1.0001f;
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002098#endif
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002099 /* Lag windowing */
2100 for (i=1;i<=LPC_ORDER;i++)
2101 {
2102 /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002103#ifdef FIXED_POINT
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002104 ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002105#else
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002106 ac[i] -= ac[i]*(.008f*i)*(.008f*i);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002107#endif
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002108 }
2109
2110 _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
2111 }
2112 for (i=0;i<LPC_ORDER;i++)
2113 mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
2114 fir(exc, lpc+c*LPC_ORDER, exc, MAX_PERIOD, LPC_ORDER, mem);
2115 /*for (i=0;i<MAX_PERIOD;i++)printf("%d ", exc[i]); printf("\n");*/
2116 /* Check if the waveform is decaying (and if so how fast) */
2117 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002118 opus_val32 E1=1, E2=1;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002119 int period;
2120 if (pitch_index <= MAX_PERIOD/2)
2121 period = pitch_index;
2122 else
2123 period = MAX_PERIOD/2;
2124 for (i=0;i<period;i++)
2125 {
2126 E1 += SHR32(MULT16_16(exc[MAX_PERIOD-period+i],exc[MAX_PERIOD-period+i]),8);
2127 E2 += SHR32(MULT16_16(exc[MAX_PERIOD-2*period+i],exc[MAX_PERIOD-2*period+i]),8);
2128 }
2129 if (E1 > E2)
2130 E1 = E2;
2131 decay = celt_sqrt(frac_div32(SHR(E1,1),E2));
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05002132 }
2133
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002134 /* Copy excitation, taking decay into account */
2135 for (i=0;i<len+st->mode->overlap;i++)
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002136 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002137 opus_val16 tmp;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002138 if (offset+i >= MAX_PERIOD)
2139 {
2140 offset -= pitch_index;
2141 decay = MULT16_16_Q15(decay, decay);
2142 }
2143 e[i] = SHL32(EXTEND32(MULT16_16_Q15(decay, exc[offset+i])), SIG_SHIFT);
2144 tmp = ROUND16(out_mem[c][offset+i],SIG_SHIFT);
2145 S1 += SHR32(MULT16_16(tmp,tmp),8);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002146 }
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002147 for (i=0;i<LPC_ORDER;i++)
2148 mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
2149 for (i=0;i<len+st->mode->overlap;i++)
2150 e[i] = MULT16_32_Q15(fade, e[i]);
2151 iir(e, lpc+c*LPC_ORDER, e, len+st->mode->overlap, LPC_ORDER, mem);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002152
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002153 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002154 opus_val32 S2=0;
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05002155 for (i=0;i<len+overlap;i++)
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002156 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002157 opus_val16 tmp = ROUND16(e[i],SIG_SHIFT);
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002158 S2 += SHR32(MULT16_16(tmp,tmp),8);
2159 }
2160 /* This checks for an "explosion" in the synthesis */
2161#ifdef FIXED_POINT
2162 if (!(S1 > SHR32(S2,2)))
2163#else
2164 /* Float test is written this way to catch NaNs at the same time */
2165 if (!(S1 > 0.2f*S2))
2166#endif
2167 {
2168 for (i=0;i<len+overlap;i++)
2169 e[i] = 0;
2170 } else if (S1 < S2)
2171 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002172 opus_val16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002173 for (i=0;i<len+overlap;i++)
2174 e[i] = MULT16_32_Q15(ratio, e[i]);
2175 }
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05002176 }
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002177
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002178 /* Apply post-filter to the MDCT overlap of the previous frame */
2179 comb_filter(out_mem[c]+MAX_PERIOD, out_mem[c]+MAX_PERIOD, st->postfilter_period, st->postfilter_period, st->overlap,
2180 st->postfilter_gain, st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset,
2181 NULL, 0);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002182
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002183 for (i=0;i<MAX_PERIOD+st->mode->overlap-N;i++)
2184 out_mem[c][i] = out_mem[c][N+i];
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002185
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002186 /* Apply TDAC to the concealed audio so that it blends with the
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002187 previous and next frames */
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002188 for (i=0;i<overlap/2;i++)
2189 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002190 opus_val32 tmp;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002191 tmp = MULT16_32_Q15(st->mode->window[i], e[N+overlap-1-i]) +
2192 MULT16_32_Q15(st->mode->window[overlap-i-1], e[N+i ]);
2193 out_mem[c][MAX_PERIOD+i] = MULT16_32_Q15(st->mode->window[overlap-i-1], tmp);
2194 out_mem[c][MAX_PERIOD+overlap-i-1] = MULT16_32_Q15(st->mode->window[i], tmp);
2195 }
2196 for (i=0;i<N;i++)
2197 out_mem[c][MAX_PERIOD-N+i] = e[i];
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002198
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002199 /* Apply pre-filter to the MDCT overlap for the next frame (post-filter will be applied then) */
2200 comb_filter(e, out_mem[c]+MAX_PERIOD, st->postfilter_period, st->postfilter_period, st->overlap,
2201 -st->postfilter_gain, -st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset,
2202 NULL, 0);
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002203 for (i=0;i<overlap;i++)
2204 out_mem[c][MAX_PERIOD+i] = e[i];
2205 } while (++c<C);
2206 }
Jean-Marc Valin1677aa92007-12-08 01:13:34 +11002207
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002208 deemphasis(out_syn, pcm, N, C, st->downsample, st->mode->preemph, st->preemph_memD);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002209
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04002210 st->loss_count++;
2211
Jean-Marc Valin8600f692008-02-29 15:14:12 +11002212 RESTORE_STACK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002213}
2214
Jean-Marc Valin51c78622011-02-03 00:43:37 -05002215CELT_STATIC
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002216int celt_decode_with_ec(CELTDecoder * restrict st, const unsigned char *data, int len, opus_val16 * restrict pcm, int frame_size, ec_dec *dec)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11002217{
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -04002218 int c, i, N;
Timothy B. Terriberry320cf2e2010-12-17 05:52:06 -08002219 int spread_decision;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002220 opus_int32 bits;
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002221 ec_dec _dec;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002222 VARDECL(celt_sig, freq);
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002223 VARDECL(celt_norm, X);
2224 VARDECL(celt_ener, bandE);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002225 VARDECL(int, fine_quant);
2226 VARDECL(int, pulses);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002227 VARDECL(int, cap);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002228 VARDECL(int, offsets);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04002229 VARDECL(int, fine_priority);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -04002230 VARDECL(int, tf_res);
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002231 VARDECL(unsigned char, collapse_masks);
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002232 celt_sig *out_mem[2];
2233 celt_sig *decode_mem[2];
2234 celt_sig *overlap_mem[2];
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04002235 celt_sig *out_syn[2];
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002236 opus_val16 *lpc;
2237 opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
Jean-Marc Valinc890b582008-08-01 22:26:49 -04002238
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +10002239 int shortBlocks;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04002240 int isTransient;
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -04002241 int intra_ener;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002242 const int CC = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04002243 int LM, M;
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002244 int effEnd;
Jean-Marc Valinb801da52010-09-28 14:56:20 -04002245 int codedBands;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04002246 int alloc_trim;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002247 int postfilter_pitch;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002248 opus_val16 postfilter_gain;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05002249 int intensity=0;
Jean-Marc Valine65978f2010-12-02 13:46:48 -05002250 int dual_stereo=0;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002251 opus_int32 total_bits;
2252 opus_int32 balance;
2253 opus_int32 tell;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002254 int dynalloc_logp;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002255 int postfilter_tapset;
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002256 int anti_collapse_rsv;
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002257 int anti_collapse_on=0;
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002258 int silence;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002259 int C = CHANNELS(st->stream_channels);
Jean-Marc Valinf62b3bb2011-03-09 11:56:29 -05002260 ALLOC_STACK;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11002261
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002262 frame_size *= st->downsample;
Jean-Marc Valin017fa852010-05-06 22:11:48 -04002263
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002264 c=0; do {
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002265 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
2266 out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
2267 overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002268 } while (++c<CC);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002269 lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*CC);
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002270 oldBandE = lpc+LPC_ORDER;
2271 oldLogE = oldBandE + 2*st->mode->nbEBands;
2272 oldLogE2 = oldLogE + 2*st->mode->nbEBands;
2273 backgroundLogE = oldLogE2 + 2*st->mode->nbEBands;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002274
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002275 if (st->signalling && data!=NULL)
2276 {
Jean-Marc Valind6bf19d2011-03-21 07:06:09 -04002277 int data0=data[0];
2278 /* Convert "standard mode" to Opus header */
2279 if (st->mode->Fs==48000 && st->mode->shortMdctSize==120)
2280 {
2281 data0 = fromOpus(data0);
2282 if (data0<0)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002283 return OPUS_CORRUPTED_DATA;
Jean-Marc Valind6bf19d2011-03-21 07:06:09 -04002284 }
2285 st->end = IMAX(1, st->mode->effEBands-2*(data0>>5));
2286 LM = (data0>>3)&0x3;
2287 C = 1 + ((data0>>2)&0x1);
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002288 data++;
2289 len--;
2290 if (LM>st->mode->maxLM)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002291 return OPUS_CORRUPTED_DATA;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002292 if (frame_size < st->mode->shortMdctSize<<LM)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002293 return OPUS_BUFFER_TOO_SMALL;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002294 else
2295 frame_size = st->mode->shortMdctSize<<LM;
2296 } else {
2297 for (LM=0;LM<=st->mode->maxLM;LM++)
2298 if (st->mode->shortMdctSize<<LM==frame_size)
2299 break;
2300 if (LM>st->mode->maxLM)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002301 return OPUS_BAD_ARG;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002302 }
2303 M=1<<LM;
2304
2305 if (len<0 || len>1275 || pcm==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002306 return OPUS_BAD_ARG;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002307
Jean-Marc Valin04752672010-05-05 07:21:21 -04002308 N = M*st->mode->shortMdctSize;
Jean-Marc Valin01417232008-03-03 13:59:55 +11002309
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002310 effEnd = st->end;
2311 if (effEnd > st->mode->effEBands)
2312 effEnd = st->mode->effEBands;
2313
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002314 ALLOC(freq, IMAX(CC,C)*N, celt_sig); /**< Interleaved signal MDCTs */
2315 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
2316 ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002317 c=0; do
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002318 for (i=0;i<M*st->mode->eBands[st->start];i++)
2319 X[c*N+i] = 0;
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002320 while (++c<C);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002321 c=0; do
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002322 for (i=M*st->mode->eBands[effEnd];i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002323 X[c*N+i] = 0;
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002324 while (++c<C);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002325
Jean-Marc Valin65d35a32011-01-26 22:04:59 -05002326 if (data == NULL || len<=1)
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002327 {
Jean-Marc Valin017fa852010-05-06 22:11:48 -04002328 celt_decode_lost(st, pcm, N, LM);
Jean-Marc Valin8600f692008-02-29 15:14:12 +11002329 RESTORE_STACK;
Jean-Marc Valin37e788c2011-03-16 20:56:28 -04002330 return frame_size/st->downsample;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002331 }
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002332
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002333 if (dec == NULL)
2334 {
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002335 ec_dec_init(&_dec,(unsigned char*)data,len);
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002336 dec = &_dec;
2337 }
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04002338
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002339 if (C<CC)
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002340 {
2341 for (i=0;i<st->mode->nbEBands;i++)
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002342 oldBandE[i]=MAX16(oldBandE[i],oldBandE[st->mode->nbEBands+i]);
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002343 }
2344
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002345 total_bits = len*8;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002346 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002347
Jean-Marc Valina0653ed2011-07-05 13:18:59 -04002348 if (tell >= total_bits)
2349 silence = 1;
2350 else if (tell==1)
Jean-Marc Valin65d35a32011-01-26 22:04:59 -05002351 silence = ec_dec_bit_logp(dec, 15);
2352 else
2353 silence = 0;
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002354 if (silence)
2355 {
Jean-Marc Valin13a7c262011-01-26 10:58:33 -05002356 /* Pretend we've read all the remaining bits */
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002357 tell = len*8;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002358 dec->nbits_total+=tell-ec_tell(dec);
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002359 }
2360
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002361 postfilter_gain = 0;
2362 postfilter_pitch = 0;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002363 postfilter_tapset = 0;
Jean-Marc Valinef986e42011-02-03 15:47:10 -05002364 if (st->start==0 && tell+16 <= total_bits)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002365 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002366 if(ec_dec_bit_logp(dec, 1))
2367 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002368 int qg, octave;
2369 octave = ec_dec_uint(dec, 6);
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002370 postfilter_pitch = (16<<octave)+ec_dec_bits(dec, 4+octave)-1;
Jean-Marc Valinef986e42011-02-03 15:47:10 -05002371 qg = ec_dec_bits(dec, 3);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002372 if (ec_tell(dec)+2<=total_bits)
Jean-Marc Valinef986e42011-02-03 15:47:10 -05002373 postfilter_tapset = ec_dec_icdf(dec, tapset_icdf, 2);
2374 postfilter_gain = QCONST16(.09375f,15)*(qg+1);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002375 }
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002376 tell = ec_tell(dec);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002377 }
2378
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002379 if (LM > 0 && tell+3 <= total_bits)
2380 {
Timothy B. Terriberrye86fb262010-12-17 14:50:19 -08002381 isTransient = ec_dec_bit_logp(dec, 3);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002382 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002383 }
Jean-Marc Valinf9fdbff2010-09-05 21:02:38 -04002384 else
2385 isTransient = 0;
Jean-Marc Valin017001a2010-08-05 15:42:50 -04002386
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04002387 if (isTransient)
2388 shortBlocks = M;
2389 else
2390 shortBlocks = 0;
2391
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002392 /* Decode the global flags (first symbols in the stream) */
2393 intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0;
2394 /* Get band energies */
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05002395 unquant_coarse_energy(st->mode, st->start, st->end, oldBandE,
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002396 intra_ener, dec, C, LM);
2397
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04002398 ALLOC(tf_res, st->mode->nbEBands, int);
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05002399 tf_decode(st->start, st->end, isTransient, tf_res, LM, dec);
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04002400
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002401 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002402 spread_decision = SPREAD_NORMAL;
2403 if (tell+4 <= total_bits)
2404 spread_decision = ec_dec_icdf(dec, spread_icdf, 5);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04002405
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002406 ALLOC(pulses, st->mode->nbEBands, int);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002407 ALLOC(cap, st->mode->nbEBands, int);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002408 ALLOC(offsets, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04002409 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002410
Timothy B. Terriberryce6d0902011-02-01 17:41:12 -08002411 init_caps(st->mode,cap,LM,C);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002412
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002413 dynalloc_logp = 6;
2414 total_bits<<=BITRES;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002415 tell = ec_tell_frac(dec);
Timothy B. Terriberryd6f61572010-12-30 09:04:16 -08002416 for (i=st->start;i<st->end;i++)
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002417 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002418 int width, quanta;
2419 int dynalloc_loop_logp;
2420 int boost;
2421 width = C*(st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
2422 /* quanta is 6 bits, but no more than 1 bit/sample
2423 and no less than 1/8 bit/sample */
2424 quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));
2425 dynalloc_loop_logp = dynalloc_logp;
2426 boost = 0;
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002427 while (tell+(dynalloc_loop_logp<<BITRES) < total_bits && boost < cap[i])
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002428 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002429 int flag;
2430 flag = ec_dec_bit_logp(dec, dynalloc_loop_logp);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002431 tell = ec_tell_frac(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002432 if (!flag)
2433 break;
2434 boost += quanta;
2435 total_bits -= quanta;
2436 dynalloc_loop_logp = 1;
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002437 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002438 offsets[i] = boost;
2439 /* Making dynalloc more likely */
2440 if (boost>0)
2441 dynalloc_logp = IMAX(2, dynalloc_logp-1);
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002442 }
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002443
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04002444 ALLOC(fine_quant, st->mode->nbEBands, int);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002445 alloc_trim = tell+(6<<BITRES) <= total_bits ?
2446 ec_dec_icdf(dec, trim_icdf, 7) : 5;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05002447
Gregory Maxwell75d27802011-08-30 14:02:41 -04002448 bits = (((opus_int32)len*8)<<BITRES) - ec_tell_frac(dec) - 1;
2449 anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0;
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002450 bits -= anti_collapse_rsv;
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002451 codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08002452 alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
2453 fine_quant, fine_priority, C, LM, dec, 0, 0);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002454
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05002455 unquant_fine_energy(st->mode, st->start, st->end, oldBandE, fine_quant, dec, C);
Jean-Marc Valin827f9312008-05-06 23:21:55 +10002456
Jean-Marc Valin8cbea172010-08-05 15:22:57 -04002457 /* Decode fixed codebook */
Jean-Marc Valin7e983192011-02-01 18:00:29 -05002458 ALLOC(collapse_masks, C*st->mode->nbEBands, unsigned char);
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002459 quant_all_bands(0, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks,
Gregory Maxwelld830d082011-08-15 16:05:40 -04002460 NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08002461 len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng);
Jean-Marc Valin746b2a82010-05-14 22:12:33 -04002462
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002463 if (anti_collapse_rsv > 0)
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002464 {
2465 anti_collapse_on = ec_dec_bits(dec, 1);
2466 }
2467
Jean-Marc Valine3e2c262011-01-26 13:09:53 -05002468 unquant_energy_finalise(st->mode, st->start, st->end, oldBandE,
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002469 fine_quant, fine_priority, len*8-ec_tell(dec), dec, C);
Jean-Marc Valin30d51252010-06-21 17:55:28 -04002470
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002471 if (anti_collapse_on)
Gregory Maxwellb288c502011-08-12 14:22:16 -04002472 anti_collapse(st->mode, X, collapse_masks, LM, C, CC, N,
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05002473 st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002474
Jean-Marc Valin02a35272010-08-27 16:00:01 -04002475 log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04002476
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002477 if (silence)
2478 {
2479 for (i=0;i<C*st->mode->nbEBands;i++)
2480 {
2481 bandE[i] = 0;
Gregory Maxwell8b631f22011-01-26 20:19:01 -05002482 oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002483 }
2484 }
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11002485 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002486 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11002487
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04002488 OPUS_MOVE(decode_mem[0], decode_mem[0]+N, DECODE_BUFFER_SIZE-N);
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002489 if (CC==2)
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04002490 OPUS_MOVE(decode_mem[1], decode_mem[1]+N, DECODE_BUFFER_SIZE-N);
Jean-Marc Valin88619552009-10-04 21:35:36 -04002491
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002492 c=0; do
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002493 for (i=0;i<M*st->mode->eBands[st->start];i++)
2494 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002495 while (++c<C);
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002496 c=0; do {
2497 int bound = M*st->mode->eBands[effEnd];
2498 if (st->downsample!=1)
2499 bound = IMIN(bound, N/st->downsample);
Jean-Marc Valin23340e22011-02-03 23:21:00 -05002500 for (i=bound;i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002501 freq[c*N+i] = 0;
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002502 } while (++c<C);
Jean-Marc Valin3a0bc3d2010-02-21 15:10:22 -05002503
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002504 out_syn[0] = out_mem[0]+MAX_PERIOD-N;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002505 if (CC==2)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002506 out_syn[1] = out_mem[1]+MAX_PERIOD-N;
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04002507
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002508 if (CC==2&&C==1)
2509 {
2510 for (i=0;i<N;i++)
2511 freq[N+i] = freq[i];
2512 }
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002513 if (CC==1&&C==2)
2514 {
2515 for (i=0;i<N;i++)
2516 freq[i] = HALF32(ADD32(freq[i],freq[N+i]));
2517 }
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002518
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11002519 /* Compute inverse MDCTs */
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002520 compute_inv_mdcts(st->mode, shortBlocks, freq, out_syn, overlap_mem, CC, LM);
Jean-Marc Valinffa13472007-12-10 16:54:17 +11002521
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002522 c=0; do {
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05002523 st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD);
2524 st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD);
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05002525 comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, st->mode->shortMdctSize,
Jean-Marc Valina14e86d2011-02-11 16:27:27 -05002526 st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset,
2527 st->mode->window, st->overlap);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05002528 if (LM!=0)
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05002529 comb_filter(out_syn[c]+st->mode->shortMdctSize, out_syn[c]+st->mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-st->mode->shortMdctSize,
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002530 st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset,
2531 st->mode->window, st->mode->overlap);
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05002532
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002533 } while (++c<CC);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05002534 st->postfilter_period_old = st->postfilter_period;
2535 st->postfilter_gain_old = st->postfilter_gain;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002536 st->postfilter_tapset_old = st->postfilter_tapset;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002537 st->postfilter_period = postfilter_pitch;
2538 st->postfilter_gain = postfilter_gain;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002539 st->postfilter_tapset = postfilter_tapset;
Jean-Marc Valina14e86d2011-02-11 16:27:27 -05002540 if (LM!=0)
2541 {
2542 st->postfilter_period_old = st->postfilter_period;
2543 st->postfilter_gain_old = st->postfilter_gain;
2544 st->postfilter_tapset_old = st->postfilter_tapset;
2545 }
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002546
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002547 if (C==1) {
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002548 for (i=0;i<st->mode->nbEBands;i++)
2549 oldBandE[st->mode->nbEBands+i]=oldBandE[i];
2550 }
2551
Jean-Marc Valin5677e342011-01-13 16:15:53 -05002552 /* In case start or end were to change */
Jean-Marc Valin5c2ac2b2011-01-22 14:48:20 -05002553 c=0; do
2554 {
2555 for (i=0;i<st->start;i++)
2556 oldBandE[c*st->mode->nbEBands+i]=0;
2557 for (i=st->end;i<st->mode->nbEBands;i++)
2558 oldBandE[c*st->mode->nbEBands+i]=0;
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002559 } while (++c<2);
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002560 if (!isTransient)
2561 {
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002562 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002563 oldLogE2[i] = oldLogE[i];
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002564 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002565 oldLogE[i] = oldBandE[i];
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002566 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002567 backgroundLogE[i] = MIN16(backgroundLogE[i] + M*QCONST16(0.001f,DB_SHIFT), oldBandE[i]);
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05002568 } else {
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002569 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05002570 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002571 }
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05002572 st->rng = dec->rng;
Jean-Marc Valin5677e342011-01-13 16:15:53 -05002573
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002574 deemphasis(out_syn, pcm, N, CC, st->downsample, st->mode->preemph, st->preemph_memD);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002575 st->loss_count = 0;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11002576 RESTORE_STACK;
Jean-Marc Valinef20e392011-03-18 15:34:11 -04002577 if (ec_tell(dec) > 8*len)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002578 return OPUS_INTERNAL_ERROR;
Jean-Marc Valinef20e392011-03-18 15:34:11 -04002579 if(ec_get_error(dec))
2580 st->error = 1;
2581 return frame_size/st->downsample;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11002582}
2583
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002584
2585
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002586#ifdef FIXED_POINT
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002587int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, opus_int16 * restrict pcm, int frame_size)
2588{
2589 return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL);
2590}
2591
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002592#ifndef DISABLE_FLOAT_API
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002593int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002594{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002595 int j, ret, C, N;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002596 VARDECL(opus_int16, out);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05002597 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04002598
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04002599 if (pcm==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002600 return OPUS_BAD_ARG;
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04002601
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04002602 C = CHANNELS(st->channels);
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002603 N = frame_size;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002604
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002605 ALLOC(out, C*N, opus_int16);
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002606 ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL);
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002607 if (ret>0)
2608 for (j=0;j<C*ret;j++)
Jean-Marc Valinae01e112010-08-03 21:43:41 -04002609 pcm[j]=out[j]*(1.f/32768.f);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002610
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04002611 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002612 return ret;
2613}
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002614#endif /* DISABLE_FLOAT_API */
2615
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002616#else
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002617
2618int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size)
2619{
2620 return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL);
2621}
2622
2623int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, opus_int16 * restrict pcm, int frame_size)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002624{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002625 int j, ret, C, N;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002626 VARDECL(celt_sig, out);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05002627 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04002628
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04002629 if (pcm==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002630 return OPUS_BAD_ARG;
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04002631
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04002632 C = CHANNELS(st->channels);
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002633 N = frame_size;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002634 ALLOC(out, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002635
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002636 ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002637
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002638 if (ret>0)
2639 for (j=0;j<C*ret;j++)
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04002640 pcm[j] = FLOAT2INT16 (out[j]);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002641
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04002642 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002643 return ret;
2644}
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002645
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002646#endif
John Ridges454d1d02009-05-21 22:38:39 -04002647
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002648
John Ridges454d1d02009-05-21 22:38:39 -04002649int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
2650{
2651 va_list ap;
Gregory Maxwell17169992009-06-04 15:15:34 -04002652
John Ridges454d1d02009-05-21 22:38:39 -04002653 va_start(ap, request);
2654 switch (request)
2655 {
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002656 case CELT_SET_START_BAND_REQUEST:
2657 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002658 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002659 if (value<0 || value>=st->mode->nbEBands)
2660 goto bad_arg;
2661 st->start = value;
2662 }
2663 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002664 case CELT_SET_END_BAND_REQUEST:
2665 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002666 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwell1928f8d2011-02-08 22:32:56 -05002667 if (value<1 || value>st->mode->nbEBands)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002668 goto bad_arg;
2669 st->end = value;
2670 }
2671 break;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002672 case CELT_SET_CHANNELS_REQUEST:
2673 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002674 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002675 if (value<1 || value>2)
2676 goto bad_arg;
2677 st->stream_channels = value;
2678 }
Jean-Marc Valindd2973d2011-03-11 17:46:02 -05002679 break;
Jean-Marc Valinef20e392011-03-18 15:34:11 -04002680 case CELT_GET_AND_CLEAR_ERROR_REQUEST:
2681 {
2682 int *value = va_arg(ap, int*);
2683 if (value==NULL)
2684 goto bad_arg;
2685 *value=st->error;
2686 st->error = 0;
2687 }
2688 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002689 case OPUS_GET_LOOKAHEAD_REQUEST:
Jean-Marc Valinff96b162011-03-21 11:32:50 -04002690 {
2691 int *value = va_arg(ap, int*);
2692 if (value==NULL)
2693 goto bad_arg;
2694 *value = st->overlap/st->downsample;
2695 }
2696 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002697 case OPUS_RESET_STATE:
John Ridges454d1d02009-05-21 22:38:39 -04002698 {
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04002699 OPUS_CLEAR((char*)&st->DECODER_RESET_START,
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05002700 celt_decoder_get_size_custom(st->mode, st->channels)-
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04002701 ((char*)&st->DECODER_RESET_START - (char*)st));
John Ridges454d1d02009-05-21 22:38:39 -04002702 }
2703 break;
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04002704#ifdef OPUS_BUILD
2705 case CELT_GET_MODE_REQUEST:
2706 {
2707 const CELTMode ** value = va_arg(ap, const CELTMode**);
2708 if (value==0)
2709 goto bad_arg;
2710 *value=st->mode;
2711 }
2712 break;
2713 case CELT_SET_SIGNALLING_REQUEST:
2714 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002715 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04002716 st->signalling = value;
2717 }
2718 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002719 case OPUS_GET_FINAL_RANGE_REQUEST:
Jean-Marc Valin06cee2b2011-08-19 16:11:41 -04002720 {
2721 opus_uint32 * value = va_arg(ap, opus_uint32 *);
2722 if (value==0)
2723 goto bad_arg;
2724 *value=st->rng;
2725 }
2726 break;
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04002727#endif
John Ridges454d1d02009-05-21 22:38:39 -04002728 default:
2729 goto bad_request;
2730 }
2731 va_end(ap);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002732 return OPUS_OK;
John Ridges454d1d02009-05-21 22:38:39 -04002733bad_arg:
2734 va_end(ap);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002735 return OPUS_BAD_ARG;
John Ridges454d1d02009-05-21 22:38:39 -04002736bad_request:
2737 va_end(ap);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002738 return OPUS_UNIMPLEMENTED;
John Ridges454d1d02009-05-21 22:38:39 -04002739}
Jean-Marc Valinece94a02009-10-16 07:30:14 -04002740
2741const char *celt_strerror(int error)
2742{
2743 static const char *error_strings[8] = {
2744 "success",
2745 "invalid argument",
Jean-Marc Valinc5f99902011-03-18 15:47:53 -04002746 "buffer too small",
Jean-Marc Valinece94a02009-10-16 07:30:14 -04002747 "internal error",
2748 "corrupted stream",
2749 "request not implemented",
2750 "invalid state",
2751 "memory allocation failed"
2752 };
2753 if (error > 0 || error < -7)
2754 return "unknown error";
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002755 else
Jean-Marc Valinece94a02009-10-16 07:30:14 -04002756 return error_strings[-error];
2757}