blob: ad4ef60130c1e801c606ac1bc2c85c7f1fe86243 [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;
118 }
119 return ret;
120}
121
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400122/** Encoder state
Jean-Marc Valin276de722008-02-20 17:45:51 +1100123 @brief Encoder state
124 */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +1100125struct CELTEncoder {
Jean-Marc Valin276de722008-02-20 17:45:51 +1100126 const CELTMode *mode; /**< Mode used by the encoder */
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100127 int overlap;
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100128 int channels;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -0500129 int stream_channels;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400130
Gregory Maxwell2dd3d322009-06-05 14:05:51 -0400131 int force_intra;
Jean-Marc Valin0b405d12011-02-04 01:03:42 -0500132 int clip;
Jean-Marc Valind539c6b2011-02-03 13:36:03 -0500133 int disable_pf;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400134 int complexity;
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500135 int upsample;
Jean-Marc Valinc09807d2010-08-27 17:17:50 -0400136 int start, end;
137
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400138 opus_int32 bitrate;
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500139 int vbr;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -0500140 int signalling;
Jean-Marc Valin9faf7402010-12-04 10:27:22 -0500141 int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */
Jean-Marc Valin69653882011-04-21 10:41:13 -0400142 int loss_rate;
Jean-Marc Valinc09807d2010-08-27 17:17:50 -0400143
144 /* Everything beyond this point gets cleared on a reset */
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -0500145#define ENCODER_RESET_START rng
Jean-Marc Valinc09807d2010-08-27 17:17:50 -0400146
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400147 opus_uint32 rng;
Timothy B. Terriberry320cf2e2010-12-17 05:52:06 -0800148 int spread_decision;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400149 opus_val32 delayedIntra;
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -0400150 int tonal_average;
Jean-Marc Valindfd6e712010-12-09 23:23:34 -0500151 int lastCodedBands;
Jean-Marc Valin8d367022011-01-17 16:37:51 -0500152 int hf_average;
153 int tapset_decision;
Jean-Marc Valin527db5c2009-06-02 07:56:19 -0400154
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400155 int prefilter_period;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400156 opus_val16 prefilter_gain;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500157 int prefilter_tapset;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -0500158#ifdef RESYNTH
159 int prefilter_period_old;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400160 opus_val16 prefilter_gain_old;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500161 int prefilter_tapset_old;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -0500162#endif
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -0500163 int consec_transient;
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400164
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400165 /* VBR-related parameters */
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400166 opus_int32 vbr_reservoir;
167 opus_int32 vbr_drift;
168 opus_int32 vbr_offset;
169 opus_int32 vbr_count;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400170
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400171 opus_val32 preemph_memE[2];
172 opus_val32 preemph_memD[2];
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100173
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400174#ifdef RESYNTH
175 celt_sig syn_mem[2][2*MAX_PERIOD];
176#endif
177
Jean-Marc Valinca8b9922010-08-27 16:23:03 -0400178 celt_sig in_mem[1]; /* Size = channels*mode->overlap */
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400179 /* celt_sig prefilter_mem[], Size = channels*COMBFILTER_PERIOD */
Jean-Marc Valinca8b9922010-08-27 16:23:03 -0400180 /* celt_sig overlap_mem[], Size = channels*mode->overlap */
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400181 /* opus_val16 oldEBands[], Size = 2*channels*mode->nbEBands */
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100182};
183
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -0500184int celt_encoder_get_size(int channels)
185{
186 CELTMode *mode = celt_mode_create(48000, 960, NULL);
187 return celt_encoder_get_size_custom(mode, channels);
188}
189
190int celt_encoder_get_size_custom(const CELTMode *mode, int channels)
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400191{
192 int size = sizeof(struct CELTEncoder)
193 + (2*channels*mode->overlap-1)*sizeof(celt_sig)
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400194 + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig)
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400195 + 3*channels*mode->nbEBands*sizeof(opus_val16);
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400196 return size;
197}
198
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500199CELTEncoder *celt_encoder_create(int sampling_rate, int channels, int *error)
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100200{
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -0500201 CELTEncoder *st;
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -0500202 st = (CELTEncoder *)celt_alloc(celt_encoder_get_size(channels));
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -0500203 if (st!=NULL && celt_encoder_init(st, sampling_rate, channels, error)==NULL)
204 {
205 celt_encoder_destroy(st);
206 st = NULL;
207 }
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500208 return st;
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -0400209}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100210
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500211CELTEncoder *celt_encoder_create_custom(const CELTMode *mode, int channels, int *error)
212{
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -0500213 CELTEncoder *st = (CELTEncoder *)celt_alloc(celt_encoder_get_size_custom(mode, channels));
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -0500214 if (st!=NULL && celt_encoder_init_custom(st, mode, channels, error)==NULL)
215 {
216 celt_encoder_destroy(st);
217 st = NULL;
218 }
219 return st;
Jean-Marc Valin02fa9132008-02-20 12:09:29 +1100220}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100221
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500222CELTEncoder *celt_encoder_init(CELTEncoder *st, int sampling_rate, int channels, int *error)
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500223{
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500224 celt_encoder_init_custom(st, celt_mode_create(48000, 960, NULL), channels, error);
225 st->upsample = resampling_factor(sampling_rate);
226 if (st->upsample==0)
227 {
228 if (error)
229 *error = CELT_BAD_ARG;
230 return NULL;
231 }
232 return st;
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500233}
234
235CELTEncoder *celt_encoder_init_custom(CELTEncoder *st, const CELTMode *mode, int channels, int *error)
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -0400236{
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400237 if (channels < 0 || channels > 2)
238 {
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400239 if (error)
240 *error = CELT_BAD_ARG;
241 return NULL;
242 }
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100243
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -0500244 if (st==NULL || mode==NULL)
Jean-Marc Valinece94a02009-10-16 07:30:14 -0400245 {
246 if (error)
247 *error = CELT_ALLOC_FAIL;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400248 return NULL;
Jean-Marc Valinece94a02009-10-16 07:30:14 -0400249 }
Jean-Marc Valin6d3829f2010-08-27 17:52:38 -0400250
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -0500251 CELT_MEMSET((char*)st, 0, celt_encoder_get_size_custom(mode, channels));
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400252
Jean-Marc Valin73e51b32007-12-05 17:48:24 +1100253 st->mode = mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100254 st->overlap = mode->overlap;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -0500255 st->stream_channels = st->channels = channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100256
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500257 st->upsample = 1;
Jean-Marc Valin5f961462010-05-19 13:38:10 -0400258 st->start = 0;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400259 st->end = st->mode->effEBands;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -0500260 st->signalling = 1;
261
Jean-Marc Valin9faf7402010-12-04 10:27:22 -0500262 st->constrained_vbr = 1;
Jean-Marc Valin0b405d12011-02-04 01:03:42 -0500263 st->clip = 1;
Jean-Marc Valin5f961462010-05-19 13:38:10 -0400264
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500265 st->bitrate = 255000*channels;
266 st->vbr = 0;
Jean-Marc Valin30165bb2010-12-03 14:35:59 -0500267 st->vbr_offset = 0;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -0400268 st->force_intra = 0;
Gregory Maxwell8842fde2009-05-04 15:58:40 -0400269 st->delayedIntra = 1;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400270 st->tonal_average = 256;
Timothy B. Terriberry320cf2e2010-12-17 05:52:06 -0800271 st->spread_decision = SPREAD_NORMAL;
Jean-Marc Valin8d367022011-01-17 16:37:51 -0500272 st->hf_average = 0;
273 st->tapset_decision = 0;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400274 st->complexity = 5;
Jean-Marc Valina76a0b22008-01-17 22:43:05 +1100275
Jean-Marc Valinece94a02009-10-16 07:30:14 -0400276 if (error)
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400277 *error = CELT_OK;
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400278 return st;
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100279}
280
Peter Kirk19f9dc92008-06-06 14:38:38 +0200281void celt_encoder_destroy(CELTEncoder *st)
Jean-Marc Valin14191b32007-11-30 12:15:49 +1100282{
Jean-Marc Valin14191b32007-11-30 12:15:49 +1100283 celt_free(st);
284}
285
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400286static inline opus_int16 FLOAT2INT16(float x)
Jean-Marc Valin42074382008-02-27 11:08:53 +1100287{
Gregory Maxwell0ac2b2f2009-05-21 23:08:46 -0400288 x = x*CELT_SIG_SCALE;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400289 x = MAX32(x, -32768);
290 x = MIN32(x, 32767);
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400291 return (opus_int16)float2int(x);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400292}
293
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400294static inline opus_val16 SIG2WORD16(celt_sig x)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400295{
296#ifdef FIXED_POINT
Jean-Marc Valin42074382008-02-27 11:08:53 +1100297 x = PSHR32(x, SIG_SHIFT);
Jean-Marc Valinabdfc382008-04-18 15:57:18 +1000298 x = MAX32(x, -32768);
299 x = MIN32(x, 32767);
Jean-Marc Valin42074382008-02-27 11:08:53 +1100300 return EXTRACT16(x);
301#else
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400302 return (opus_val16)x;
Jean-Marc Valin42074382008-02-27 11:08:53 +1100303#endif
304}
305
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400306static int transient_analysis(const opus_val32 * restrict in, int len, int C,
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -0500307 int overlap)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000308{
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500309 int i;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400310 VARDECL(opus_val16, tmp);
311 opus_val32 mem0=0,mem1=0;
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500312 int is_transient = 0;
313 int block;
314 int N;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400315 VARDECL(opus_val16, bins);
Jean-Marc Valin0ceccb22008-07-03 20:41:06 -0400316 SAVE_STACK;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400317 ALLOC(tmp, len, opus_val16);
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400318
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500319 block = overlap/2;
320 N=len/block;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400321 ALLOC(bins, N, opus_val16);
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400322 if (C==1)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000323 {
324 for (i=0;i<len;i++)
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400325 tmp[i] = SHR32(in[i],SIG_SHIFT);
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400326 } else {
327 for (i=0;i<len;i++)
Jean-Marc Valin933dd832010-10-24 00:08:16 -0400328 tmp[i] = SHR32(ADD32(in[i],in[i+len]), SIG_SHIFT+1);
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000329 }
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400330
331 /* High-pass filter: (1 - 2*z^-1 + z^-2) / (1 - z^-1 + .5*z^-2) */
332 for (i=0;i<len;i++)
333 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400334 opus_val32 x,y;
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400335 x = tmp[i];
336 y = ADD32(mem0, x);
337#ifdef FIXED_POINT
338 mem0 = mem1 + y - SHL32(x,1);
339 mem1 = x - SHR32(y,1);
340#else
341 mem0 = mem1 + y - 2*x;
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400342 mem1 = x - .5f*y;
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400343#endif
344 tmp[i] = EXTRACT16(SHR(y,2));
345 }
346 /* First few samples are bad because we don't propagate the memory */
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500347 for (i=0;i<12;i++)
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400348 tmp[i] = 0;
349
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500350 for (i=0;i<N;i++)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000351 {
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500352 int j;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400353 opus_val16 max_abs=0;
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500354 for (j=0;j<block;j++)
Jean-Marc Valin168888f2011-03-02 17:26:48 -0500355 max_abs = MAX16(max_abs, ABS16(tmp[i*block+j]));
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500356 bins[i] = max_abs;
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000357 }
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500358 for (i=0;i<N;i++)
Jean-Marc Valin4a8c1f12010-10-13 18:03:50 -0400359 {
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500360 int j;
361 int conseq=0;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400362 opus_val16 t1, t2, t3;
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500363
364 t1 = MULT16_16_Q15(QCONST16(.15f, 15), bins[i]);
365 t2 = MULT16_16_Q15(QCONST16(.4f, 15), bins[i]);
366 t3 = MULT16_16_Q15(QCONST16(.15f, 15), bins[i]);
367 for (j=0;j<i;j++)
368 {
369 if (bins[j] < t1)
370 conseq++;
371 if (bins[j] < t2)
372 conseq++;
373 else
374 conseq = 0;
375 }
376 if (conseq>=3)
377 is_transient=1;
378 conseq = 0;
379 for (j=i+1;j<N;j++)
380 {
381 if (bins[j] < t3)
382 conseq++;
383 else
384 conseq = 0;
385 }
386 if (conseq>=7)
387 is_transient=1;
Jean-Marc Valin4a8c1f12010-10-13 18:03:50 -0400388 }
Jean-Marc Valin0ceccb22008-07-03 20:41:06 -0400389 RESTORE_STACK;
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500390 return is_transient;
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000391}
392
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400393/** Apply window and compute the MDCT for all sub-frames and
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400394 all channels in a frame */
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400395static 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 +1100396{
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400397 const int C = CHANNELS(_C);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000398 if (C==1 && !shortBlocks)
Jean-Marc Valinda721882007-11-30 15:17:42 +1100399 {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000400 const int overlap = OVERLAP(mode);
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400401 clt_mdct_forward(&mode->mdct, in, out, mode->window, overlap, mode->maxLM-LM);
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400402 } else {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000403 const int overlap = OVERLAP(mode);
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400404 int N = mode->shortMdctSize<<LM;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400405 int B = 1;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000406 int b, c;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400407 VARDECL(opus_val32, tmp);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000408 SAVE_STACK;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400409 if (shortBlocks)
410 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400411 /*lookup = &mode->mdct[0];*/
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400412 N = mode->shortMdctSize;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400413 B = shortBlocks;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400414 }
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400415 ALLOC(tmp, N, opus_val32);
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400416 c=0; do {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000417 for (b=0;b<B;b++)
418 {
419 int j;
Jean-Marc Valineedb4222010-10-24 00:22:45 -0400420 clt_mdct_forward(&mode->mdct, in+c*(B*N+overlap)+b*N, tmp, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000421 /* Interleaving the sub-frames */
422 for (j=0;j<N;j++)
Jean-Marc Valin08a82ff2009-06-14 14:05:19 -0400423 out[(j*B+b)+c*N*B] = tmp[j];
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000424 }
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400425 } while (++c<C);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000426 RESTORE_STACK;
Jean-Marc Valinda721882007-11-30 15:17:42 +1100427 }
Jean-Marc Valinda721882007-11-30 15:17:42 +1100428}
429
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400430/** Compute the IMDCT and apply window for all sub-frames and
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400431 all channels in a frame */
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400432static void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig *X,
Jean-Marc Valin7a08ddd2010-10-18 14:55:42 -0400433 celt_sig * restrict out_mem[],
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400434 celt_sig * restrict overlap_mem[], int _C, int LM)
Jean-Marc Valin1677aa92007-12-08 01:13:34 +1100435{
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -0400436 int c;
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400437 const int C = CHANNELS(_C);
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400438 const int N = mode->shortMdctSize<<LM;
Jean-Marc Valinb18ec0b2008-04-11 04:07:52 +1000439 const int overlap = OVERLAP(mode);
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400440 c=0; do {
Jean-Marc Valinb886ddc2008-03-25 14:38:55 +1100441 int j;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400442 VARDECL(opus_val32, x);
443 VARDECL(opus_val32, tmp);
Jean-Marc Valinde678582009-10-03 10:36:27 -0400444 int b;
445 int N2 = N;
446 int B = 1;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000447 SAVE_STACK;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400448
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400449 ALLOC(x, N+overlap, opus_val32);
450 ALLOC(tmp, N, opus_val32);
Jean-Marc Valinde678582009-10-03 10:36:27 -0400451
452 if (shortBlocks)
453 {
Jean-Marc Valinde678582009-10-03 10:36:27 -0400454 N2 = mode->shortMdctSize;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400455 B = shortBlocks;
Jean-Marc Valinde678582009-10-03 10:36:27 -0400456 }
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000457 /* Prevents problems from the imdct doing the overlap-add */
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400458 CELT_MEMSET(x, 0, overlap);
Jean-Marc Valinde678582009-10-03 10:36:27 -0400459
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000460 for (b=0;b<B;b++)
461 {
462 /* De-interleaving the sub-frames */
463 for (j=0;j<N2;j++)
Jean-Marc Valin08a82ff2009-06-14 14:05:19 -0400464 tmp[j] = X[(j*B+b)+c*N2*B];
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400465 clt_mdct_backward(&mode->mdct, tmp, x+N2*b, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000466 }
Jean-Marc Valinde678582009-10-03 10:36:27 -0400467
Jean-Marc Valin8ddd7f42008-04-22 13:37:16 +1000468 for (j=0;j<overlap;j++)
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400469 out_mem[c][j] = x[j] + overlap_mem[c][j];
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400470 for (;j<N;j++)
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400471 out_mem[c][j] = x[j];
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400472 for (j=0;j<overlap;j++)
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400473 overlap_mem[c][j] = x[N+j];
Jean-Marc Valin8ddd7f42008-04-22 13:37:16 +1000474 RESTORE_STACK;
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400475 } while (++c<C);
Jean-Marc Valin1677aa92007-12-08 01:13:34 +1100476}
477
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400478static 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 -0400479{
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400480 const int C = CHANNELS(_C);
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400481 int c;
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500482 int count=0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400483 c=0; do {
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400484 int j;
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400485 celt_sig * restrict x;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400486 opus_val16 * restrict y;
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400487 celt_sig m = mem[c];
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400488 x =in[c];
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400489 y = pcm+c;
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400490 for (j=0;j<N;j++)
491 {
Jean-Marc Valinaf1fce92010-07-16 11:05:06 -0400492 celt_sig tmp = *x + m;
493 m = MULT16_32_Q15(coef[0], tmp)
494 - MULT16_32_Q15(coef[1], *x);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400495 tmp = SHL32(MULT16_32_Q15(coef[3], tmp), 2);
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400496 x++;
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500497 /* Technically the store could be moved outside of the if because
498 the stores we don't want will just be overwritten */
499 if (++count==downsample)
500 {
501 *y = SCALEOUT(SIG2WORD16(tmp));
502 y+=C;
503 count=0;
504 }
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400505 }
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400506 mem[c] = m;
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400507 } while (++c<C);
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400508}
509
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400510static void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
511 opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
512 const opus_val16 *window, int overlap)
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400513{
514 int i;
515 /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400516 opus_val16 g00, g01, g02, g10, g11, g12;
517 static const opus_val16 gains[3][3] = {
Jean-Marc Valin61f40412011-01-27 17:14:33 -0500518 {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
519 {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
520 {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500521 g00 = MULT16_16_Q15(g0, gains[tapset0][0]);
522 g01 = MULT16_16_Q15(g0, gains[tapset0][1]);
523 g02 = MULT16_16_Q15(g0, gains[tapset0][2]);
524 g10 = MULT16_16_Q15(g1, gains[tapset1][0]);
525 g11 = MULT16_16_Q15(g1, gains[tapset1][1]);
526 g12 = MULT16_16_Q15(g1, gains[tapset1][2]);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400527 for (i=0;i<overlap;i++)
528 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400529 opus_val16 f;
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400530 f = MULT16_16_Q15(window[i],window[i]);
531 y[i] = x[i]
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500532 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g00),x[i-T0])
533 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),x[i-T0-1])
534 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),x[i-T0+1])
535 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),x[i-T0-2])
536 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),x[i-T0+2])
537 + MULT16_32_Q15(MULT16_16_Q15(f,g10),x[i-T1])
538 + MULT16_32_Q15(MULT16_16_Q15(f,g11),x[i-T1-1])
539 + MULT16_32_Q15(MULT16_16_Q15(f,g11),x[i-T1+1])
540 + MULT16_32_Q15(MULT16_16_Q15(f,g12),x[i-T1-2])
541 + MULT16_32_Q15(MULT16_16_Q15(f,g12),x[i-T1+2]);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400542
543 }
544 for (i=overlap;i<N;i++)
545 y[i] = x[i]
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500546 + MULT16_32_Q15(g10,x[i-T1])
547 + MULT16_32_Q15(g11,x[i-T1-1])
548 + MULT16_32_Q15(g11,x[i-T1+1])
549 + MULT16_32_Q15(g12,x[i-T1-2])
550 + MULT16_32_Q15(g12,x[i-T1+2]);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400551}
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400552
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400553static const signed char tf_select_table[4][8] = {
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400554 {0, -1, 0, -1, 0,-1, 0,-1},
Jean-Marc Valin41a15e62010-12-27 16:33:38 -0500555 {0, -1, 0, -2, 1, 0, 1,-1},
556 {0, -2, 0, -3, 2, 0, 1,-1},
Jean-Marc Valin2b134012011-01-12 16:13:46 -0500557 {0, -2, 0, -3, 3, 0, 1,-1},
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400558};
559
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400560static opus_val32 l1_metric(const celt_norm *tmp, int N, int LM, int width)
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400561{
562 int i, j;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400563 static const opus_val16 sqrtM_1[4] = {Q15ONE, QCONST16(.70710678f,15), QCONST16(0.5f,15), QCONST16(0.35355339f,15)};
564 opus_val32 L1;
565 opus_val16 bias;
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400566 L1=0;
567 for (i=0;i<1<<LM;i++)
568 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400569 opus_val32 L2 = 0;
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400570 for (j=0;j<N>>LM;j++)
571 L2 = MAC16_16(L2, tmp[(j<<LM)+i], tmp[(j<<LM)+i]);
572 L1 += celt_sqrt(L2);
573 }
574 L1 = MULT16_32_Q15(sqrtM_1[LM], L1);
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400575 if (width==1)
576 bias = QCONST16(.12f,15)*LM;
577 else if (width==2)
578 bias = QCONST16(.05f,15)*LM;
579 else
580 bias = QCONST16(.02f,15)*LM;
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400581 L1 = MAC16_32_Q15(L1, bias, L1);
582 return L1;
583}
584
Gregory Maxwell06d57b22011-08-01 22:02:25 -0400585static int tf_analysis(const CELTMode *m, int len, int C, int isTransient,
586 int *tf_res, int nbCompressedBytes, celt_norm *X, int N0, int LM,
587 int *tf_sum)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400588{
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400589 int i;
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400590 VARDECL(int, metric);
591 int cost0;
592 int cost1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400593 VARDECL(int, path0);
594 VARDECL(int, path1);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400595 VARDECL(celt_norm, tmp);
596 int lambda;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400597 int tf_select=0;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400598 SAVE_STACK;
599
Jean-Marc Valin6bf3b0a2010-07-19 14:32:40 -0400600 if (nbCompressedBytes<15*C)
601 {
Jean-Marc Valina3a066c2010-11-04 15:15:54 -0400602 *tf_sum = 0;
Jean-Marc Valin6bf3b0a2010-07-19 14:32:40 -0400603 for (i=0;i<len;i++)
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400604 tf_res[i] = isTransient;
Jean-Marc Valin6bf3b0a2010-07-19 14:32:40 -0400605 return 0;
606 }
Jean-Marc Valin73319772010-05-28 21:12:39 -0400607 if (nbCompressedBytes<40)
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400608 lambda = 12;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400609 else if (nbCompressedBytes<60)
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400610 lambda = 6;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400611 else if (nbCompressedBytes<100)
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400612 lambda = 4;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400613 else
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400614 lambda = 3;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400615
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400616 ALLOC(metric, len, int);
617 ALLOC(tmp, (m->eBands[len]-m->eBands[len-1])<<LM, celt_norm);
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400618 ALLOC(path0, len, int);
619 ALLOC(path1, len, int);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400620
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400621 *tf_sum = 0;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400622 for (i=0;i<len;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400623 {
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400624 int j, k, N;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400625 opus_val32 L1, best_L1;
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400626 int best_level=0;
627 N = (m->eBands[i+1]-m->eBands[i])<<LM;
628 for (j=0;j<N;j++)
629 tmp[j] = X[j+(m->eBands[i]<<LM)];
Jean-Marc Valin20e4c6a2010-12-21 22:27:08 -0500630 /* Just add the right channel if we're in stereo */
Jean-Marc Valina3a066c2010-11-04 15:15:54 -0400631 if (C==2)
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400632 for (j=0;j<N;j++)
Jean-Marc Valina3a066c2010-11-04 15:15:54 -0400633 tmp[j] = ADD16(tmp[j],X[N0+j+(m->eBands[i]<<LM)]);
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400634 L1 = l1_metric(tmp, N, isTransient ? LM : 0, N>>LM);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400635 best_L1 = L1;
636 /*printf ("%f ", L1);*/
637 for (k=0;k<LM;k++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400638 {
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400639 int B;
640
641 if (isTransient)
642 B = (LM-k-1);
643 else
644 B = k+1;
645
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400646 if (isTransient)
647 haar1(tmp, N>>(LM-k), 1<<(LM-k));
648 else
649 haar1(tmp, N>>k, 1<<k);
650
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400651 L1 = l1_metric(tmp, N, B, N>>LM);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400652
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400653 if (L1 < best_L1)
654 {
655 best_L1 = L1;
656 best_level = k+1;
657 }
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400658 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400659 /*printf ("%d ", isTransient ? LM-best_level : best_level);*/
660 if (isTransient)
661 metric[i] = best_level;
662 else
663 metric[i] = -best_level;
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400664 *tf_sum += metric[i];
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400665 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400666 /*printf("\n");*/
Jean-Marc Valin27169ca2011-05-16 14:10:04 -0400667 /* TODO: Detect the extreme transients that require tf_select = 1 */
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400668 tf_select = 0;
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400669
Jean-Marc Valin88232612010-05-28 18:01:02 -0400670 cost0 = 0;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400671 cost1 = isTransient ? 0 : lambda;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400672 /* Viterbi forward pass */
673 for (i=1;i<len;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400674 {
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400675 int curr0, curr1;
676 int from0, from1;
Jean-Marc Valin581fdba2010-05-28 06:56:23 -0400677
Jean-Marc Valin88232612010-05-28 18:01:02 -0400678 from0 = cost0;
679 from1 = cost1 + lambda;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400680 if (from0 < from1)
681 {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400682 curr0 = from0;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400683 path0[i]= 0;
684 } else {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400685 curr0 = from1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400686 path0[i]= 1;
687 }
688
Jean-Marc Valin88232612010-05-28 18:01:02 -0400689 from0 = cost0 + lambda;
690 from1 = cost1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400691 if (from0 < from1)
692 {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400693 curr1 = from0;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400694 path1[i]= 0;
695 } else {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400696 curr1 = from1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400697 path1[i]= 1;
698 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400699 cost0 = curr0 + abs(metric[i]-tf_select_table[LM][4*isTransient+2*tf_select+0]);
700 cost1 = curr1 + abs(metric[i]-tf_select_table[LM][4*isTransient+2*tf_select+1]);
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400701 }
Jean-Marc Valin88232612010-05-28 18:01:02 -0400702 tf_res[len-1] = cost0 < cost1 ? 0 : 1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400703 /* Viterbi backward pass to check the decisions */
704 for (i=len-2;i>=0;i--)
705 {
706 if (tf_res[i+1] == 1)
707 tf_res[i] = path1[i+1];
708 else
709 tf_res[i] = path0[i+1];
710 }
Jean-Marc Valin71ae6d42010-06-27 21:55:08 -0400711 RESTORE_STACK;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400712 return tf_select;
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400713}
714
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -0500715static 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 -0400716{
717 int curr, i;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800718 int tf_select_rsv;
719 int tf_changed;
720 int logp;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400721 opus_uint32 budget;
722 opus_uint32 tell;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800723 budget = enc->storage*8;
724 tell = ec_tell(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800725 logp = isTransient ? 2 : 4;
726 /* Reserve space to code the tf_select decision. */
727 tf_select_rsv = LM>0 && tell+logp+1 <= budget;
728 budget -= tf_select_rsv;
729 curr = tf_changed = 0;
730 for (i=start;i<end;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400731 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800732 if (tell+logp<=budget)
733 {
734 ec_enc_bit_logp(enc, tf_res[i] ^ curr, logp);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800735 tell = ec_tell(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800736 curr = tf_res[i];
737 tf_changed |= curr;
738 }
739 else
740 tf_res[i] = curr;
741 logp = isTransient ? 4 : 5;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400742 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800743 /* Only code tf_select if it would actually make a difference. */
744 if (tf_select_rsv &&
745 tf_select_table[LM][4*isTransient+0+tf_changed]!=
746 tf_select_table[LM][4*isTransient+2+tf_changed])
747 ec_enc_bit_logp(enc, tf_select, 1);
748 else
749 tf_select = 0;
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400750 for (i=start;i<end;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400751 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400752 /*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 -0400753}
754
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -0500755static 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 -0400756{
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400757 int i, curr, tf_select;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800758 int tf_select_rsv;
759 int tf_changed;
760 int logp;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400761 opus_uint32 budget;
762 opus_uint32 tell;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800763
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800764 budget = dec->storage*8;
765 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800766 logp = isTransient ? 2 : 4;
767 tf_select_rsv = LM>0 && tell+logp+1<=budget;
768 budget -= tf_select_rsv;
769 tf_changed = curr = 0;
770 for (i=start;i<end;i++)
Timothy B. Terriberry509ad202010-12-27 18:20:20 -0800771 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800772 if (tell+logp<=budget)
773 {
774 curr ^= ec_dec_bit_logp(dec, logp);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800775 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800776 tf_changed |= curr;
777 }
778 tf_res[i] = curr;
779 logp = isTransient ? 4 : 5;
780 }
781 tf_select = 0;
782 if (tf_select_rsv &&
783 tf_select_table[LM][4*isTransient+0+tf_changed] !=
784 tf_select_table[LM][4*isTransient+2+tf_changed])
785 {
786 tf_select = ec_dec_bit_logp(dec, 1);
787 }
788 for (i=start;i<end;i++)
789 {
790 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
Timothy B. Terriberry509ad202010-12-27 18:20:20 -0800791 }
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400792}
793
Timothy B. Terriberryce6d0902011-02-01 17:41:12 -0800794static void init_caps(const CELTMode *m,int *cap,int LM,int C)
795{
796 int i;
797 for (i=0;i<m->nbEBands;i++)
798 {
799 int N;
800 N=(m->eBands[i+1]-m->eBands[i])<<LM;
801 cap[i] = (m->cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2;
802 }
803}
804
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400805static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X,
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400806 const opus_val16 *bandLogE, int end, int LM, int C, int N0)
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400807{
808 int i;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400809 opus_val32 diff=0;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500810 int c;
Jean-Marc Valin4b087df2010-11-30 21:08:31 -0500811 int trim_index = 5;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400812 if (C==2)
813 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400814 opus_val16 sum = 0; /* Q10 */
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400815 /* Compute inter-channel correlation for low frequencies */
816 for (i=0;i<8;i++)
817 {
818 int j;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400819 opus_val32 partial = 0;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400820 for (j=m->eBands[i]<<LM;j<m->eBands[i+1]<<LM;j++)
821 partial = MAC16_16(partial, X[j], X[N0+j]);
822 sum = ADD16(sum, EXTRACT16(SHR32(partial, 18)));
823 }
824 sum = MULT16_16_Q15(QCONST16(1.f/8, 15), sum);
825 /*printf ("%f\n", sum);*/
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400826 if (sum > QCONST16(.995f,10))
Jean-Marc Valin4b087df2010-11-30 21:08:31 -0500827 trim_index-=4;
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400828 else if (sum > QCONST16(.92f,10))
Jean-Marc Valin4b087df2010-11-30 21:08:31 -0500829 trim_index-=3;
830 else if (sum > QCONST16(.85f,10))
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400831 trim_index-=2;
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400832 else if (sum > QCONST16(.8f,10))
Jean-Marc Valinc40addc2010-10-22 14:57:07 -0400833 trim_index-=1;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400834 }
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500835
836 /* Estimate spectral tilt */
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400837 c=0; do {
Gregory Maxwell7007f1b2011-02-08 16:17:47 -0500838 for (i=0;i<end-1;i++)
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400839 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400840 diff += bandLogE[i+c*m->nbEBands]*(opus_int32)(2+2*i-m->nbEBands);
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400841 }
Gregory Maxwellf93d81b2011-08-07 00:57:31 -0400842 } while (++c<C);
Gregory Maxwell7007f1b2011-02-08 16:17:47 -0500843 diff /= C*(end-1);
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400844 /*printf("%f\n", diff);*/
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500845 if (diff > QCONST16(2.f, DB_SHIFT))
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400846 trim_index--;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500847 if (diff > QCONST16(8.f, DB_SHIFT))
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400848 trim_index--;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500849 if (diff < -QCONST16(4.f, DB_SHIFT))
Jean-Marc Valin90377572010-10-22 15:12:01 -0400850 trim_index++;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500851 if (diff < -QCONST16(10.f, DB_SHIFT))
852 trim_index++;
853
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400854 if (trim_index<0)
855 trim_index = 0;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500856 if (trim_index>10)
857 trim_index = 10;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400858 return trim_index;
859}
860
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500861static int stereo_analysis(const CELTMode *m, const celt_norm *X,
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -0500862 int LM, int N0)
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500863{
864 int i;
865 int thetas;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400866 opus_val32 sumLR = EPSILON, sumMS = EPSILON;
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500867
868 /* Use the L1 norm to model the entropy of the L/R signal vs the M/S signal */
869 for (i=0;i<13;i++)
870 {
871 int j;
872 for (j=m->eBands[i]<<LM;j<m->eBands[i+1]<<LM;j++)
873 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400874 opus_val16 L, R, M, S;
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500875 L = X[j];
876 R = X[N0+j];
877 M = L+R;
878 S = L-R;
879 sumLR += EXTEND32(ABS16(L)) + EXTEND32(ABS16(R));
880 sumMS += EXTEND32(ABS16(M)) + EXTEND32(ABS16(S));
881 }
882 }
883 sumMS = MULT16_32_Q15(QCONST16(0.707107f, 15), sumMS);
884 thetas = 13;
885 /* We don't need thetas for lower bands with LM<=1 */
886 if (LM<=1)
887 thetas -= 8;
888 return MULT16_32_Q15((m->eBands[13]<<(LM+1))+thetas, sumMS)
889 > MULT16_32_Q15(m->eBands[13]<<(LM+1), sumLR);
890}
891
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400892#ifdef FIXED_POINT
Jean-Marc Valin3a8f04d2011-02-02 23:02:25 -0500893CELT_STATIC
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400894int celt_encode_with_ec(CELTEncoder * restrict st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100895{
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400896#else
Jean-Marc Valin3a8f04d2011-02-02 23:02:25 -0500897CELT_STATIC
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400898int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400899{
900#endif
Jean-Marc Valin7a08ddd2010-10-18 14:55:42 -0400901 int i, c, N;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400902 opus_int32 bits;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800903 ec_enc _enc;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400904 VARDECL(celt_sig, in);
905 VARDECL(celt_sig, freq);
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400906 VARDECL(celt_norm, X);
907 VARDECL(celt_ener, bandE);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400908 VARDECL(opus_val16, bandLogE);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400909 VARDECL(int, fine_quant);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400910 VARDECL(opus_val16, error);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400911 VARDECL(int, pulses);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -0800912 VARDECL(int, cap);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400913 VARDECL(int, offsets);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -0400914 VARDECL(int, fine_priority);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400915 VARDECL(int, tf_res);
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -0800916 VARDECL(unsigned char, collapse_masks);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400917 celt_sig *prefilter_mem;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400918 opus_val16 *oldBandE, *oldLogE, *oldLogE2;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000919 int shortBlocks=0;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400920 int isTransient=0;
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -0400921 int resynth;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -0500922 const int CC = CHANNELS(st->channels);
923 const int C = CHANNELS(st->stream_channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400924 int LM, M;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400925 int tf_select;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400926 int nbFilledBytes, nbAvailableBytes;
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400927 int effEnd;
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400928 int codedBands;
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400929 int tf_sum;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -0400930 int alloc_trim;
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -0500931 int pitch_index=COMBFILTER_MINPERIOD;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400932 opus_val16 gain1 = 0;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -0500933 int intensity=0;
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500934 int dual_stereo=0;
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -0500935 int effectiveBytes;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400936 opus_val16 pf_threshold;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800937 int dynalloc_logp;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400938 opus_int32 vbr_rate;
939 opus_int32 total_bits;
940 opus_int32 total_boost;
941 opus_int32 balance;
942 opus_int32 tell;
Jean-Marc Valin8d367022011-01-17 16:37:51 -0500943 int prefilter_tapset=0;
944 int pf_on;
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -0800945 int anti_collapse_rsv;
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -0500946 int anti_collapse_on=0;
Jean-Marc Valinde79c372011-01-26 09:24:33 -0500947 int silence=0;
Jean-Marc Valinf62b3bb2011-03-09 11:56:29 -0500948 ALLOC_STACK;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100949
Jean-Marc Valinb3dae4b2011-02-04 21:50:54 -0500950 if (nbCompressedBytes<2 || pcm==NULL)
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400951 return CELT_BAD_ARG;
Gregory Maxwell520eeae2009-02-09 01:33:21 -0500952
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500953 frame_size *= st->upsample;
Gregory Maxwell95becbe2011-02-03 21:06:43 -0500954 for (LM=0;LM<=st->mode->maxLM;LM++)
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400955 if (st->mode->shortMdctSize<<LM==frame_size)
956 break;
Gregory Maxwell95becbe2011-02-03 21:06:43 -0500957 if (LM>st->mode->maxLM)
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400958 return CELT_BAD_ARG;
959 M=1<<LM;
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500960 N = M*st->mode->shortMdctSize;
Jean-Marc Valin8679a802008-10-18 07:44:35 -0400961
Jean-Marc Valin00a98f52011-01-31 11:19:03 -0500962 prefilter_mem = st->in_mem+CC*(st->overlap);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400963 oldBandE = (opus_val16*)(st->in_mem+CC*(2*st->overlap+COMBFILTER_MAXPERIOD));
Jean-Marc Valin00a98f52011-01-31 11:19:03 -0500964 oldLogE = oldBandE + CC*st->mode->nbEBands;
965 oldLogE2 = oldLogE + CC*st->mode->nbEBands;
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400966
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400967 if (enc==NULL)
968 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800969 tell=1;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400970 nbFilledBytes=0;
971 } else {
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800972 tell=ec_tell(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800973 nbFilledBytes=(tell+4)>>3;
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400974 }
Jean-Marc Valine6acfe02011-03-11 16:31:24 -0500975
976 if (st->signalling && enc==NULL)
977 {
978 int tmp = (st->mode->effEBands-st->end)>>1;
979 st->end = IMAX(1, st->mode->effEBands-tmp);
980 compressed[0] = tmp<<5;
981 compressed[0] |= LM<<3;
982 compressed[0] |= (C==2)<<2;
Jean-Marc Valind6bf19d2011-03-21 07:06:09 -0400983 /* Convert "standard mode" to Opus header */
984 if (st->mode->Fs==48000 && st->mode->shortMdctSize==120)
985 {
986 int c0 = toOpus(compressed[0]);
987 if (c0<0)
988 return CELT_BAD_ARG;
989 compressed[0] = c0;
990 }
Jean-Marc Valine6acfe02011-03-11 16:31:24 -0500991 compressed++;
992 nbCompressedBytes--;
993 }
994
995 /* Can't produce more than 1275 output bytes */
996 nbCompressedBytes = IMIN(nbCompressedBytes,1275);
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400997 nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
998
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500999 if (st->vbr)
1000 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001001 opus_int32 den=st->mode->Fs>>BITRES;
Jean-Marc Valin23340e22011-02-03 23:21:00 -05001002 vbr_rate=(st->bitrate*frame_size+(den>>1))/den;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05001003 if (st->signalling)
1004 vbr_rate -= 8<<BITRES;
Jean-Marc Valin3beb70e2011-03-01 18:08:15 -05001005 effectiveBytes = vbr_rate>>(3+BITRES);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001006 } else {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001007 opus_int32 tmp;
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001008 vbr_rate = 0;
1009 tmp = st->bitrate*frame_size;
1010 if (tell>1)
1011 tmp += tell;
1012 nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes,
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05001013 (tmp+4*st->mode->Fs)/(8*st->mode->Fs)-!!st->signalling));
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001014 effectiveBytes = nbCompressedBytes;
1015 }
1016
1017 if (enc==NULL)
1018 {
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001019 ec_enc_init(&_enc, compressed, nbCompressedBytes);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001020 enc = &_enc;
1021 }
1022
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001023 if (vbr_rate>0)
1024 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001025 /* Computes the max bit-rate allowed in VBR mode to avoid violating the
1026 target rate and buffering.
1027 We must do this up front so that bust-prevention logic triggers
1028 correctly if we don't have enough bits. */
1029 if (st->constrained_vbr)
1030 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001031 opus_int32 vbr_bound;
1032 opus_int32 max_allowed;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001033 /* We could use any multiple of vbr_rate as bound (depending on the
1034 delay).
Gregory Maxwell420c3252011-01-27 22:35:50 -05001035 This is clamped to ensure we use at least two bytes if the encoder
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001036 was entirely empty, but to allow 0 in hybrid mode. */
1037 vbr_bound = vbr_rate;
Gregory Maxwell420c3252011-01-27 22:35:50 -05001038 max_allowed = IMIN(IMAX(tell==1?2:0,
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001039 vbr_rate+vbr_bound-st->vbr_reservoir>>(BITRES+3)),
1040 nbAvailableBytes);
1041 if(max_allowed < nbAvailableBytes)
1042 {
1043 nbCompressedBytes = nbFilledBytes+max_allowed;
1044 nbAvailableBytes = max_allowed;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001045 ec_enc_shrink(enc, nbCompressedBytes);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001046 }
1047 }
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001048 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001049 total_bits = nbCompressedBytes*8;
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001050
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001051 effEnd = st->end;
1052 if (effEnd > st->mode->effEBands)
1053 effEnd = st->mode->effEBands;
1054
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001055 ALLOC(in, CC*(N+st->overlap), celt_sig);
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001056
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001057 /* Find pitch period and gain */
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +11001058 {
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001059 VARDECL(celt_sig, _pre);
1060 celt_sig *pre[2];
1061 SAVE_STACK;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001062 ALLOC(_pre, CC*(N+COMBFILTER_MAXPERIOD), celt_sig);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001063
1064 pre[0] = _pre;
1065 pre[1] = _pre + (N+COMBFILTER_MAXPERIOD);
1066
Jean-Marc Valinde79c372011-01-26 09:24:33 -05001067 silence = 1;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001068 c=0; do {
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001069 int count = 0;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001070 const opus_val16 * restrict pcmp = pcm+c;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001071 celt_sig * restrict inp = in+c*(N+st->overlap)+st->overlap;
1072
1073 for (i=0;i<N;i++)
1074 {
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001075 celt_sig x, tmp;
1076
1077 x = SCALEIN(*pcmp);
Jean-Marc Valin0b405d12011-02-04 01:03:42 -05001078#ifndef FIXED_POINT
Gregory Maxwell58ecb1a2011-05-09 13:16:30 -04001079 if (!(x==x))
1080 x = 0;
Jean-Marc Valin0b405d12011-02-04 01:03:42 -05001081 if (st->clip)
1082 x = MAX32(-65536.f, MIN32(65536.f,x));
1083#endif
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001084 if (++count==st->upsample)
1085 {
1086 count=0;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001087 pcmp+=CC;
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001088 } else {
1089 x = 0;
1090 }
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001091 /* Apply pre-emphasis */
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001092 tmp = MULT16_16(st->mode->preemph[2], x);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001093 *inp = tmp + st->preemph_memE[c];
1094 st->preemph_memE[c] = MULT16_32_Q15(st->mode->preemph[1], *inp)
1095 - MULT16_32_Q15(st->mode->preemph[0], tmp);
Jean-Marc Valinde79c372011-01-26 09:24:33 -05001096 silence = silence && *inp == 0;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001097 inp++;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001098 }
1099 CELT_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD);
1100 CELT_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+st->overlap)+st->overlap, N);
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001101 } while (++c<CC);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001102
Jean-Marc Valin65d35a32011-01-26 22:04:59 -05001103 if (tell==1)
1104 ec_enc_bit_logp(enc, silence, 15);
1105 else
1106 silence=0;
Jean-Marc Valinde79c372011-01-26 09:24:33 -05001107 if (silence)
1108 {
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001109 /*In VBR mode there is no need to send more than the minimum. */
1110 if (vbr_rate>0)
1111 {
Jean-Marc Valin65d35a32011-01-26 22:04:59 -05001112 effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2);
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001113 total_bits=nbCompressedBytes*8;
1114 nbAvailableBytes=2;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001115 ec_enc_shrink(enc, nbCompressedBytes);
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001116 }
Jean-Marc Valin13a7c262011-01-26 10:58:33 -05001117 /* Pretend we've filled all the remaining bits with zeros
1118 (that's what the initialiser did anyway) */
Jean-Marc Valinde79c372011-01-26 09:24:33 -05001119 tell = nbCompressedBytes*8;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001120 enc->nbits_total+=tell-ec_tell(enc);
Jean-Marc Valinde79c372011-01-26 09:24:33 -05001121 }
Jean-Marc Valind539c6b2011-02-03 13:36:03 -05001122 if (nbAvailableBytes>12*C && st->start==0 && !silence && !st->disable_pf && st->complexity >= 5)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001123 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001124 VARDECL(opus_val16, pitch_buf);
1125 ALLOC(pitch_buf, (COMBFILTER_MAXPERIOD+N)>>1, opus_val16);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001126
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001127 pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC);
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05001128 pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N,
Jean-Marc Valine3e2c262011-01-26 13:09:53 -05001129 COMBFILTER_MAXPERIOD-COMBFILTER_MINPERIOD, &pitch_index);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001130 pitch_index = COMBFILTER_MAXPERIOD-pitch_index;
1131
1132 gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD,
1133 N, &pitch_index, st->prefilter_period, st->prefilter_gain);
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001134 if (pitch_index > COMBFILTER_MAXPERIOD-2)
1135 pitch_index = COMBFILTER_MAXPERIOD-2;
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -05001136 gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1);
Jean-Marc Valin69653882011-04-21 10:41:13 -04001137 if (st->loss_rate>2)
1138 gain1 = HALF32(gain1);
1139 if (st->loss_rate>4)
1140 gain1 = HALF32(gain1);
1141 if (st->loss_rate>8)
1142 gain1 = 0;
Jean-Marc Valin8d367022011-01-17 16:37:51 -05001143 prefilter_tapset = st->tapset_decision;
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -05001144 } else {
1145 gain1 = 0;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001146 }
Jean-Marc Valin6ba0b352010-12-20 11:40:30 -05001147
1148 /* Gain threshold for enabling the prefilter/postfilter */
1149 pf_threshold = QCONST16(.2f,15);
1150
1151 /* Adjusting the threshold based on rate and continuity */
1152 if (abs(pitch_index-st->prefilter_period)*10>pitch_index)
1153 pf_threshold += QCONST16(.2f,15);
1154 if (nbAvailableBytes<25)
1155 pf_threshold += QCONST16(.1f,15);
1156 if (nbAvailableBytes<35)
1157 pf_threshold += QCONST16(.1f,15);
1158 if (st->prefilter_gain > QCONST16(.4f,15))
1159 pf_threshold -= QCONST16(.1f,15);
1160 if (st->prefilter_gain > QCONST16(.55f,15))
1161 pf_threshold -= QCONST16(.1f,15);
1162
1163 /* Hard threshold at 0.2 */
1164 pf_threshold = MAX16(pf_threshold, QCONST16(.2f,15));
1165 if (gain1<pf_threshold)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001166 {
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001167 if(st->start==0 && tell+16<=total_bits)
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001168 ec_enc_bit_logp(enc, 0, 1);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001169 gain1 = 0;
Jean-Marc Valin8d367022011-01-17 16:37:51 -05001170 pf_on = 0;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001171 } else {
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001172 /*This block is not gated by a total bits check only because
1173 of the nbAvailableBytes check above.*/
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001174 int qg;
1175 int octave;
Jean-Marc Valin6ba0b352010-12-20 11:40:30 -05001176
Jean-Marc Valinb417d832011-01-27 17:19:49 -05001177 if (ABS16(gain1-st->prefilter_gain)<QCONST16(.1f,15))
Jean-Marc Valin6ba0b352010-12-20 11:40:30 -05001178 gain1=st->prefilter_gain;
1179
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001180#ifdef FIXED_POINT
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001181 qg = ((gain1+1536)>>10)/3-1;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001182#else
Gregory Maxwell662587d2011-08-01 20:41:54 -04001183 qg = (int)floor(.5f+gain1*32/3)-1;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001184#endif
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001185 qg = IMAX(0, IMIN(7, qg));
Timothy B. Terriberrye86fb262010-12-17 14:50:19 -08001186 ec_enc_bit_logp(enc, 1, 1);
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001187 pitch_index += 1;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001188 octave = EC_ILOG(pitch_index)-5;
1189 ec_enc_uint(enc, octave, 6);
1190 ec_enc_bits(enc, pitch_index-(16<<octave), 4+octave);
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001191 pitch_index -= 1;
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001192 ec_enc_bits(enc, qg, 3);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001193 if (ec_tell(enc)+2<=total_bits)
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001194 ec_enc_icdf(enc, prefilter_tapset, tapset_icdf, 2);
1195 else
1196 prefilter_tapset = 0;
1197 gain1 = QCONST16(0.09375f,15)*(qg+1);
Jean-Marc Valin8d367022011-01-17 16:37:51 -05001198 pf_on = 1;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001199 }
1200 /*printf("%d %f\n", pitch_index, gain1);*/
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001201
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001202 c=0; do {
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05001203 int offset = st->mode->shortMdctSize-st->mode->overlap;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001204 st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001205 CELT_COPY(in+c*(N+st->overlap), st->in_mem+c*(st->overlap), st->overlap);
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05001206 if (offset)
1207 comb_filter(in+c*(N+st->overlap)+st->overlap, pre[c]+COMBFILTER_MAXPERIOD,
1208 st->prefilter_period, st->prefilter_period, offset, -st->prefilter_gain, -st->prefilter_gain,
1209 st->prefilter_tapset, st->prefilter_tapset, NULL, 0);
1210
1211 comb_filter(in+c*(N+st->overlap)+st->overlap+offset, pre[c]+COMBFILTER_MAXPERIOD+offset,
1212 st->prefilter_period, pitch_index, N-offset, -st->prefilter_gain, -gain1,
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001213 st->prefilter_tapset, prefilter_tapset, st->mode->window, st->mode->overlap);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001214 CELT_COPY(st->in_mem+c*(st->overlap), in+c*(N+st->overlap)+N, st->overlap);
1215
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001216 if (N>COMBFILTER_MAXPERIOD)
1217 {
1218 CELT_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD);
1219 } else {
1220 CELT_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, prefilter_mem+c*COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD-N);
1221 CELT_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N);
1222 }
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001223 } while (++c<CC);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001224
1225 RESTORE_STACK;
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +11001226 }
Jean-Marc Valin2014ca32009-06-18 23:33:04 -04001227
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001228#ifdef RESYNTH
1229 resynth = 1;
1230#else
1231 resynth = 0;
1232#endif
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -04001233
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001234 isTransient = 0;
1235 shortBlocks = 0;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001236 if (LM>0 && ec_tell(enc)+3<=total_bits)
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001237 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001238 if (st->complexity > 1)
1239 {
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001240 isTransient = transient_analysis(in, N+st->overlap, CC,
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05001241 st->overlap);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001242 if (isTransient)
1243 shortBlocks = M;
1244 }
1245 ec_enc_bit_logp(enc, isTransient, 3);
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001246 }
Jean-Marc Valinc5f2a9d2008-10-26 22:00:26 -04001247
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001248 ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */
1249 ALLOC(bandE,st->mode->nbEBands*CC, celt_ener);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001250 ALLOC(bandLogE,st->mode->nbEBands*CC, opus_val16);
Jean-Marc Valin32ec58c2009-05-01 21:28:58 -04001251 /* Compute MDCTs */
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001252 compute_mdcts(st->mode, shortBlocks, in, freq, CC, LM);
Jean-Marc Valin08a82ff2009-06-14 14:05:19 -04001253
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001254 if (CC==2&&C==1)
1255 {
1256 for (i=0;i<N;i++)
1257 freq[i] = ADD32(HALF32(freq[i]), HALF32(freq[N+i]));
1258 }
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001259 if (st->upsample != 1)
1260 {
1261 c=0; do
1262 {
1263 int bound = N/st->upsample;
1264 for (i=0;i<bound;i++)
1265 freq[c*N+i] *= st->upsample;
1266 for (;i<N;i++)
1267 freq[c*N+i] = 0;
1268 } while (++c<C);
1269 }
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001270 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
Jean-Marc Valin8d4ac152008-02-29 17:24:02 +11001271
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001272 compute_band_energies(st->mode, freq, bandE, effEnd, C, M);
Jean-Marc Valin504fb3c2010-08-06 15:56:22 -04001273
1274 amp2Log2(st->mode, effEnd, st->end, bandE, bandLogE, C);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001275
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11001276 /* Band normalisation */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001277 normalise_bands(st->mode, freq, X, bandE, effEnd, C, M);
Jean-Marc Valin4c77ea92009-09-14 22:50:41 -04001278
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -04001279 ALLOC(tf_res, st->mode->nbEBands, int);
Gregory Maxwell06d57b22011-08-01 22:02:25 -04001280 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 -04001281 for (i=effEnd;i<st->end;i++)
1282 tf_res[i] = tf_res[effEnd-1];
1283
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001284 ALLOC(error, C*st->mode->nbEBands, opus_val16);
Jean-Marc Valin5e7f02d2010-08-08 09:48:22 -04001285 quant_coarse_energy(st->mode, st->start, st->end, effEnd, bandLogE,
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001286 oldBandE, total_bits, error, enc,
Timothy B. Terriberryef2e6502010-11-09 01:43:18 -08001287 C, LM, nbAvailableBytes, st->force_intra,
Jean-Marc Valineda2dee2011-04-21 16:04:27 -04001288 &st->delayedIntra, st->complexity >= 4, st->loss_rate);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001289
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001290 tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc);
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001291
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001292 st->spread_decision = SPREAD_NORMAL;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001293 if (ec_tell(enc)+4<=total_bits)
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -04001294 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001295 if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C)
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001296 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001297 if (st->complexity == 0)
1298 st->spread_decision = SPREAD_NONE;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001299 } else {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001300 st->spread_decision = spreading_decision(st->mode, X,
Jean-Marc Valin8d367022011-01-17 16:37:51 -05001301 &st->tonal_average, st->spread_decision, &st->hf_average,
1302 &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M);
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001303 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001304 ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5);
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -04001305 }
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001306
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001307 ALLOC(cap, st->mode->nbEBands, int);
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001308 ALLOC(offsets, st->mode->nbEBands, int);
1309
Timothy B. Terriberryce6d0902011-02-01 17:41:12 -08001310 init_caps(st->mode,cap,LM,C);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001311 for (i=0;i<st->mode->nbEBands;i++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001312 offsets[i] = 0;
1313 /* Dynamic allocation code */
1314 /* Make sure that dynamic allocation can't make us bust the budget */
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001315 if (effectiveBytes > 50 && LM>=1)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001316 {
1317 int t1, t2;
1318 if (LM <= 1)
1319 {
1320 t1 = 3;
1321 t2 = 5;
1322 } else {
1323 t1 = 2;
1324 t2 = 4;
1325 }
Gregory Maxwell7007f1b2011-02-08 16:17:47 -05001326 for (i=st->start+1;i<st->end-1;i++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001327 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001328 opus_val32 d2;
Jean-Marc Valina3a066c2010-11-04 15:15:54 -04001329 d2 = 2*bandLogE[i]-bandLogE[i-1]-bandLogE[i+1];
1330 if (C==2)
1331 d2 = HALF32(d2 + 2*bandLogE[i+st->mode->nbEBands]-
1332 bandLogE[i-1+st->mode->nbEBands]-bandLogE[i+1+st->mode->nbEBands]);
1333 if (d2 > SHL16(t1,DB_SHIFT))
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001334 offsets[i] += 1;
Jean-Marc Valina3a066c2010-11-04 15:15:54 -04001335 if (d2 > SHL16(t2,DB_SHIFT))
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001336 offsets[i] += 1;
1337 }
1338 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001339 dynalloc_logp = 6;
1340 total_bits<<=BITRES;
1341 total_boost = 0;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001342 tell = ec_tell_frac(enc);
Timothy B. Terriberryd6f61572010-12-30 09:04:16 -08001343 for (i=st->start;i<st->end;i++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001344 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001345 int width, quanta;
1346 int dynalloc_loop_logp;
1347 int boost;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001348 int j;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001349 width = C*(st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
1350 /* quanta is 6 bits, but no more than 1 bit/sample
1351 and no less than 1/8 bit/sample */
1352 quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));
1353 dynalloc_loop_logp = dynalloc_logp;
1354 boost = 0;
1355 for (j = 0; tell+(dynalloc_loop_logp<<BITRES) < total_bits-total_boost
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001356 && boost < cap[i]; j++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001357 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001358 int flag;
1359 flag = j<offsets[i];
1360 ec_enc_bit_logp(enc, flag, dynalloc_loop_logp);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001361 tell = ec_tell_frac(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001362 if (!flag)
1363 break;
1364 boost += quanta;
1365 total_boost += quanta;
1366 dynalloc_loop_logp = 1;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001367 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001368 /* Making dynalloc more likely */
1369 if (j)
1370 dynalloc_logp = IMAX(2, dynalloc_logp-1);
1371 offsets[i] = boost;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001372 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001373 alloc_trim = 5;
1374 if (tell+(6<<BITRES) <= total_bits - total_boost)
1375 {
1376 alloc_trim = alloc_trim_analysis(st->mode, X, bandLogE,
Gregory Maxwell7007f1b2011-02-08 16:17:47 -05001377 st->end, LM, C, N);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001378 ec_enc_icdf(enc, alloc_trim, trim_icdf, 7);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001379 tell = ec_tell_frac(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001380 }
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001381
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001382 /* Variable bitrate */
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001383 if (vbr_rate>0)
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001384 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001385 opus_val16 alpha;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001386 opus_int32 delta;
Gregory Maxwella9411472010-10-28 03:52:21 -04001387 /* The target rate in 8th bits per frame */
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001388 opus_int32 target;
1389 opus_int32 min_allowed;
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001390
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001391 target = vbr_rate + st->vbr_offset - ((40*C+20)<<BITRES);
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001392
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001393 /* Shortblocks get a large boost in bitrate, but since they
Jean-Marc Valinccd5a612010-10-13 01:11:55 -04001394 are uncommon long blocks are not greatly affected */
1395 if (shortBlocks || tf_sum < -2*(st->end-st->start))
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001396 target = 7*target/4;
Jean-Marc Valinccd5a612010-10-13 01:11:55 -04001397 else if (tf_sum < -(st->end-st->start))
1398 target = 3*target/2;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001399 else if (M > 1)
Jean-Marc Valinccd5a612010-10-13 01:11:55 -04001400 target-=(target+14)/28;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001401
Gregory Maxwella9411472010-10-28 03:52:21 -04001402 /* The current offset is removed from the target and the space used
1403 so far is added*/
Jean-Marc Valina4badac2010-12-03 15:20:11 -05001404 target=target+tell;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001405
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001406 /* In VBR mode the frame size must not be reduced so much that it would
1407 result in the encoder running out of bits.
1408 The margin of 2 bytes ensures that none of the bust-prevention logic
1409 in the decoder will have triggered so far. */
1410 min_allowed = (tell+total_boost+(1<<BITRES+3)-1>>(BITRES+3)) + 2 - nbFilledBytes;
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001411
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001412 nbAvailableBytes = target+(1<<(BITRES+2))>>(BITRES+3);
Gregory Maxwelld85018c2011-01-13 14:38:24 -05001413 nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes);
1414 nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes) - nbFilledBytes;
Jean-Marc Valin6b565262011-01-12 11:27:03 -05001415
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001416 /* By how much did we "miss" the target on that frame */
1417 delta = target - vbr_rate;
1418
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001419 target=nbAvailableBytes<<(BITRES+3);
1420
Gregory Maxwellfdd86752011-04-13 17:08:22 -04001421 /*If the frame is silent we don't adjust our drift, otherwise
1422 the encoder will shoot to very high rates after hitting a
1423 span of silence, but we do allow the bitres to refill.
1424 This means that we'll undershoot our target in CVBR/VBR modes
1425 on files with lots of silence. */
1426 if(silence)
1427 {
1428 nbAvailableBytes = 2;
1429 target = 2*8<<BITRES;
1430 delta = 0;
1431 }
1432
Gregory Maxwella9411472010-10-28 03:52:21 -04001433 if (st->vbr_count < 970)
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001434 {
1435 st->vbr_count++;
Gregory Maxwella9411472010-10-28 03:52:21 -04001436 alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+20),16));
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001437 } else
1438 alpha = QCONST16(.001f,15);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001439 /* How many bits have we used in excess of what we're allowed */
Jean-Marc Valin9faf7402010-12-04 10:27:22 -05001440 if (st->constrained_vbr)
1441 st->vbr_reservoir += target - vbr_rate;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001442 /*printf ("%d\n", st->vbr_reservoir);*/
1443
1444 /* Compute the offset we need to apply in order to reach the target */
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001445 st->vbr_drift += (opus_int32)MULT16_32_Q15(alpha,delta-st->vbr_offset-st->vbr_drift);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001446 st->vbr_offset = -st->vbr_drift;
1447 /*printf ("%d\n", st->vbr_drift);*/
1448
Jean-Marc Valin9faf7402010-12-04 10:27:22 -05001449 if (st->constrained_vbr && st->vbr_reservoir < 0)
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001450 {
1451 /* We're under the min value -- increase rate */
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001452 int adjust = (-st->vbr_reservoir)/(8<<BITRES);
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001453 /* Unless we're just coding silence */
1454 nbAvailableBytes += silence?0:adjust;
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001455 st->vbr_reservoir = 0;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001456 /*printf ("+%d\n", adjust);*/
1457 }
Gregory Maxwelld85018c2011-01-13 14:38:24 -05001458 nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001459 /* This moves the raw bits to take into account the new compressed size */
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001460 ec_enc_shrink(enc, nbCompressedBytes);
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001461 }
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001462 if (C==2)
1463 {
1464 int effectiveRate;
1465
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001466 /* Always use MS for 2.5 ms frames until we can do a better analysis */
1467 if (LM!=0)
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05001468 dual_stereo = stereo_analysis(st->mode, X, LM, N);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001469
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001470 /* Account for coarse energy */
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001471 effectiveRate = (8*effectiveBytes - 80)>>LM;
1472
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001473 /* effectiveRate in kb/s */
1474 effectiveRate = 2*effectiveRate/5;
1475 if (effectiveRate<35)
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -05001476 intensity = 8;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001477 else if (effectiveRate<50)
1478 intensity = 12;
1479 else if (effectiveRate<68)
1480 intensity = 16;
1481 else if (effectiveRate<84)
1482 intensity = 18;
1483 else if (effectiveRate<102)
1484 intensity = 19;
1485 else if (effectiveRate<130)
1486 intensity = 20;
1487 else
1488 intensity = 100;
1489 intensity = IMIN(st->end,IMAX(st->start, intensity));
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001490 }
1491
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001492 /* Bit allocation */
1493 ALLOC(fine_quant, st->mode->nbEBands, int);
1494 ALLOC(pulses, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04001495 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +11001496
Timothy B. Terriberry285bc372011-02-06 13:29:00 -08001497 /* bits = packet size - where we are - safety*/
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001498 bits = ((opus_int32)nbCompressedBytes*8<<BITRES) - ec_tell_frac(enc) - 1;
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08001499 anti_collapse_rsv = isTransient&&LM>=2&&bits>=(LM+2<<BITRES) ? (1<<BITRES) : 0;
1500 bits -= anti_collapse_rsv;
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001501 codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08001502 alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
1503 fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands);
Jean-Marc Valindfd6e712010-12-09 23:23:34 -05001504 st->lastCodedBands = codedBands;
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -05001505
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05001506 quant_fine_energy(st->mode, st->start, st->end, oldBandE, error, fine_quant, enc, C);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001507
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +02001508#ifdef MEASURE_NORM_MSE
Jean-Marc Valin44092242010-07-29 18:32:54 +02001509 float X0[3000];
1510 float bandE0[60];
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001511 c=0; do
Jean-Marc Valin44092242010-07-29 18:32:54 +02001512 for (i=0;i<N;i++)
1513 X0[i+c*N] = X[i+c*N];
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001514 while (++c<C);
Jean-Marc Valin44092242010-07-29 18:32:54 +02001515 for (i=0;i<C*st->mode->nbEBands;i++)
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +02001516 bandE0[i] = bandE[i];
1517#endif
1518
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11001519 /* Residual quantisation */
Jean-Marc Valin7e983192011-02-01 18:00:29 -05001520 ALLOC(collapse_masks, C*st->mode->nbEBands, unsigned char);
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08001521 quant_all_bands(1, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks,
Timothy B. Terriberry320cf2e2010-12-17 05:52:06 -08001522 bandE, pulses, shortBlocks, st->spread_decision, dual_stereo, intensity, tf_res, resynth,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08001523 nbCompressedBytes*(8<<BITRES)-anti_collapse_rsv, balance, enc, LM, codedBands, &st->rng);
Jean-Marc Valin39710532009-06-09 00:10:32 -04001524
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08001525 if (anti_collapse_rsv > 0)
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001526 {
1527 anti_collapse_on = st->consec_transient<2;
1528 ec_enc_bits(enc, anti_collapse_on, 1);
1529 }
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001530 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 -04001531
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001532 if (silence)
1533 {
1534 for (i=0;i<C*st->mode->nbEBands;i++)
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001535 oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001536 }
1537
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001538#ifdef RESYNTH
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -05001539 /* Re-synthesis of the coded audio if required */
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -04001540 if (resynth)
Jean-Marc Valin18ddc022008-02-22 14:24:50 +11001541 {
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001542 celt_sig *out_mem[2];
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001543 celt_sig *overlap_mem[2];
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001544
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001545 log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
Jean-Marc Valin4b000c32011-01-26 20:30:21 -05001546 if (silence)
1547 {
1548 for (i=0;i<C*st->mode->nbEBands;i++)
1549 bandE[i] = 0;
1550 }
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04001551
1552#ifdef MEASURE_NORM_MSE
1553 measure_norm_mse(st->mode, X, X0, bandE, bandE0, M, N, C);
1554#endif
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001555 if (anti_collapse_on)
1556 {
Timothy B. Terriberry682b6cf2011-01-31 13:34:54 -08001557 anti_collapse(st->mode, X, collapse_masks, LM, C, CC, N,
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05001558 st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001559 }
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04001560
Jean-Marc Valin88619552009-10-04 21:35:36 -04001561 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001562 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valin88619552009-10-04 21:35:36 -04001563
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001564 CELT_MOVE(st->syn_mem[0], st->syn_mem[0]+N, MAX_PERIOD);
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001565 if (CC==2)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001566 CELT_MOVE(st->syn_mem[1], st->syn_mem[1]+N, MAX_PERIOD);
1567
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001568 c=0; do
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -04001569 for (i=0;i<M*st->mode->eBands[st->start];i++)
1570 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001571 while (++c<C);
1572 c=0; do
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -04001573 for (i=M*st->mode->eBands[st->end];i<N;i++)
1574 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001575 while (++c<C);
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -04001576
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001577 if (CC==2&&C==1)
1578 {
1579 for (i=0;i<N;i++)
1580 freq[N+i] = freq[i];
1581 }
1582
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001583 out_mem[0] = st->syn_mem[0]+MAX_PERIOD;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001584 if (CC==2)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001585 out_mem[1] = st->syn_mem[1]+MAX_PERIOD;
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001586
Gregory Maxwella45724e2011-07-29 11:53:45 -04001587 overlap_mem[0] = prefilter_mem+CC*COMBFILTER_MAXPERIOD;
1588 if (CC==2)
1589 overlap_mem[1] = overlap_mem[0] + st->overlap;
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001590
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001591 compute_inv_mdcts(st->mode, shortBlocks, freq, out_mem, overlap_mem, CC, LM);
Jean-Marc Valine12017e2009-10-03 13:57:31 -04001592
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001593 c=0; do {
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001594 st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);
1595 st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD);
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05001596 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 -05001597 st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset,
1598 st->mode->window, st->overlap);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001599 if (LM!=0)
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05001600 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 -05001601 st->prefilter_gain, gain1, st->prefilter_tapset, prefilter_tapset,
1602 st->mode->window, st->mode->overlap);
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001603 } while (++c<CC);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001604
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001605 deemphasis(out_mem, (opus_val16*)pcm, N, CC, st->upsample, st->mode->preemph, st->preemph_memD);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001606 st->prefilter_period_old = st->prefilter_period;
1607 st->prefilter_gain_old = st->prefilter_gain;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001608 st->prefilter_tapset_old = st->prefilter_tapset;
Jean-Marc Valind9b95652008-08-31 23:34:47 -04001609 }
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001610#endif
1611
1612 st->prefilter_period = pitch_index;
1613 st->prefilter_gain = gain1;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001614 st->prefilter_tapset = prefilter_tapset;
Jean-Marc Valina14e86d2011-02-11 16:27:27 -05001615#ifdef RESYNTH
1616 if (LM!=0)
1617 {
1618 st->prefilter_period_old = st->prefilter_period;
1619 st->prefilter_gain_old = st->prefilter_gain;
1620 st->prefilter_tapset_old = st->prefilter_tapset;
1621 }
1622#endif
Gregory Maxwell54547f12009-02-16 18:56:44 -05001623
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001624 if (CC==2&&C==1) {
1625 for (i=0;i<st->mode->nbEBands;i++)
1626 oldBandE[st->mode->nbEBands+i]=oldBandE[i];
1627 }
1628
Jean-Marc Valin5677e342011-01-13 16:15:53 -05001629 /* In case start or end were to change */
Jean-Marc Valin5c2ac2b2011-01-22 14:48:20 -05001630 c=0; do
1631 {
1632 for (i=0;i<st->start;i++)
1633 oldBandE[c*st->mode->nbEBands+i]=0;
1634 for (i=st->end;i<st->mode->nbEBands;i++)
1635 oldBandE[c*st->mode->nbEBands+i]=0;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001636 } while (++c<CC);
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001637 if (!isTransient)
1638 {
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001639 for (i=0;i<CC*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001640 oldLogE2[i] = oldLogE[i];
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001641 for (i=0;i<CC*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001642 oldLogE[i] = oldBandE[i];
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05001643 } else {
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001644 for (i=0;i<CC*st->mode->nbEBands;i++)
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05001645 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001646 }
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001647 if (isTransient)
1648 st->consec_transient++;
1649 else
1650 st->consec_transient=0;
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05001651 st->rng = enc->rng;
Jean-Marc Valin5677e342011-01-13 16:15:53 -05001652
Jean-Marc Valin30d51252010-06-21 17:55:28 -04001653 /* If there's any room left (can only happen for very high rates),
Jean-Marc Valin13a7c262011-01-26 10:58:33 -05001654 it's already filled with zeros */
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001655 ec_enc_done(enc);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001656
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05001657 if (st->signalling)
1658 nbCompressedBytes++;
1659
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001660 RESTORE_STACK;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001661 if (ec_get_error(enc))
Jean-Marc Valinef20e392011-03-18 15:34:11 -04001662 return CELT_INTERNAL_ERROR;
Jean-Marc Valin9d785af2010-07-18 09:42:05 -04001663 else
1664 return nbCompressedBytes;
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11001665}
1666
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001667#ifdef FIXED_POINT
1668#ifndef DISABLE_FLOAT_API
Jean-Marc Valin51c78622011-02-03 00:43:37 -05001669CELT_STATIC
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001670int celt_encode_with_ec_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001671{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001672 int j, ret, C, N;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001673 VARDECL(opus_int16, in);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05001674 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001675
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001676 if (pcm==NULL)
1677 return CELT_BAD_ARG;
1678
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001679 C = CHANNELS(st->channels);
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001680 N = frame_size;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001681 ALLOC(in, C*N, opus_int16);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001682
1683 for (j=0;j<C*N;j++)
1684 in[j] = FLOAT2INT16(pcm[j]);
1685
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001686 ret=celt_encode_with_ec(st,in,frame_size,compressed,nbCompressedBytes, enc);
1687#ifdef RESYNTH
1688 for (j=0;j<C*N;j++)
1689 ((float*)pcm)[j]=in[j]*(1.f/32768.f);
1690#endif
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001691 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001692 return ret;
1693
1694}
1695#endif /*DISABLE_FLOAT_API*/
1696#else
Jean-Marc Valin51c78622011-02-03 00:43:37 -05001697CELT_STATIC
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001698int celt_encode_with_ec(CELTEncoder * restrict st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001699{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001700 int j, ret, C, N;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001701 VARDECL(celt_sig, in);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05001702 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001703
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001704 if (pcm==NULL)
1705 return CELT_BAD_ARG;
1706
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001707 C=CHANNELS(st->channels);
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001708 N=frame_size;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001709 ALLOC(in, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001710 for (j=0;j<C*N;j++) {
1711 in[j] = SCALEOUT(pcm[j]);
1712 }
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001713
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001714 ret = celt_encode_with_ec_float(st,in,frame_size,compressed,nbCompressedBytes, enc);
1715#ifdef RESYNTH
1716 for (j=0;j<C*N;j++)
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001717 ((opus_int16*)pcm)[j] = FLOAT2INT16(in[j]);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001718#endif
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001719 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001720 return ret;
1721}
1722#endif
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +11001723
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001724int celt_encode(CELTEncoder * restrict st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001725{
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001726 return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001727}
1728
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001729#ifndef DISABLE_FLOAT_API
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001730int celt_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1731{
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001732 return celt_encode_with_ec_float(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001733}
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001734#endif /* DISABLE_FLOAT_API */
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001735
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001736int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...)
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001737{
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001738 va_list ap;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001739
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001740 va_start(ap, request);
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001741 switch (request)
1742 {
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001743 case CELT_SET_COMPLEXITY_REQUEST:
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001744 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001745 int value = va_arg(ap, opus_int32);
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001746 if (value<0 || value>10)
1747 goto bad_arg;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001748 st->complexity = value;
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001749 }
1750 break;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001751 case CELT_SET_START_BAND_REQUEST:
1752 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001753 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001754 if (value<0 || value>=st->mode->nbEBands)
1755 goto bad_arg;
1756 st->start = value;
1757 }
1758 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001759 case CELT_SET_END_BAND_REQUEST:
1760 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001761 opus_int32 value = va_arg(ap, opus_int32);
Timothy B. Terriberry8893e532010-12-30 08:56:49 -08001762 if (value<1 || value>st->mode->nbEBands)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001763 goto bad_arg;
1764 st->end = value;
1765 }
1766 break;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001767 case CELT_SET_PREDICTION_REQUEST:
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001768 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001769 int value = va_arg(ap, opus_int32);
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001770 if (value<0 || value>2)
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001771 goto bad_arg;
Jean-Marc Valind539c6b2011-02-03 13:36:03 -05001772 st->disable_pf = value<=1;
1773 st->force_intra = value==0;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001774 }
1775 break;
Jean-Marc Valin69653882011-04-21 10:41:13 -04001776 case CELT_SET_LOSS_PERC_REQUEST:
1777 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001778 int value = va_arg(ap, opus_int32);
Jean-Marc Valin69653882011-04-21 10:41:13 -04001779 if (value<0 || value>100)
1780 goto bad_arg;
1781 st->loss_rate = value;
1782 }
1783 break;
Jean-Marc Valin79b34eb2010-12-05 17:22:06 -05001784 case CELT_SET_VBR_CONSTRAINT_REQUEST:
1785 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001786 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin79b34eb2010-12-05 17:22:06 -05001787 st->constrained_vbr = value;
1788 }
1789 break;
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001790 case CELT_SET_VBR_REQUEST:
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001791 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001792 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001793 st->vbr = value;
1794 }
1795 break;
1796 case CELT_SET_BITRATE_REQUEST:
1797 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001798 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001799 if (value<=500)
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001800 goto bad_arg;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05001801 value = IMIN(value, 260000*st->channels);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001802 st->bitrate = value;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001803 }
1804 break;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001805 case CELT_SET_CHANNELS_REQUEST:
1806 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001807 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001808 if (value<1 || value>2)
1809 goto bad_arg;
1810 st->stream_channels = value;
1811 }
1812 break;
John Ridges454d1d02009-05-21 22:38:39 -04001813 case CELT_RESET_STATE:
1814 {
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001815 CELT_MEMSET((char*)&st->ENCODER_RESET_START, 0,
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05001816 celt_encoder_get_size_custom(st->mode, st->channels)-
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001817 ((char*)&st->ENCODER_RESET_START - (char*)st));
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001818 st->vbr_offset = 0;
John Ridges454d1d02009-05-21 22:38:39 -04001819 st->delayedIntra = 1;
Timothy B. Terriberry320cf2e2010-12-17 05:52:06 -08001820 st->spread_decision = SPREAD_NORMAL;
Jean-Marc Valin628c0252010-04-16 20:57:56 -04001821 st->tonal_average = QCONST16(1.f,8);
John Ridges454d1d02009-05-21 22:38:39 -04001822 }
1823 break;
Jean-Marc Valin0b405d12011-02-04 01:03:42 -05001824 case CELT_SET_INPUT_CLIPPING_REQUEST:
1825 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001826 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin0b405d12011-02-04 01:03:42 -05001827 st->clip = value;
1828 }
1829 break;
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04001830#ifdef OPUS_BUILD
1831 case CELT_SET_SIGNALLING_REQUEST:
1832 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001833 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04001834 st->signalling = value;
1835 }
1836 break;
1837 case CELT_GET_MODE_REQUEST:
1838 {
1839 const CELTMode ** value = va_arg(ap, const CELTMode**);
1840 if (value==0)
1841 goto bad_arg;
1842 *value=st->mode;
1843 }
1844 break;
1845#endif
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001846 default:
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001847 goto bad_request;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001848 }
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001849 va_end(ap);
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001850 return CELT_OK;
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001851bad_arg:
1852 va_end(ap);
1853 return CELT_BAD_ARG;
1854bad_request:
1855 va_end(ap);
1856 return CELT_UNIMPLEMENTED;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001857}
1858
Jean-Marc Valin56522ad2009-06-05 17:17:25 -04001859/**********************************************************************/
1860/* */
1861/* DECODER */
1862/* */
1863/**********************************************************************/
Jean-Marc Valineafbdd52009-04-27 19:35:09 -04001864#define DECODE_BUFFER_SIZE 2048
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001865
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001866/** Decoder state
Jean-Marc Valin276de722008-02-20 17:45:51 +11001867 @brief Decoder state
1868 */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001869struct CELTDecoder {
1870 const CELTMode *mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001871 int overlap;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001872 int channels;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05001873 int stream_channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001874
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001875 int downsample;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001876 int start, end;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05001877 int signalling;
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001878
1879 /* Everything beyond this point gets cleared on a reset */
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05001880#define DECODER_RESET_START rng
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001881
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001882 opus_uint32 rng;
Jean-Marc Valinef20e392011-03-18 15:34:11 -04001883 int error;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001884 int last_pitch_index;
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001885 int loss_count;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001886 int postfilter_period;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001887 int postfilter_period_old;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001888 opus_val16 postfilter_gain;
1889 opus_val16 postfilter_gain_old;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001890 int postfilter_tapset;
1891 int postfilter_tapset_old;
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001892
1893 celt_sig preemph_memD[2];
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001894
Jean-Marc Valinca8b9922010-08-27 16:23:03 -04001895 celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001896 /* opus_val16 lpc[], Size = channels*LPC_ORDER */
1897 /* opus_val16 oldEBands[], Size = 2*mode->nbEBands */
1898 /* opus_val16 oldLogE[], Size = 2*mode->nbEBands */
1899 /* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */
1900 /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001901};
1902
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05001903int celt_decoder_get_size(int channels)
1904{
1905 const CELTMode *mode = celt_mode_create(48000, 960, NULL);
1906 return celt_decoder_get_size_custom(mode, channels);
1907}
1908
1909int celt_decoder_get_size_custom(const CELTMode *mode, int channels)
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001910{
1911 int size = sizeof(struct CELTDecoder)
1912 + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig)
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001913 + channels*LPC_ORDER*sizeof(opus_val16)
1914 + 4*2*mode->nbEBands*sizeof(opus_val16);
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001915 return size;
1916}
1917
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001918CELTDecoder *celt_decoder_create(int sampling_rate, int channels, int *error)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001919{
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -05001920 CELTDecoder *st;
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05001921 st = (CELTDecoder *)celt_alloc(celt_decoder_get_size(channels));
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -05001922 if (st!=NULL && celt_decoder_init(st, sampling_rate, channels, error)==NULL)
1923 {
1924 celt_decoder_destroy(st);
1925 st = NULL;
1926 }
1927 return st;
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -04001928}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001929
Jean-Marc Valinc97b2582011-01-28 23:07:32 -05001930CELTDecoder *celt_decoder_create_custom(const CELTMode *mode, int channels, int *error)
1931{
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05001932 CELTDecoder *st = (CELTDecoder *)celt_alloc(celt_decoder_get_size_custom(mode, channels));
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -05001933 if (st!=NULL && celt_decoder_init_custom(st, mode, channels, error)==NULL)
1934 {
1935 celt_decoder_destroy(st);
1936 st = NULL;
1937 }
1938 return st;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11001939}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001940
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001941CELTDecoder *celt_decoder_init(CELTDecoder *st, int sampling_rate, int channels, int *error)
Jean-Marc Valinc97b2582011-01-28 23:07:32 -05001942{
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001943 celt_decoder_init_custom(st, celt_mode_create(48000, 960, NULL), channels, error);
1944 st->downsample = resampling_factor(sampling_rate);
1945 if (st->downsample==0)
1946 {
1947 if (error)
1948 *error = CELT_BAD_ARG;
1949 return NULL;
1950 }
1951 return st;
Jean-Marc Valinc97b2582011-01-28 23:07:32 -05001952}
1953
1954CELTDecoder *celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int channels, int *error)
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -04001955{
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001956 if (channels < 0 || channels > 2)
1957 {
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001958 if (error)
1959 *error = CELT_BAD_ARG;
1960 return NULL;
1961 }
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001962
Gregory Maxwell17169992009-06-04 15:15:34 -04001963 if (st==NULL)
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001964 {
1965 if (error)
1966 *error = CELT_ALLOC_FAIL;
Gregory Maxwell17169992009-06-04 15:15:34 -04001967 return NULL;
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001968 }
1969
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05001970 CELT_MEMSET((char*)st, 0, celt_decoder_get_size_custom(mode, channels));
Jean-Marc Valin6d3829f2010-08-27 17:52:38 -04001971
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001972 st->mode = mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001973 st->overlap = mode->overlap;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05001974 st->stream_channels = st->channels = channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001975
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001976 st->downsample = 1;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001977 st->start = 0;
Jean-Marc Valin8952c452010-07-16 21:48:44 -04001978 st->end = st->mode->effEBands;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05001979 st->signalling = 1;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001980
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001981 st->loss_count = 0;
Gregory Maxwell17169992009-06-04 15:15:34 -04001982
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001983 if (error)
1984 *error = CELT_OK;
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001985 return st;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001986}
1987
Peter Kirk19f9dc92008-06-06 14:38:38 +02001988void celt_decoder_destroy(CELTDecoder *st)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001989{
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001990 celt_free(st);
1991}
1992
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001993static void celt_decode_lost(CELTDecoder * restrict st, opus_val16 * restrict pcm, int N, int LM)
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001994{
Jean-Marc Valin04752672010-05-05 07:21:21 -04001995 int c;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11001996 int pitch_index;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001997 int overlap = st->mode->overlap;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001998 opus_val16 fade = Q15ONE;
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10001999 int i, len;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04002000 const int C = CHANNELS(st->channels);
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10002001 int offset;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002002 celt_sig *out_mem[2];
2003 celt_sig *decode_mem[2];
2004 celt_sig *overlap_mem[2];
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002005 opus_val16 *lpc;
2006 opus_val32 *out_syn[2];
2007 opus_val16 *oldBandE, *oldLogE2, *backgroundLogE;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002008 int plc=1;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11002009 SAVE_STACK;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002010
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002011 c=0; do {
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002012 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
2013 out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
2014 overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002015 } while (++c<C);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002016 lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C);
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002017 oldBandE = lpc+C*LPC_ORDER;
2018 oldLogE2 = oldBandE + C*st->mode->nbEBands;
2019 backgroundLogE = oldLogE2 + C*st->mode->nbEBands;
2020
2021 out_syn[0] = out_mem[0]+MAX_PERIOD-N;
2022 if (C==2)
2023 out_syn[1] = out_mem[1]+MAX_PERIOD-N;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002024
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10002025 len = N+st->mode->overlap;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002026
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002027 if (st->loss_count >= 5)
2028 {
2029 VARDECL(celt_sig, freq);
2030 VARDECL(celt_norm, X);
2031 VARDECL(celt_ener, bandE);
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002032 opus_uint32 seed;
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002033 int effEnd;
2034
2035 effEnd = st->end;
2036 if (effEnd > st->mode->effEBands)
2037 effEnd = st->mode->effEBands;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002038
2039 ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
2040 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
2041 ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
2042
2043 log2Amp(st->mode, st->start, st->end, bandE, backgroundLogE, C);
2044
2045 seed = st->rng;
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002046 for (c=0;c<C;c++)
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002047 {
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002048 for (i=0;i<(st->mode->eBands[st->start]<<LM);i++)
2049 X[c*N+i] = 0;
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002050 for (i=0;i<st->mode->effEBands;i++)
2051 {
2052 int j;
2053 int boffs;
2054 int blen;
2055 boffs = N*c+(st->mode->eBands[i]<<LM);
2056 blen = (st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
2057 for (j=0;j<blen;j++)
2058 {
2059 seed = lcg_rand(seed);
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002060 X[boffs+j] = (opus_int32)(seed)>>20;
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002061 }
2062 renormalise_vector(X+boffs, blen, Q15ONE);
2063 }
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002064 for (i=(st->mode->eBands[st->end]<<LM);i<N;i++)
2065 X[c*N+i] = 0;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002066 }
2067 st->rng = seed;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002068
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002069 denormalise_bands(st->mode, X, freq, bandE, st->mode->effEBands, C, 1<<LM);
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002070
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002071 c=0; do
2072 for (i=0;i<st->mode->eBands[st->start]<<LM;i++)
2073 freq[c*N+i] = 0;
2074 while (++c<C);
2075 c=0; do {
2076 int bound = st->mode->eBands[effEnd]<<LM;
2077 if (st->downsample!=1)
2078 bound = IMIN(bound, N/st->downsample);
2079 for (i=bound;i<N;i++)
2080 freq[c*N+i] = 0;
2081 } while (++c<C);
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002082 compute_inv_mdcts(st->mode, 0, freq, out_syn, overlap_mem, C, LM);
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002083 plc = 0;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002084 } else if (st->loss_count == 0)
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04002085 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002086 opus_val16 pitch_buf[DECODE_BUFFER_SIZE>>1];
Jean-Marc Valin5f3d1af2011-05-13 17:24:25 -04002087 /* Corresponds to a min pitch of 67 Hz. It's possible to save CPU in this
2088 search by using only part of the decode buffer */
2089 int poffset = 720;
2090 pitch_downsample(decode_mem, pitch_buf, DECODE_BUFFER_SIZE, C);
2091 /* Max pitch is 100 samples (480 Hz) */
2092 pitch_search(pitch_buf+((poffset)>>1), pitch_buf, DECODE_BUFFER_SIZE-poffset,
2093 poffset-100, &pitch_index);
2094 pitch_index = poffset-pitch_index;
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04002095 st->last_pitch_index = pitch_index;
2096 } else {
2097 pitch_index = st->last_pitch_index;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002098 fade = QCONST16(.8f,15);
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04002099 }
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002100
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002101 if (plc)
2102 {
2103 c=0; do {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002104 VARDECL(opus_val32, e);
2105 opus_val16 exc[MAX_PERIOD];
2106 opus_val32 ac[LPC_ORDER+1];
2107 opus_val16 decay = 1;
2108 opus_val32 S1=0;
Gregory Maxwell06d57b22011-08-01 22:02:25 -04002109 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 -05002110
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002111 ALLOC(e, MAX_PERIOD+2*st->mode->overlap, opus_val32);
Jean-Marc Valinf54a0a32011-05-13 17:36:31 -04002112
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002113 offset = MAX_PERIOD-pitch_index;
2114 for (i=0;i<MAX_PERIOD;i++)
2115 exc[i] = ROUND16(out_mem[c][i], SIG_SHIFT);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05002116
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002117 if (st->loss_count == 0)
2118 {
2119 _celt_autocorr(exc, ac, st->mode->window, st->mode->overlap,
2120 LPC_ORDER, MAX_PERIOD);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05002121
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002122 /* Noise floor -40 dB */
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002123#ifdef FIXED_POINT
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002124 ac[0] += SHR32(ac[0],13);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002125#else
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002126 ac[0] *= 1.0001f;
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002127#endif
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002128 /* Lag windowing */
2129 for (i=1;i<=LPC_ORDER;i++)
2130 {
2131 /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002132#ifdef FIXED_POINT
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002133 ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002134#else
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002135 ac[i] -= ac[i]*(.008f*i)*(.008f*i);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002136#endif
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002137 }
2138
2139 _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
2140 }
2141 for (i=0;i<LPC_ORDER;i++)
2142 mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
2143 fir(exc, lpc+c*LPC_ORDER, exc, MAX_PERIOD, LPC_ORDER, mem);
2144 /*for (i=0;i<MAX_PERIOD;i++)printf("%d ", exc[i]); printf("\n");*/
2145 /* Check if the waveform is decaying (and if so how fast) */
2146 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002147 opus_val32 E1=1, E2=1;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002148 int period;
2149 if (pitch_index <= MAX_PERIOD/2)
2150 period = pitch_index;
2151 else
2152 period = MAX_PERIOD/2;
2153 for (i=0;i<period;i++)
2154 {
2155 E1 += SHR32(MULT16_16(exc[MAX_PERIOD-period+i],exc[MAX_PERIOD-period+i]),8);
2156 E2 += SHR32(MULT16_16(exc[MAX_PERIOD-2*period+i],exc[MAX_PERIOD-2*period+i]),8);
2157 }
2158 if (E1 > E2)
2159 E1 = E2;
2160 decay = celt_sqrt(frac_div32(SHR(E1,1),E2));
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05002161 }
2162
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002163 /* Copy excitation, taking decay into account */
2164 for (i=0;i<len+st->mode->overlap;i++)
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002165 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002166 opus_val16 tmp;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002167 if (offset+i >= MAX_PERIOD)
2168 {
2169 offset -= pitch_index;
2170 decay = MULT16_16_Q15(decay, decay);
2171 }
2172 e[i] = SHL32(EXTEND32(MULT16_16_Q15(decay, exc[offset+i])), SIG_SHIFT);
2173 tmp = ROUND16(out_mem[c][offset+i],SIG_SHIFT);
2174 S1 += SHR32(MULT16_16(tmp,tmp),8);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002175 }
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002176 for (i=0;i<LPC_ORDER;i++)
2177 mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
2178 for (i=0;i<len+st->mode->overlap;i++)
2179 e[i] = MULT16_32_Q15(fade, e[i]);
2180 iir(e, lpc+c*LPC_ORDER, e, len+st->mode->overlap, LPC_ORDER, mem);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002181
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002182 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002183 opus_val32 S2=0;
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05002184 for (i=0;i<len+overlap;i++)
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002185 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002186 opus_val16 tmp = ROUND16(e[i],SIG_SHIFT);
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002187 S2 += SHR32(MULT16_16(tmp,tmp),8);
2188 }
2189 /* This checks for an "explosion" in the synthesis */
2190#ifdef FIXED_POINT
2191 if (!(S1 > SHR32(S2,2)))
2192#else
2193 /* Float test is written this way to catch NaNs at the same time */
2194 if (!(S1 > 0.2f*S2))
2195#endif
2196 {
2197 for (i=0;i<len+overlap;i++)
2198 e[i] = 0;
2199 } else if (S1 < S2)
2200 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002201 opus_val16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002202 for (i=0;i<len+overlap;i++)
2203 e[i] = MULT16_32_Q15(ratio, e[i]);
2204 }
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05002205 }
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002206
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002207 /* Apply post-filter to the MDCT overlap of the previous frame */
2208 comb_filter(out_mem[c]+MAX_PERIOD, out_mem[c]+MAX_PERIOD, st->postfilter_period, st->postfilter_period, st->overlap,
2209 st->postfilter_gain, st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset,
2210 NULL, 0);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002211
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002212 for (i=0;i<MAX_PERIOD+st->mode->overlap-N;i++)
2213 out_mem[c][i] = out_mem[c][N+i];
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002214
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002215 /* Apply TDAC to the concealed audio so that it blends with the
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002216 previous and next frames */
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002217 for (i=0;i<overlap/2;i++)
2218 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002219 opus_val32 tmp;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002220 tmp = MULT16_32_Q15(st->mode->window[i], e[N+overlap-1-i]) +
2221 MULT16_32_Q15(st->mode->window[overlap-i-1], e[N+i ]);
2222 out_mem[c][MAX_PERIOD+i] = MULT16_32_Q15(st->mode->window[overlap-i-1], tmp);
2223 out_mem[c][MAX_PERIOD+overlap-i-1] = MULT16_32_Q15(st->mode->window[i], tmp);
2224 }
2225 for (i=0;i<N;i++)
2226 out_mem[c][MAX_PERIOD-N+i] = e[i];
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002227
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002228 /* Apply pre-filter to the MDCT overlap for the next frame (post-filter will be applied then) */
2229 comb_filter(e, out_mem[c]+MAX_PERIOD, st->postfilter_period, st->postfilter_period, st->overlap,
2230 -st->postfilter_gain, -st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset,
2231 NULL, 0);
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002232 for (i=0;i<overlap;i++)
2233 out_mem[c][MAX_PERIOD+i] = e[i];
2234 } while (++c<C);
2235 }
Jean-Marc Valin1677aa92007-12-08 01:13:34 +11002236
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002237 deemphasis(out_syn, pcm, N, C, st->downsample, st->mode->preemph, st->preemph_memD);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002238
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04002239 st->loss_count++;
2240
Jean-Marc Valin8600f692008-02-29 15:14:12 +11002241 RESTORE_STACK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002242}
2243
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002244#ifdef FIXED_POINT
Jean-Marc Valin51c78622011-02-03 00:43:37 -05002245CELT_STATIC
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002246int celt_decode_with_ec(CELTDecoder * restrict st, const unsigned char *data, int len, opus_int16 * restrict pcm, int frame_size, ec_dec *dec)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11002247{
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002248#else
Jean-Marc Valin51c78622011-02-03 00:43:37 -05002249CELT_STATIC
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002250int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *data, int len, celt_sig * restrict pcm, int frame_size, ec_dec *dec)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002251{
2252#endif
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -04002253 int c, i, N;
Timothy B. Terriberry320cf2e2010-12-17 05:52:06 -08002254 int spread_decision;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002255 opus_int32 bits;
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002256 ec_dec _dec;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002257 VARDECL(celt_sig, freq);
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002258 VARDECL(celt_norm, X);
2259 VARDECL(celt_ener, bandE);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002260 VARDECL(int, fine_quant);
2261 VARDECL(int, pulses);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002262 VARDECL(int, cap);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002263 VARDECL(int, offsets);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04002264 VARDECL(int, fine_priority);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -04002265 VARDECL(int, tf_res);
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002266 VARDECL(unsigned char, collapse_masks);
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002267 celt_sig *out_mem[2];
2268 celt_sig *decode_mem[2];
2269 celt_sig *overlap_mem[2];
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04002270 celt_sig *out_syn[2];
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002271 opus_val16 *lpc;
2272 opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
Jean-Marc Valinc890b582008-08-01 22:26:49 -04002273
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +10002274 int shortBlocks;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04002275 int isTransient;
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -04002276 int intra_ener;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002277 const int CC = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04002278 int LM, M;
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002279 int effEnd;
Jean-Marc Valinb801da52010-09-28 14:56:20 -04002280 int codedBands;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04002281 int alloc_trim;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002282 int postfilter_pitch;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002283 opus_val16 postfilter_gain;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05002284 int intensity=0;
Jean-Marc Valine65978f2010-12-02 13:46:48 -05002285 int dual_stereo=0;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002286 opus_int32 total_bits;
2287 opus_int32 balance;
2288 opus_int32 tell;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002289 int dynalloc_logp;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002290 int postfilter_tapset;
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002291 int anti_collapse_rsv;
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002292 int anti_collapse_on=0;
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002293 int silence;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002294 int C = CHANNELS(st->stream_channels);
Jean-Marc Valinf62b3bb2011-03-09 11:56:29 -05002295 ALLOC_STACK;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11002296
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002297 frame_size *= st->downsample;
Jean-Marc Valin017fa852010-05-06 22:11:48 -04002298
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002299 c=0; do {
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002300 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
2301 out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
2302 overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002303 } while (++c<CC);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002304 lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*CC);
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002305 oldBandE = lpc+LPC_ORDER;
2306 oldLogE = oldBandE + 2*st->mode->nbEBands;
2307 oldLogE2 = oldLogE + 2*st->mode->nbEBands;
2308 backgroundLogE = oldLogE2 + 2*st->mode->nbEBands;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002309
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002310 if (st->signalling && data!=NULL)
2311 {
Jean-Marc Valind6bf19d2011-03-21 07:06:09 -04002312 int data0=data[0];
2313 /* Convert "standard mode" to Opus header */
2314 if (st->mode->Fs==48000 && st->mode->shortMdctSize==120)
2315 {
2316 data0 = fromOpus(data0);
2317 if (data0<0)
2318 return CELT_CORRUPTED_DATA;
2319 }
2320 st->end = IMAX(1, st->mode->effEBands-2*(data0>>5));
2321 LM = (data0>>3)&0x3;
2322 C = 1 + ((data0>>2)&0x1);
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002323 data++;
2324 len--;
2325 if (LM>st->mode->maxLM)
2326 return CELT_CORRUPTED_DATA;
2327 if (frame_size < st->mode->shortMdctSize<<LM)
Jean-Marc Valinef20e392011-03-18 15:34:11 -04002328 return CELT_BUFFER_TOO_SMALL;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002329 else
2330 frame_size = st->mode->shortMdctSize<<LM;
2331 } else {
2332 for (LM=0;LM<=st->mode->maxLM;LM++)
2333 if (st->mode->shortMdctSize<<LM==frame_size)
2334 break;
2335 if (LM>st->mode->maxLM)
2336 return CELT_BAD_ARG;
2337 }
2338 M=1<<LM;
2339
2340 if (len<0 || len>1275 || pcm==NULL)
2341 return CELT_BAD_ARG;
2342
Jean-Marc Valin04752672010-05-05 07:21:21 -04002343 N = M*st->mode->shortMdctSize;
Jean-Marc Valin01417232008-03-03 13:59:55 +11002344
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002345 effEnd = st->end;
2346 if (effEnd > st->mode->effEBands)
2347 effEnd = st->mode->effEBands;
2348
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002349 ALLOC(freq, IMAX(CC,C)*N, celt_sig); /**< Interleaved signal MDCTs */
2350 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
2351 ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002352 c=0; do
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002353 for (i=0;i<M*st->mode->eBands[st->start];i++)
2354 X[c*N+i] = 0;
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002355 while (++c<C);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002356 c=0; do
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002357 for (i=M*st->mode->eBands[effEnd];i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002358 X[c*N+i] = 0;
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002359 while (++c<C);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002360
Jean-Marc Valin65d35a32011-01-26 22:04:59 -05002361 if (data == NULL || len<=1)
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002362 {
Jean-Marc Valin017fa852010-05-06 22:11:48 -04002363 celt_decode_lost(st, pcm, N, LM);
Jean-Marc Valin8600f692008-02-29 15:14:12 +11002364 RESTORE_STACK;
Jean-Marc Valin37e788c2011-03-16 20:56:28 -04002365 return frame_size/st->downsample;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002366 }
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002367
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002368 if (dec == NULL)
2369 {
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002370 ec_dec_init(&_dec,(unsigned char*)data,len);
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002371 dec = &_dec;
2372 }
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04002373
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002374 if (C<CC)
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002375 {
2376 for (i=0;i<st->mode->nbEBands;i++)
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002377 oldBandE[i]=MAX16(oldBandE[i],oldBandE[st->mode->nbEBands+i]);
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002378 }
2379
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002380 total_bits = len*8;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002381 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002382
Jean-Marc Valina0653ed2011-07-05 13:18:59 -04002383 if (tell >= total_bits)
2384 silence = 1;
2385 else if (tell==1)
Jean-Marc Valin65d35a32011-01-26 22:04:59 -05002386 silence = ec_dec_bit_logp(dec, 15);
2387 else
2388 silence = 0;
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002389 if (silence)
2390 {
Jean-Marc Valin13a7c262011-01-26 10:58:33 -05002391 /* Pretend we've read all the remaining bits */
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002392 tell = len*8;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002393 dec->nbits_total+=tell-ec_tell(dec);
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002394 }
2395
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002396 postfilter_gain = 0;
2397 postfilter_pitch = 0;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002398 postfilter_tapset = 0;
Jean-Marc Valinef986e42011-02-03 15:47:10 -05002399 if (st->start==0 && tell+16 <= total_bits)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002400 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002401 if(ec_dec_bit_logp(dec, 1))
2402 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002403 int qg, octave;
2404 octave = ec_dec_uint(dec, 6);
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002405 postfilter_pitch = (16<<octave)+ec_dec_bits(dec, 4+octave)-1;
Jean-Marc Valinef986e42011-02-03 15:47:10 -05002406 qg = ec_dec_bits(dec, 3);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002407 if (ec_tell(dec)+2<=total_bits)
Jean-Marc Valinef986e42011-02-03 15:47:10 -05002408 postfilter_tapset = ec_dec_icdf(dec, tapset_icdf, 2);
2409 postfilter_gain = QCONST16(.09375f,15)*(qg+1);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002410 }
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002411 tell = ec_tell(dec);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002412 }
2413
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002414 if (LM > 0 && tell+3 <= total_bits)
2415 {
Timothy B. Terriberrye86fb262010-12-17 14:50:19 -08002416 isTransient = ec_dec_bit_logp(dec, 3);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002417 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002418 }
Jean-Marc Valinf9fdbff2010-09-05 21:02:38 -04002419 else
2420 isTransient = 0;
Jean-Marc Valin017001a2010-08-05 15:42:50 -04002421
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04002422 if (isTransient)
2423 shortBlocks = M;
2424 else
2425 shortBlocks = 0;
2426
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002427 /* Decode the global flags (first symbols in the stream) */
2428 intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0;
2429 /* Get band energies */
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05002430 unquant_coarse_energy(st->mode, st->start, st->end, oldBandE,
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002431 intra_ener, dec, C, LM);
2432
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04002433 ALLOC(tf_res, st->mode->nbEBands, int);
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05002434 tf_decode(st->start, st->end, isTransient, tf_res, LM, dec);
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04002435
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002436 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002437 spread_decision = SPREAD_NORMAL;
2438 if (tell+4 <= total_bits)
2439 spread_decision = ec_dec_icdf(dec, spread_icdf, 5);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04002440
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002441 ALLOC(pulses, st->mode->nbEBands, int);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002442 ALLOC(cap, st->mode->nbEBands, int);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002443 ALLOC(offsets, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04002444 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002445
Timothy B. Terriberryce6d0902011-02-01 17:41:12 -08002446 init_caps(st->mode,cap,LM,C);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002447
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002448 dynalloc_logp = 6;
2449 total_bits<<=BITRES;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002450 tell = ec_tell_frac(dec);
Timothy B. Terriberryd6f61572010-12-30 09:04:16 -08002451 for (i=st->start;i<st->end;i++)
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002452 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002453 int width, quanta;
2454 int dynalloc_loop_logp;
2455 int boost;
2456 width = C*(st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
2457 /* quanta is 6 bits, but no more than 1 bit/sample
2458 and no less than 1/8 bit/sample */
2459 quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));
2460 dynalloc_loop_logp = dynalloc_logp;
2461 boost = 0;
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002462 while (tell+(dynalloc_loop_logp<<BITRES) < total_bits && boost < cap[i])
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002463 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002464 int flag;
2465 flag = ec_dec_bit_logp(dec, dynalloc_loop_logp);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002466 tell = ec_tell_frac(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002467 if (!flag)
2468 break;
2469 boost += quanta;
2470 total_bits -= quanta;
2471 dynalloc_loop_logp = 1;
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002472 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002473 offsets[i] = boost;
2474 /* Making dynalloc more likely */
2475 if (boost>0)
2476 dynalloc_logp = IMAX(2, dynalloc_logp-1);
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002477 }
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002478
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04002479 ALLOC(fine_quant, st->mode->nbEBands, int);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002480 alloc_trim = tell+(6<<BITRES) <= total_bits ?
2481 ec_dec_icdf(dec, trim_icdf, 7) : 5;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05002482
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002483 bits = ((opus_int32)len*8<<BITRES) - ec_tell_frac(dec) - 1;
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002484 anti_collapse_rsv = isTransient&&LM>=2&&bits>=(LM+2<<BITRES) ? (1<<BITRES) : 0;
2485 bits -= anti_collapse_rsv;
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002486 codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08002487 alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
2488 fine_quant, fine_priority, C, LM, dec, 0, 0);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002489
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05002490 unquant_fine_energy(st->mode, st->start, st->end, oldBandE, fine_quant, dec, C);
Jean-Marc Valin827f9312008-05-06 23:21:55 +10002491
Jean-Marc Valin8cbea172010-08-05 15:22:57 -04002492 /* Decode fixed codebook */
Jean-Marc Valin7e983192011-02-01 18:00:29 -05002493 ALLOC(collapse_masks, C*st->mode->nbEBands, unsigned char);
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002494 quant_all_bands(0, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks,
Timothy B. Terriberry320cf2e2010-12-17 05:52:06 -08002495 NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res, 1,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08002496 len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng);
Jean-Marc Valin746b2a82010-05-14 22:12:33 -04002497
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002498 if (anti_collapse_rsv > 0)
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002499 {
2500 anti_collapse_on = ec_dec_bits(dec, 1);
2501 }
2502
Jean-Marc Valine3e2c262011-01-26 13:09:53 -05002503 unquant_energy_finalise(st->mode, st->start, st->end, oldBandE,
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002504 fine_quant, fine_priority, len*8-ec_tell(dec), dec, C);
Jean-Marc Valin30d51252010-06-21 17:55:28 -04002505
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002506 if (anti_collapse_on)
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002507 anti_collapse(st->mode, X, collapse_masks, LM, C, C, N,
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05002508 st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002509
Jean-Marc Valin02a35272010-08-27 16:00:01 -04002510 log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04002511
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002512 if (silence)
2513 {
2514 for (i=0;i<C*st->mode->nbEBands;i++)
2515 {
2516 bandE[i] = 0;
Gregory Maxwell8b631f22011-01-26 20:19:01 -05002517 oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002518 }
2519 }
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11002520 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002521 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11002522
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002523 CELT_MOVE(decode_mem[0], decode_mem[0]+N, DECODE_BUFFER_SIZE-N);
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002524 if (CC==2)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002525 CELT_MOVE(decode_mem[1], decode_mem[1]+N, DECODE_BUFFER_SIZE-N);
Jean-Marc Valin88619552009-10-04 21:35:36 -04002526
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002527 c=0; do
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002528 for (i=0;i<M*st->mode->eBands[st->start];i++)
2529 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002530 while (++c<C);
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002531 c=0; do {
2532 int bound = M*st->mode->eBands[effEnd];
2533 if (st->downsample!=1)
2534 bound = IMIN(bound, N/st->downsample);
Jean-Marc Valin23340e22011-02-03 23:21:00 -05002535 for (i=bound;i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002536 freq[c*N+i] = 0;
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002537 } while (++c<C);
Jean-Marc Valin3a0bc3d2010-02-21 15:10:22 -05002538
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002539 out_syn[0] = out_mem[0]+MAX_PERIOD-N;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002540 if (CC==2)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002541 out_syn[1] = out_mem[1]+MAX_PERIOD-N;
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04002542
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002543 if (CC==2&&C==1)
2544 {
2545 for (i=0;i<N;i++)
2546 freq[N+i] = freq[i];
2547 }
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002548 if (CC==1&&C==2)
2549 {
2550 for (i=0;i<N;i++)
2551 freq[i] = HALF32(ADD32(freq[i],freq[N+i]));
2552 }
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002553
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11002554 /* Compute inverse MDCTs */
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002555 compute_inv_mdcts(st->mode, shortBlocks, freq, out_syn, overlap_mem, CC, LM);
Jean-Marc Valinffa13472007-12-10 16:54:17 +11002556
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002557 c=0; do {
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05002558 st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD);
2559 st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD);
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05002560 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 -05002561 st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset,
2562 st->mode->window, st->overlap);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05002563 if (LM!=0)
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05002564 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 -05002565 st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset,
2566 st->mode->window, st->mode->overlap);
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05002567
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002568 } while (++c<CC);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05002569 st->postfilter_period_old = st->postfilter_period;
2570 st->postfilter_gain_old = st->postfilter_gain;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002571 st->postfilter_tapset_old = st->postfilter_tapset;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002572 st->postfilter_period = postfilter_pitch;
2573 st->postfilter_gain = postfilter_gain;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002574 st->postfilter_tapset = postfilter_tapset;
Jean-Marc Valina14e86d2011-02-11 16:27:27 -05002575 if (LM!=0)
2576 {
2577 st->postfilter_period_old = st->postfilter_period;
2578 st->postfilter_gain_old = st->postfilter_gain;
2579 st->postfilter_tapset_old = st->postfilter_tapset;
2580 }
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002581
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002582 if (C==1) {
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002583 for (i=0;i<st->mode->nbEBands;i++)
2584 oldBandE[st->mode->nbEBands+i]=oldBandE[i];
2585 }
2586
Jean-Marc Valin5677e342011-01-13 16:15:53 -05002587 /* In case start or end were to change */
Jean-Marc Valin5c2ac2b2011-01-22 14:48:20 -05002588 c=0; do
2589 {
2590 for (i=0;i<st->start;i++)
2591 oldBandE[c*st->mode->nbEBands+i]=0;
2592 for (i=st->end;i<st->mode->nbEBands;i++)
2593 oldBandE[c*st->mode->nbEBands+i]=0;
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002594 } while (++c<2);
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002595 if (!isTransient)
2596 {
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002597 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002598 oldLogE2[i] = oldLogE[i];
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002599 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002600 oldLogE[i] = oldBandE[i];
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002601 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002602 backgroundLogE[i] = MIN16(backgroundLogE[i] + M*QCONST16(0.001f,DB_SHIFT), oldBandE[i]);
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05002603 } else {
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002604 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05002605 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002606 }
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05002607 st->rng = dec->rng;
Jean-Marc Valin5677e342011-01-13 16:15:53 -05002608
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002609 deemphasis(out_syn, pcm, N, CC, st->downsample, st->mode->preemph, st->preemph_memD);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002610 st->loss_count = 0;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11002611 RESTORE_STACK;
Jean-Marc Valinef20e392011-03-18 15:34:11 -04002612 if (ec_tell(dec) > 8*len)
2613 return CELT_INTERNAL_ERROR;
2614 if(ec_get_error(dec))
2615 st->error = 1;
2616 return frame_size/st->downsample;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11002617}
2618
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002619#ifdef FIXED_POINT
2620#ifndef DISABLE_FLOAT_API
Jean-Marc Valin51c78622011-02-03 00:43:37 -05002621CELT_STATIC
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002622int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size, ec_dec *dec)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002623{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002624 int j, ret, C, N;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002625 VARDECL(opus_int16, out);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05002626 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04002627
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04002628 if (pcm==NULL)
2629 return CELT_BAD_ARG;
2630
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04002631 C = CHANNELS(st->channels);
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002632 N = frame_size;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002633
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002634 ALLOC(out, C*N, opus_int16);
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002635 ret=celt_decode_with_ec(st, data, len, out, frame_size, dec);
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002636 if (ret>0)
2637 for (j=0;j<C*ret;j++)
Jean-Marc Valinae01e112010-08-03 21:43:41 -04002638 pcm[j]=out[j]*(1.f/32768.f);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002639
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04002640 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002641 return ret;
2642}
2643#endif /*DISABLE_FLOAT_API*/
2644#else
Jean-Marc Valin51c78622011-02-03 00:43:37 -05002645CELT_STATIC
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002646int celt_decode_with_ec(CELTDecoder * restrict st, const unsigned char *data, int len, opus_int16 * restrict pcm, int frame_size, ec_dec *dec)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002647{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002648 int j, ret, C, N;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002649 VARDECL(celt_sig, out);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05002650 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04002651
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04002652 if (pcm==NULL)
2653 return CELT_BAD_ARG;
2654
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04002655 C = CHANNELS(st->channels);
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002656 N = frame_size;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002657 ALLOC(out, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002658
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002659 ret=celt_decode_with_ec_float(st, data, len, out, frame_size, dec);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002660
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002661 if (ret>0)
2662 for (j=0;j<C*ret;j++)
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04002663 pcm[j] = FLOAT2INT16 (out[j]);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002664
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04002665 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002666 return ret;
2667}
2668#endif
John Ridges454d1d02009-05-21 22:38:39 -04002669
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002670int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, opus_int16 * restrict pcm, int frame_size)
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002671{
2672 return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL);
2673}
2674
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04002675#ifndef DISABLE_FLOAT_API
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002676int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size)
2677{
2678 return celt_decode_with_ec_float(st, data, len, pcm, frame_size, NULL);
2679}
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04002680#endif /* DISABLE_FLOAT_API */
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002681
John Ridges454d1d02009-05-21 22:38:39 -04002682int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
2683{
2684 va_list ap;
Gregory Maxwell17169992009-06-04 15:15:34 -04002685
John Ridges454d1d02009-05-21 22:38:39 -04002686 va_start(ap, request);
2687 switch (request)
2688 {
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002689 case CELT_SET_START_BAND_REQUEST:
2690 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002691 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002692 if (value<0 || value>=st->mode->nbEBands)
2693 goto bad_arg;
2694 st->start = value;
2695 }
2696 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002697 case CELT_SET_END_BAND_REQUEST:
2698 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002699 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwell1928f8d2011-02-08 22:32:56 -05002700 if (value<1 || value>st->mode->nbEBands)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002701 goto bad_arg;
2702 st->end = value;
2703 }
2704 break;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002705 case CELT_SET_CHANNELS_REQUEST:
2706 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002707 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002708 if (value<1 || value>2)
2709 goto bad_arg;
2710 st->stream_channels = value;
2711 }
Jean-Marc Valindd2973d2011-03-11 17:46:02 -05002712 break;
Jean-Marc Valinef20e392011-03-18 15:34:11 -04002713 case CELT_GET_AND_CLEAR_ERROR_REQUEST:
2714 {
2715 int *value = va_arg(ap, int*);
2716 if (value==NULL)
2717 goto bad_arg;
2718 *value=st->error;
2719 st->error = 0;
2720 }
2721 break;
Jean-Marc Valinff96b162011-03-21 11:32:50 -04002722 case CELT_GET_LOOKAHEAD_REQUEST:
2723 {
2724 int *value = va_arg(ap, int*);
2725 if (value==NULL)
2726 goto bad_arg;
2727 *value = st->overlap/st->downsample;
2728 }
2729 break;
John Ridges454d1d02009-05-21 22:38:39 -04002730 case CELT_RESET_STATE:
2731 {
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04002732 CELT_MEMSET((char*)&st->DECODER_RESET_START, 0,
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05002733 celt_decoder_get_size_custom(st->mode, st->channels)-
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04002734 ((char*)&st->DECODER_RESET_START - (char*)st));
John Ridges454d1d02009-05-21 22:38:39 -04002735 }
2736 break;
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04002737#ifdef OPUS_BUILD
2738 case CELT_GET_MODE_REQUEST:
2739 {
2740 const CELTMode ** value = va_arg(ap, const CELTMode**);
2741 if (value==0)
2742 goto bad_arg;
2743 *value=st->mode;
2744 }
2745 break;
2746 case CELT_SET_SIGNALLING_REQUEST:
2747 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002748 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04002749 st->signalling = value;
2750 }
2751 break;
2752#endif
John Ridges454d1d02009-05-21 22:38:39 -04002753 default:
2754 goto bad_request;
2755 }
2756 va_end(ap);
2757 return CELT_OK;
John Ridges454d1d02009-05-21 22:38:39 -04002758bad_arg:
2759 va_end(ap);
2760 return CELT_BAD_ARG;
John Ridges454d1d02009-05-21 22:38:39 -04002761bad_request:
2762 va_end(ap);
2763 return CELT_UNIMPLEMENTED;
2764}
Jean-Marc Valinece94a02009-10-16 07:30:14 -04002765
2766const char *celt_strerror(int error)
2767{
2768 static const char *error_strings[8] = {
2769 "success",
2770 "invalid argument",
Jean-Marc Valinc5f99902011-03-18 15:47:53 -04002771 "buffer too small",
Jean-Marc Valinece94a02009-10-16 07:30:14 -04002772 "internal error",
2773 "corrupted stream",
2774 "request not implemented",
2775 "invalid state",
2776 "memory allocation failed"
2777 };
2778 if (error > 0 || error < -7)
2779 return "unknown error";
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002780 else
Jean-Marc Valinece94a02009-10-16 07:30:14 -04002781 return error_strings[-error];
2782}