blob: 5e962e36ded4ee2e9490c339b83f17a523224513 [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
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400585static int tf_analysis(const CELTMode *m, opus_val16 *bandLogE, opus_val16 *oldBandE,
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400586 int len, int C, int isTransient, int *tf_res, int nbCompressedBytes, celt_norm *X,
587 int N0, int LM, 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 Maxwell9743bf32010-11-04 20:45:09 -0400842 } while (++c<0);
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
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001183 qg = floor(.5+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);
1280 /* Needs to be before coarse energy quantization because otherwise the energy gets modified */
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001281 tf_select = tf_analysis(st->mode, bandLogE, oldBandE, effEnd, C, isTransient, tf_res, effectiveBytes, X, N, LM, &tf_sum);
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -04001282 for (i=effEnd;i<st->end;i++)
1283 tf_res[i] = tf_res[effEnd-1];
1284
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001285 ALLOC(error, C*st->mode->nbEBands, opus_val16);
Jean-Marc Valin5e7f02d2010-08-08 09:48:22 -04001286 quant_coarse_energy(st->mode, st->start, st->end, effEnd, bandLogE,
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001287 oldBandE, total_bits, error, enc,
Timothy B. Terriberryef2e6502010-11-09 01:43:18 -08001288 C, LM, nbAvailableBytes, st->force_intra,
Jean-Marc Valineda2dee2011-04-21 16:04:27 -04001289 &st->delayedIntra, st->complexity >= 4, st->loss_rate);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001290
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001291 tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc);
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001292
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001293 st->spread_decision = SPREAD_NORMAL;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001294 if (ec_tell(enc)+4<=total_bits)
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -04001295 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001296 if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C)
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001297 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001298 if (st->complexity == 0)
1299 st->spread_decision = SPREAD_NONE;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001300 } else {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001301 st->spread_decision = spreading_decision(st->mode, X,
Jean-Marc Valin8d367022011-01-17 16:37:51 -05001302 &st->tonal_average, st->spread_decision, &st->hf_average,
1303 &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M);
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001304 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001305 ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5);
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -04001306 }
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001307
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001308 ALLOC(cap, st->mode->nbEBands, int);
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001309 ALLOC(offsets, st->mode->nbEBands, int);
1310
Timothy B. Terriberryce6d0902011-02-01 17:41:12 -08001311 init_caps(st->mode,cap,LM,C);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001312 for (i=0;i<st->mode->nbEBands;i++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001313 offsets[i] = 0;
1314 /* Dynamic allocation code */
1315 /* Make sure that dynamic allocation can't make us bust the budget */
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001316 if (effectiveBytes > 50 && LM>=1)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001317 {
1318 int t1, t2;
1319 if (LM <= 1)
1320 {
1321 t1 = 3;
1322 t2 = 5;
1323 } else {
1324 t1 = 2;
1325 t2 = 4;
1326 }
Gregory Maxwell7007f1b2011-02-08 16:17:47 -05001327 for (i=st->start+1;i<st->end-1;i++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001328 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001329 opus_val32 d2;
Jean-Marc Valina3a066c2010-11-04 15:15:54 -04001330 d2 = 2*bandLogE[i]-bandLogE[i-1]-bandLogE[i+1];
1331 if (C==2)
1332 d2 = HALF32(d2 + 2*bandLogE[i+st->mode->nbEBands]-
1333 bandLogE[i-1+st->mode->nbEBands]-bandLogE[i+1+st->mode->nbEBands]);
1334 if (d2 > SHL16(t1,DB_SHIFT))
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001335 offsets[i] += 1;
Jean-Marc Valina3a066c2010-11-04 15:15:54 -04001336 if (d2 > SHL16(t2,DB_SHIFT))
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001337 offsets[i] += 1;
1338 }
1339 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001340 dynalloc_logp = 6;
1341 total_bits<<=BITRES;
1342 total_boost = 0;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001343 tell = ec_tell_frac(enc);
Timothy B. Terriberryd6f61572010-12-30 09:04:16 -08001344 for (i=st->start;i<st->end;i++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001345 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001346 int width, quanta;
1347 int dynalloc_loop_logp;
1348 int boost;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001349 int j;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001350 width = C*(st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
1351 /* quanta is 6 bits, but no more than 1 bit/sample
1352 and no less than 1/8 bit/sample */
1353 quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));
1354 dynalloc_loop_logp = dynalloc_logp;
1355 boost = 0;
1356 for (j = 0; tell+(dynalloc_loop_logp<<BITRES) < total_bits-total_boost
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001357 && boost < cap[i]; j++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001358 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001359 int flag;
1360 flag = j<offsets[i];
1361 ec_enc_bit_logp(enc, flag, dynalloc_loop_logp);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001362 tell = ec_tell_frac(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001363 if (!flag)
1364 break;
1365 boost += quanta;
1366 total_boost += quanta;
1367 dynalloc_loop_logp = 1;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001368 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001369 /* Making dynalloc more likely */
1370 if (j)
1371 dynalloc_logp = IMAX(2, dynalloc_logp-1);
1372 offsets[i] = boost;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001373 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001374 alloc_trim = 5;
1375 if (tell+(6<<BITRES) <= total_bits - total_boost)
1376 {
1377 alloc_trim = alloc_trim_analysis(st->mode, X, bandLogE,
Gregory Maxwell7007f1b2011-02-08 16:17:47 -05001378 st->end, LM, C, N);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001379 ec_enc_icdf(enc, alloc_trim, trim_icdf, 7);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001380 tell = ec_tell_frac(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001381 }
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001382
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001383 /* Variable bitrate */
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001384 if (vbr_rate>0)
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001385 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001386 opus_val16 alpha;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001387 opus_int32 delta;
Gregory Maxwella9411472010-10-28 03:52:21 -04001388 /* The target rate in 8th bits per frame */
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001389 opus_int32 target;
1390 opus_int32 min_allowed;
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001391
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001392 target = vbr_rate + st->vbr_offset - ((40*C+20)<<BITRES);
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001393
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001394 /* Shortblocks get a large boost in bitrate, but since they
Jean-Marc Valinccd5a612010-10-13 01:11:55 -04001395 are uncommon long blocks are not greatly affected */
1396 if (shortBlocks || tf_sum < -2*(st->end-st->start))
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001397 target = 7*target/4;
Jean-Marc Valinccd5a612010-10-13 01:11:55 -04001398 else if (tf_sum < -(st->end-st->start))
1399 target = 3*target/2;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001400 else if (M > 1)
Jean-Marc Valinccd5a612010-10-13 01:11:55 -04001401 target-=(target+14)/28;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001402
Gregory Maxwella9411472010-10-28 03:52:21 -04001403 /* The current offset is removed from the target and the space used
1404 so far is added*/
Jean-Marc Valina4badac2010-12-03 15:20:11 -05001405 target=target+tell;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001406
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001407 /* In VBR mode the frame size must not be reduced so much that it would
1408 result in the encoder running out of bits.
1409 The margin of 2 bytes ensures that none of the bust-prevention logic
1410 in the decoder will have triggered so far. */
1411 min_allowed = (tell+total_boost+(1<<BITRES+3)-1>>(BITRES+3)) + 2 - nbFilledBytes;
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001412
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001413 nbAvailableBytes = target+(1<<(BITRES+2))>>(BITRES+3);
Gregory Maxwelld85018c2011-01-13 14:38:24 -05001414 nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes);
1415 nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes) - nbFilledBytes;
Jean-Marc Valin6b565262011-01-12 11:27:03 -05001416
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001417 /* By how much did we "miss" the target on that frame */
1418 delta = target - vbr_rate;
1419
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001420 target=nbAvailableBytes<<(BITRES+3);
1421
Gregory Maxwellfdd86752011-04-13 17:08:22 -04001422 /*If the frame is silent we don't adjust our drift, otherwise
1423 the encoder will shoot to very high rates after hitting a
1424 span of silence, but we do allow the bitres to refill.
1425 This means that we'll undershoot our target in CVBR/VBR modes
1426 on files with lots of silence. */
1427 if(silence)
1428 {
1429 nbAvailableBytes = 2;
1430 target = 2*8<<BITRES;
1431 delta = 0;
1432 }
1433
Gregory Maxwella9411472010-10-28 03:52:21 -04001434 if (st->vbr_count < 970)
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001435 {
1436 st->vbr_count++;
Gregory Maxwella9411472010-10-28 03:52:21 -04001437 alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+20),16));
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001438 } else
1439 alpha = QCONST16(.001f,15);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001440 /* How many bits have we used in excess of what we're allowed */
Jean-Marc Valin9faf7402010-12-04 10:27:22 -05001441 if (st->constrained_vbr)
1442 st->vbr_reservoir += target - vbr_rate;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001443 /*printf ("%d\n", st->vbr_reservoir);*/
1444
1445 /* Compute the offset we need to apply in order to reach the target */
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001446 st->vbr_drift += (opus_int32)MULT16_32_Q15(alpha,delta-st->vbr_offset-st->vbr_drift);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001447 st->vbr_offset = -st->vbr_drift;
1448 /*printf ("%d\n", st->vbr_drift);*/
1449
Jean-Marc Valin9faf7402010-12-04 10:27:22 -05001450 if (st->constrained_vbr && st->vbr_reservoir < 0)
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001451 {
1452 /* We're under the min value -- increase rate */
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001453 int adjust = (-st->vbr_reservoir)/(8<<BITRES);
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001454 /* Unless we're just coding silence */
1455 nbAvailableBytes += silence?0:adjust;
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001456 st->vbr_reservoir = 0;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001457 /*printf ("+%d\n", adjust);*/
1458 }
Gregory Maxwelld85018c2011-01-13 14:38:24 -05001459 nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001460 /* This moves the raw bits to take into account the new compressed size */
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001461 ec_enc_shrink(enc, nbCompressedBytes);
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001462 }
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001463 if (C==2)
1464 {
1465 int effectiveRate;
1466
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001467 /* Always use MS for 2.5 ms frames until we can do a better analysis */
1468 if (LM!=0)
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05001469 dual_stereo = stereo_analysis(st->mode, X, LM, N);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001470
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001471 /* Account for coarse energy */
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001472 effectiveRate = (8*effectiveBytes - 80)>>LM;
1473
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001474 /* effectiveRate in kb/s */
1475 effectiveRate = 2*effectiveRate/5;
1476 if (effectiveRate<35)
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -05001477 intensity = 8;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001478 else if (effectiveRate<50)
1479 intensity = 12;
1480 else if (effectiveRate<68)
1481 intensity = 16;
1482 else if (effectiveRate<84)
1483 intensity = 18;
1484 else if (effectiveRate<102)
1485 intensity = 19;
1486 else if (effectiveRate<130)
1487 intensity = 20;
1488 else
1489 intensity = 100;
1490 intensity = IMIN(st->end,IMAX(st->start, intensity));
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001491 }
1492
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001493 /* Bit allocation */
1494 ALLOC(fine_quant, st->mode->nbEBands, int);
1495 ALLOC(pulses, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04001496 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +11001497
Timothy B. Terriberry285bc372011-02-06 13:29:00 -08001498 /* bits = packet size - where we are - safety*/
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001499 bits = ((opus_int32)nbCompressedBytes*8<<BITRES) - ec_tell_frac(enc) - 1;
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08001500 anti_collapse_rsv = isTransient&&LM>=2&&bits>=(LM+2<<BITRES) ? (1<<BITRES) : 0;
1501 bits -= anti_collapse_rsv;
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001502 codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08001503 alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
1504 fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands);
Jean-Marc Valindfd6e712010-12-09 23:23:34 -05001505 st->lastCodedBands = codedBands;
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -05001506
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05001507 quant_fine_energy(st->mode, st->start, st->end, oldBandE, error, fine_quant, enc, C);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001508
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +02001509#ifdef MEASURE_NORM_MSE
Jean-Marc Valin44092242010-07-29 18:32:54 +02001510 float X0[3000];
1511 float bandE0[60];
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001512 c=0; do
Jean-Marc Valin44092242010-07-29 18:32:54 +02001513 for (i=0;i<N;i++)
1514 X0[i+c*N] = X[i+c*N];
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001515 while (++c<C);
Jean-Marc Valin44092242010-07-29 18:32:54 +02001516 for (i=0;i<C*st->mode->nbEBands;i++)
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +02001517 bandE0[i] = bandE[i];
1518#endif
1519
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11001520 /* Residual quantisation */
Jean-Marc Valin7e983192011-02-01 18:00:29 -05001521 ALLOC(collapse_masks, C*st->mode->nbEBands, unsigned char);
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08001522 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 -08001523 bandE, pulses, shortBlocks, st->spread_decision, dual_stereo, intensity, tf_res, resynth,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08001524 nbCompressedBytes*(8<<BITRES)-anti_collapse_rsv, balance, enc, LM, codedBands, &st->rng);
Jean-Marc Valin39710532009-06-09 00:10:32 -04001525
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08001526 if (anti_collapse_rsv > 0)
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001527 {
1528 anti_collapse_on = st->consec_transient<2;
1529 ec_enc_bits(enc, anti_collapse_on, 1);
1530 }
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001531 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 -04001532
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001533 if (silence)
1534 {
1535 for (i=0;i<C*st->mode->nbEBands;i++)
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001536 oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001537 }
1538
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001539#ifdef RESYNTH
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -05001540 /* Re-synthesis of the coded audio if required */
Jean-Marc Valinb8ba70c2010-04-18 22:10:24 -04001541 if (resynth)
Jean-Marc Valin18ddc022008-02-22 14:24:50 +11001542 {
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001543 celt_sig *out_mem[2];
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001544 celt_sig *overlap_mem[2];
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001545
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001546 log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
Jean-Marc Valin4b000c32011-01-26 20:30:21 -05001547 if (silence)
1548 {
1549 for (i=0;i<C*st->mode->nbEBands;i++)
1550 bandE[i] = 0;
1551 }
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04001552
1553#ifdef MEASURE_NORM_MSE
1554 measure_norm_mse(st->mode, X, X0, bandE, bandE0, M, N, C);
1555#endif
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001556 if (anti_collapse_on)
1557 {
Timothy B. Terriberry682b6cf2011-01-31 13:34:54 -08001558 anti_collapse(st->mode, X, collapse_masks, LM, C, CC, N,
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05001559 st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001560 }
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04001561
Jean-Marc Valin88619552009-10-04 21:35:36 -04001562 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001563 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valin88619552009-10-04 21:35:36 -04001564
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001565 CELT_MOVE(st->syn_mem[0], st->syn_mem[0]+N, MAX_PERIOD);
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001566 if (CC==2)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001567 CELT_MOVE(st->syn_mem[1], st->syn_mem[1]+N, MAX_PERIOD);
1568
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001569 c=0; do
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -04001570 for (i=0;i<M*st->mode->eBands[st->start];i++)
1571 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001572 while (++c<C);
1573 c=0; do
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -04001574 for (i=M*st->mode->eBands[st->end];i<N;i++)
1575 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001576 while (++c<C);
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -04001577
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001578 if (CC==2&&C==1)
1579 {
1580 for (i=0;i<N;i++)
1581 freq[N+i] = freq[i];
1582 }
1583
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001584 out_mem[0] = st->syn_mem[0]+MAX_PERIOD;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001585 if (CC==2)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001586 out_mem[1] = st->syn_mem[1]+MAX_PERIOD;
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001587
Gregory Maxwella45724e2011-07-29 11:53:45 -04001588 overlap_mem[0] = prefilter_mem+CC*COMBFILTER_MAXPERIOD;
1589 if (CC==2)
1590 overlap_mem[1] = overlap_mem[0] + st->overlap;
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001591
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001592 compute_inv_mdcts(st->mode, shortBlocks, freq, out_mem, overlap_mem, CC, LM);
Jean-Marc Valine12017e2009-10-03 13:57:31 -04001593
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001594 c=0; do {
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001595 st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);
1596 st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD);
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05001597 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 -05001598 st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset,
1599 st->mode->window, st->overlap);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001600 if (LM!=0)
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05001601 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 -05001602 st->prefilter_gain, gain1, st->prefilter_tapset, prefilter_tapset,
1603 st->mode->window, st->mode->overlap);
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001604 } while (++c<CC);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001605
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001606 deemphasis(out_mem, (opus_val16*)pcm, N, CC, st->upsample, st->mode->preemph, st->preemph_memD);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001607 st->prefilter_period_old = st->prefilter_period;
1608 st->prefilter_gain_old = st->prefilter_gain;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001609 st->prefilter_tapset_old = st->prefilter_tapset;
Jean-Marc Valind9b95652008-08-31 23:34:47 -04001610 }
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001611#endif
1612
1613 st->prefilter_period = pitch_index;
1614 st->prefilter_gain = gain1;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001615 st->prefilter_tapset = prefilter_tapset;
Jean-Marc Valina14e86d2011-02-11 16:27:27 -05001616#ifdef RESYNTH
1617 if (LM!=0)
1618 {
1619 st->prefilter_period_old = st->prefilter_period;
1620 st->prefilter_gain_old = st->prefilter_gain;
1621 st->prefilter_tapset_old = st->prefilter_tapset;
1622 }
1623#endif
Gregory Maxwell54547f12009-02-16 18:56:44 -05001624
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001625 if (CC==2&&C==1) {
1626 for (i=0;i<st->mode->nbEBands;i++)
1627 oldBandE[st->mode->nbEBands+i]=oldBandE[i];
1628 }
1629
Jean-Marc Valin5677e342011-01-13 16:15:53 -05001630 /* In case start or end were to change */
Jean-Marc Valin5c2ac2b2011-01-22 14:48:20 -05001631 c=0; do
1632 {
1633 for (i=0;i<st->start;i++)
1634 oldBandE[c*st->mode->nbEBands+i]=0;
1635 for (i=st->end;i<st->mode->nbEBands;i++)
1636 oldBandE[c*st->mode->nbEBands+i]=0;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001637 } while (++c<CC);
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001638 if (!isTransient)
1639 {
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001640 for (i=0;i<CC*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001641 oldLogE2[i] = oldLogE[i];
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001642 for (i=0;i<CC*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001643 oldLogE[i] = oldBandE[i];
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05001644 } else {
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001645 for (i=0;i<CC*st->mode->nbEBands;i++)
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05001646 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001647 }
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001648 if (isTransient)
1649 st->consec_transient++;
1650 else
1651 st->consec_transient=0;
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05001652 st->rng = enc->rng;
Jean-Marc Valin5677e342011-01-13 16:15:53 -05001653
Jean-Marc Valin30d51252010-06-21 17:55:28 -04001654 /* If there's any room left (can only happen for very high rates),
Jean-Marc Valin13a7c262011-01-26 10:58:33 -05001655 it's already filled with zeros */
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001656 ec_enc_done(enc);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001657
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05001658 if (st->signalling)
1659 nbCompressedBytes++;
1660
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001661 RESTORE_STACK;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001662 if (ec_get_error(enc))
Jean-Marc Valinef20e392011-03-18 15:34:11 -04001663 return CELT_INTERNAL_ERROR;
Jean-Marc Valin9d785af2010-07-18 09:42:05 -04001664 else
1665 return nbCompressedBytes;
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11001666}
1667
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001668#ifdef FIXED_POINT
1669#ifndef DISABLE_FLOAT_API
Jean-Marc Valin51c78622011-02-03 00:43:37 -05001670CELT_STATIC
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001671int 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 -04001672{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001673 int j, ret, C, N;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001674 VARDECL(opus_int16, in);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05001675 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001676
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001677 if (pcm==NULL)
1678 return CELT_BAD_ARG;
1679
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001680 C = CHANNELS(st->channels);
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001681 N = frame_size;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001682 ALLOC(in, C*N, opus_int16);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001683
1684 for (j=0;j<C*N;j++)
1685 in[j] = FLOAT2INT16(pcm[j]);
1686
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001687 ret=celt_encode_with_ec(st,in,frame_size,compressed,nbCompressedBytes, enc);
1688#ifdef RESYNTH
1689 for (j=0;j<C*N;j++)
1690 ((float*)pcm)[j]=in[j]*(1.f/32768.f);
1691#endif
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001692 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001693 return ret;
1694
1695}
1696#endif /*DISABLE_FLOAT_API*/
1697#else
Jean-Marc Valin51c78622011-02-03 00:43:37 -05001698CELT_STATIC
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001699int 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 -04001700{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001701 int j, ret, C, N;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001702 VARDECL(celt_sig, in);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05001703 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001704
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001705 if (pcm==NULL)
1706 return CELT_BAD_ARG;
1707
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001708 C=CHANNELS(st->channels);
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001709 N=frame_size;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001710 ALLOC(in, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001711 for (j=0;j<C*N;j++) {
1712 in[j] = SCALEOUT(pcm[j]);
1713 }
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001714
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001715 ret = celt_encode_with_ec_float(st,in,frame_size,compressed,nbCompressedBytes, enc);
1716#ifdef RESYNTH
1717 for (j=0;j<C*N;j++)
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001718 ((opus_int16*)pcm)[j] = FLOAT2INT16(in[j]);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001719#endif
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001720 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001721 return ret;
1722}
1723#endif
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +11001724
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001725int 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 -04001726{
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001727 return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001728}
1729
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001730#ifndef DISABLE_FLOAT_API
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001731int celt_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
1732{
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001733 return celt_encode_with_ec_float(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001734}
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04001735#endif /* DISABLE_FLOAT_API */
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001736
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001737int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...)
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001738{
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001739 va_list ap;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001740
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001741 va_start(ap, request);
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001742 switch (request)
1743 {
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001744 case CELT_SET_COMPLEXITY_REQUEST:
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001745 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001746 int value = va_arg(ap, opus_int32);
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001747 if (value<0 || value>10)
1748 goto bad_arg;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001749 st->complexity = value;
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001750 }
1751 break;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001752 case CELT_SET_START_BAND_REQUEST:
1753 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001754 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001755 if (value<0 || value>=st->mode->nbEBands)
1756 goto bad_arg;
1757 st->start = value;
1758 }
1759 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001760 case CELT_SET_END_BAND_REQUEST:
1761 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001762 opus_int32 value = va_arg(ap, opus_int32);
Timothy B. Terriberry8893e532010-12-30 08:56:49 -08001763 if (value<1 || value>st->mode->nbEBands)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001764 goto bad_arg;
1765 st->end = value;
1766 }
1767 break;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001768 case CELT_SET_PREDICTION_REQUEST:
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001769 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001770 int value = va_arg(ap, opus_int32);
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001771 if (value<0 || value>2)
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001772 goto bad_arg;
Jean-Marc Valind539c6b2011-02-03 13:36:03 -05001773 st->disable_pf = value<=1;
1774 st->force_intra = value==0;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001775 }
1776 break;
Jean-Marc Valin69653882011-04-21 10:41:13 -04001777 case CELT_SET_LOSS_PERC_REQUEST:
1778 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001779 int value = va_arg(ap, opus_int32);
Jean-Marc Valin69653882011-04-21 10:41:13 -04001780 if (value<0 || value>100)
1781 goto bad_arg;
1782 st->loss_rate = value;
1783 }
1784 break;
Jean-Marc Valin79b34eb2010-12-05 17:22:06 -05001785 case CELT_SET_VBR_CONSTRAINT_REQUEST:
1786 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001787 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin79b34eb2010-12-05 17:22:06 -05001788 st->constrained_vbr = value;
1789 }
1790 break;
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001791 case CELT_SET_VBR_REQUEST:
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001792 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001793 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001794 st->vbr = value;
1795 }
1796 break;
1797 case CELT_SET_BITRATE_REQUEST:
1798 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001799 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001800 if (value<=500)
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001801 goto bad_arg;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05001802 value = IMIN(value, 260000*st->channels);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001803 st->bitrate = value;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001804 }
1805 break;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001806 case CELT_SET_CHANNELS_REQUEST:
1807 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001808 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001809 if (value<1 || value>2)
1810 goto bad_arg;
1811 st->stream_channels = value;
1812 }
1813 break;
John Ridges454d1d02009-05-21 22:38:39 -04001814 case CELT_RESET_STATE:
1815 {
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001816 CELT_MEMSET((char*)&st->ENCODER_RESET_START, 0,
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05001817 celt_encoder_get_size_custom(st->mode, st->channels)-
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001818 ((char*)&st->ENCODER_RESET_START - (char*)st));
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001819 st->vbr_offset = 0;
John Ridges454d1d02009-05-21 22:38:39 -04001820 st->delayedIntra = 1;
Timothy B. Terriberry320cf2e2010-12-17 05:52:06 -08001821 st->spread_decision = SPREAD_NORMAL;
Jean-Marc Valin628c0252010-04-16 20:57:56 -04001822 st->tonal_average = QCONST16(1.f,8);
John Ridges454d1d02009-05-21 22:38:39 -04001823 }
1824 break;
Jean-Marc Valin0b405d12011-02-04 01:03:42 -05001825 case CELT_SET_INPUT_CLIPPING_REQUEST:
1826 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001827 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin0b405d12011-02-04 01:03:42 -05001828 st->clip = value;
1829 }
1830 break;
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04001831#ifdef OPUS_BUILD
1832 case CELT_SET_SIGNALLING_REQUEST:
1833 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001834 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04001835 st->signalling = value;
1836 }
1837 break;
1838 case CELT_GET_MODE_REQUEST:
1839 {
1840 const CELTMode ** value = va_arg(ap, const CELTMode**);
1841 if (value==0)
1842 goto bad_arg;
1843 *value=st->mode;
1844 }
1845 break;
1846#endif
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001847 default:
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001848 goto bad_request;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001849 }
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001850 va_end(ap);
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001851 return CELT_OK;
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001852bad_arg:
1853 va_end(ap);
1854 return CELT_BAD_ARG;
1855bad_request:
1856 va_end(ap);
1857 return CELT_UNIMPLEMENTED;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001858}
1859
Jean-Marc Valin56522ad2009-06-05 17:17:25 -04001860/**********************************************************************/
1861/* */
1862/* DECODER */
1863/* */
1864/**********************************************************************/
Jean-Marc Valineafbdd52009-04-27 19:35:09 -04001865#define DECODE_BUFFER_SIZE 2048
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001866
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001867/** Decoder state
Jean-Marc Valin276de722008-02-20 17:45:51 +11001868 @brief Decoder state
1869 */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001870struct CELTDecoder {
1871 const CELTMode *mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001872 int overlap;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001873 int channels;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05001874 int stream_channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001875
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001876 int downsample;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001877 int start, end;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05001878 int signalling;
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001879
1880 /* Everything beyond this point gets cleared on a reset */
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05001881#define DECODER_RESET_START rng
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001882
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001883 opus_uint32 rng;
Jean-Marc Valinef20e392011-03-18 15:34:11 -04001884 int error;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001885 int last_pitch_index;
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001886 int loss_count;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001887 int postfilter_period;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001888 int postfilter_period_old;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001889 opus_val16 postfilter_gain;
1890 opus_val16 postfilter_gain_old;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001891 int postfilter_tapset;
1892 int postfilter_tapset_old;
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001893
1894 celt_sig preemph_memD[2];
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001895
Jean-Marc Valinca8b9922010-08-27 16:23:03 -04001896 celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001897 /* opus_val16 lpc[], Size = channels*LPC_ORDER */
1898 /* opus_val16 oldEBands[], Size = 2*mode->nbEBands */
1899 /* opus_val16 oldLogE[], Size = 2*mode->nbEBands */
1900 /* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */
1901 /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001902};
1903
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05001904int celt_decoder_get_size(int channels)
1905{
1906 const CELTMode *mode = celt_mode_create(48000, 960, NULL);
1907 return celt_decoder_get_size_custom(mode, channels);
1908}
1909
1910int celt_decoder_get_size_custom(const CELTMode *mode, int channels)
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001911{
1912 int size = sizeof(struct CELTDecoder)
1913 + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig)
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001914 + channels*LPC_ORDER*sizeof(opus_val16)
1915 + 4*2*mode->nbEBands*sizeof(opus_val16);
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001916 return size;
1917}
1918
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001919CELTDecoder *celt_decoder_create(int sampling_rate, int channels, int *error)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001920{
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -05001921 CELTDecoder *st;
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05001922 st = (CELTDecoder *)celt_alloc(celt_decoder_get_size(channels));
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -05001923 if (st!=NULL && celt_decoder_init(st, sampling_rate, channels, error)==NULL)
1924 {
1925 celt_decoder_destroy(st);
1926 st = NULL;
1927 }
1928 return st;
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -04001929}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001930
Jean-Marc Valinc97b2582011-01-28 23:07:32 -05001931CELTDecoder *celt_decoder_create_custom(const CELTMode *mode, int channels, int *error)
1932{
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05001933 CELTDecoder *st = (CELTDecoder *)celt_alloc(celt_decoder_get_size_custom(mode, channels));
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -05001934 if (st!=NULL && celt_decoder_init_custom(st, mode, channels, error)==NULL)
1935 {
1936 celt_decoder_destroy(st);
1937 st = NULL;
1938 }
1939 return st;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11001940}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001941
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001942CELTDecoder *celt_decoder_init(CELTDecoder *st, int sampling_rate, int channels, int *error)
Jean-Marc Valinc97b2582011-01-28 23:07:32 -05001943{
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001944 celt_decoder_init_custom(st, celt_mode_create(48000, 960, NULL), channels, error);
1945 st->downsample = resampling_factor(sampling_rate);
1946 if (st->downsample==0)
1947 {
1948 if (error)
1949 *error = CELT_BAD_ARG;
1950 return NULL;
1951 }
1952 return st;
Jean-Marc Valinc97b2582011-01-28 23:07:32 -05001953}
1954
1955CELTDecoder *celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int channels, int *error)
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -04001956{
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001957 if (channels < 0 || channels > 2)
1958 {
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001959 if (error)
1960 *error = CELT_BAD_ARG;
1961 return NULL;
1962 }
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001963
Gregory Maxwell17169992009-06-04 15:15:34 -04001964 if (st==NULL)
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001965 {
1966 if (error)
1967 *error = CELT_ALLOC_FAIL;
Gregory Maxwell17169992009-06-04 15:15:34 -04001968 return NULL;
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001969 }
1970
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05001971 CELT_MEMSET((char*)st, 0, celt_decoder_get_size_custom(mode, channels));
Jean-Marc Valin6d3829f2010-08-27 17:52:38 -04001972
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001973 st->mode = mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001974 st->overlap = mode->overlap;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05001975 st->stream_channels = st->channels = channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001976
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001977 st->downsample = 1;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001978 st->start = 0;
Jean-Marc Valin8952c452010-07-16 21:48:44 -04001979 st->end = st->mode->effEBands;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05001980 st->signalling = 1;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001981
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001982 st->loss_count = 0;
Gregory Maxwell17169992009-06-04 15:15:34 -04001983
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001984 if (error)
1985 *error = CELT_OK;
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001986 return st;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001987}
1988
Peter Kirk19f9dc92008-06-06 14:38:38 +02001989void celt_decoder_destroy(CELTDecoder *st)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001990{
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001991 celt_free(st);
1992}
1993
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001994static void celt_decode_lost(CELTDecoder * restrict st, opus_val16 * restrict pcm, int N, int LM)
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001995{
Jean-Marc Valin04752672010-05-05 07:21:21 -04001996 int c;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11001997 int pitch_index;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05001998 int overlap = st->mode->overlap;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001999 opus_val16 fade = Q15ONE;
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10002000 int i, len;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04002001 const int C = CHANNELS(st->channels);
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10002002 int offset;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002003 celt_sig *out_mem[2];
2004 celt_sig *decode_mem[2];
2005 celt_sig *overlap_mem[2];
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002006 opus_val16 *lpc;
2007 opus_val32 *out_syn[2];
2008 opus_val16 *oldBandE, *oldLogE2, *backgroundLogE;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002009 int plc=1;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11002010 SAVE_STACK;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002011
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002012 c=0; do {
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002013 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
2014 out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
2015 overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002016 } while (++c<C);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002017 lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C);
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002018 oldBandE = lpc+C*LPC_ORDER;
2019 oldLogE2 = oldBandE + C*st->mode->nbEBands;
2020 backgroundLogE = oldLogE2 + C*st->mode->nbEBands;
2021
2022 out_syn[0] = out_mem[0]+MAX_PERIOD-N;
2023 if (C==2)
2024 out_syn[1] = out_mem[1]+MAX_PERIOD-N;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002025
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10002026 len = N+st->mode->overlap;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002027
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002028 if (st->loss_count >= 5)
2029 {
2030 VARDECL(celt_sig, freq);
2031 VARDECL(celt_norm, X);
2032 VARDECL(celt_ener, bandE);
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002033 opus_uint32 seed;
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002034 int effEnd;
2035
2036 effEnd = st->end;
2037 if (effEnd > st->mode->effEBands)
2038 effEnd = st->mode->effEBands;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002039
2040 ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
2041 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
2042 ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
2043
2044 log2Amp(st->mode, st->start, st->end, bandE, backgroundLogE, C);
2045
2046 seed = st->rng;
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002047 for (c=0;c<C;c++)
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002048 {
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002049 for (i=0;i<(st->mode->eBands[st->start]<<LM);i++)
2050 X[c*N+i] = 0;
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002051 for (i=0;i<st->mode->effEBands;i++)
2052 {
2053 int j;
2054 int boffs;
2055 int blen;
2056 boffs = N*c+(st->mode->eBands[i]<<LM);
2057 blen = (st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
2058 for (j=0;j<blen;j++)
2059 {
2060 seed = lcg_rand(seed);
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002061 X[boffs+j] = (opus_int32)(seed)>>20;
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002062 }
2063 renormalise_vector(X+boffs, blen, Q15ONE);
2064 }
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002065 for (i=(st->mode->eBands[st->end]<<LM);i<N;i++)
2066 X[c*N+i] = 0;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002067 }
2068 st->rng = seed;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002069
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002070 denormalise_bands(st->mode, X, freq, bandE, st->mode->effEBands, C, 1<<LM);
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002071
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002072 c=0; do
2073 for (i=0;i<st->mode->eBands[st->start]<<LM;i++)
2074 freq[c*N+i] = 0;
2075 while (++c<C);
2076 c=0; do {
2077 int bound = st->mode->eBands[effEnd]<<LM;
2078 if (st->downsample!=1)
2079 bound = IMIN(bound, N/st->downsample);
2080 for (i=bound;i<N;i++)
2081 freq[c*N+i] = 0;
2082 } while (++c<C);
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002083 compute_inv_mdcts(st->mode, 0, freq, out_syn, overlap_mem, C, LM);
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002084 plc = 0;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002085 } else if (st->loss_count == 0)
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04002086 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002087 opus_val16 pitch_buf[DECODE_BUFFER_SIZE>>1];
Jean-Marc Valin5f3d1af2011-05-13 17:24:25 -04002088 /* Corresponds to a min pitch of 67 Hz. It's possible to save CPU in this
2089 search by using only part of the decode buffer */
2090 int poffset = 720;
2091 pitch_downsample(decode_mem, pitch_buf, DECODE_BUFFER_SIZE, C);
2092 /* Max pitch is 100 samples (480 Hz) */
2093 pitch_search(pitch_buf+((poffset)>>1), pitch_buf, DECODE_BUFFER_SIZE-poffset,
2094 poffset-100, &pitch_index);
2095 pitch_index = poffset-pitch_index;
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04002096 st->last_pitch_index = pitch_index;
2097 } else {
2098 pitch_index = st->last_pitch_index;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002099 fade = QCONST16(.8f,15);
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04002100 }
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002101
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002102 if (plc)
2103 {
2104 c=0; do {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002105 VARDECL(opus_val32, e);
2106 opus_val16 exc[MAX_PERIOD];
2107 opus_val32 ac[LPC_ORDER+1];
2108 opus_val16 decay = 1;
2109 opus_val32 S1=0;
2110 opus_val16 mem[LPC_ORDER]={0};
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002111
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002112 ALLOC(e, MAX_PERIOD+2*st->mode->overlap, opus_val32);
Jean-Marc Valinf54a0a32011-05-13 17:36:31 -04002113
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002114 offset = MAX_PERIOD-pitch_index;
2115 for (i=0;i<MAX_PERIOD;i++)
2116 exc[i] = ROUND16(out_mem[c][i], SIG_SHIFT);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05002117
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002118 if (st->loss_count == 0)
2119 {
2120 _celt_autocorr(exc, ac, st->mode->window, st->mode->overlap,
2121 LPC_ORDER, MAX_PERIOD);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05002122
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002123 /* Noise floor -40 dB */
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002124#ifdef FIXED_POINT
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002125 ac[0] += SHR32(ac[0],13);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002126#else
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002127 ac[0] *= 1.0001f;
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002128#endif
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002129 /* Lag windowing */
2130 for (i=1;i<=LPC_ORDER;i++)
2131 {
2132 /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002133#ifdef FIXED_POINT
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002134 ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002135#else
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002136 ac[i] -= ac[i]*(.008f*i)*(.008f*i);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002137#endif
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002138 }
2139
2140 _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
2141 }
2142 for (i=0;i<LPC_ORDER;i++)
2143 mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
2144 fir(exc, lpc+c*LPC_ORDER, exc, MAX_PERIOD, LPC_ORDER, mem);
2145 /*for (i=0;i<MAX_PERIOD;i++)printf("%d ", exc[i]); printf("\n");*/
2146 /* Check if the waveform is decaying (and if so how fast) */
2147 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002148 opus_val32 E1=1, E2=1;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002149 int period;
2150 if (pitch_index <= MAX_PERIOD/2)
2151 period = pitch_index;
2152 else
2153 period = MAX_PERIOD/2;
2154 for (i=0;i<period;i++)
2155 {
2156 E1 += SHR32(MULT16_16(exc[MAX_PERIOD-period+i],exc[MAX_PERIOD-period+i]),8);
2157 E2 += SHR32(MULT16_16(exc[MAX_PERIOD-2*period+i],exc[MAX_PERIOD-2*period+i]),8);
2158 }
2159 if (E1 > E2)
2160 E1 = E2;
2161 decay = celt_sqrt(frac_div32(SHR(E1,1),E2));
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05002162 }
2163
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002164 /* Copy excitation, taking decay into account */
2165 for (i=0;i<len+st->mode->overlap;i++)
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002166 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002167 opus_val16 tmp;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002168 if (offset+i >= MAX_PERIOD)
2169 {
2170 offset -= pitch_index;
2171 decay = MULT16_16_Q15(decay, decay);
2172 }
2173 e[i] = SHL32(EXTEND32(MULT16_16_Q15(decay, exc[offset+i])), SIG_SHIFT);
2174 tmp = ROUND16(out_mem[c][offset+i],SIG_SHIFT);
2175 S1 += SHR32(MULT16_16(tmp,tmp),8);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002176 }
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002177 for (i=0;i<LPC_ORDER;i++)
2178 mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
2179 for (i=0;i<len+st->mode->overlap;i++)
2180 e[i] = MULT16_32_Q15(fade, e[i]);
2181 iir(e, lpc+c*LPC_ORDER, e, len+st->mode->overlap, LPC_ORDER, mem);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002182
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002183 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002184 opus_val32 S2=0;
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05002185 for (i=0;i<len+overlap;i++)
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002186 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002187 opus_val16 tmp = ROUND16(e[i],SIG_SHIFT);
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002188 S2 += SHR32(MULT16_16(tmp,tmp),8);
2189 }
2190 /* This checks for an "explosion" in the synthesis */
2191#ifdef FIXED_POINT
2192 if (!(S1 > SHR32(S2,2)))
2193#else
2194 /* Float test is written this way to catch NaNs at the same time */
2195 if (!(S1 > 0.2f*S2))
2196#endif
2197 {
2198 for (i=0;i<len+overlap;i++)
2199 e[i] = 0;
2200 } else if (S1 < S2)
2201 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002202 opus_val16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002203 for (i=0;i<len+overlap;i++)
2204 e[i] = MULT16_32_Q15(ratio, e[i]);
2205 }
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05002206 }
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002207
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002208 /* Apply post-filter to the MDCT overlap of the previous frame */
2209 comb_filter(out_mem[c]+MAX_PERIOD, out_mem[c]+MAX_PERIOD, st->postfilter_period, st->postfilter_period, st->overlap,
2210 st->postfilter_gain, st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset,
2211 NULL, 0);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002212
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002213 for (i=0;i<MAX_PERIOD+st->mode->overlap-N;i++)
2214 out_mem[c][i] = out_mem[c][N+i];
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002215
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002216 /* Apply TDAC to the concealed audio so that it blends with the
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002217 previous and next frames */
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002218 for (i=0;i<overlap/2;i++)
2219 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002220 opus_val32 tmp;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002221 tmp = MULT16_32_Q15(st->mode->window[i], e[N+overlap-1-i]) +
2222 MULT16_32_Q15(st->mode->window[overlap-i-1], e[N+i ]);
2223 out_mem[c][MAX_PERIOD+i] = MULT16_32_Q15(st->mode->window[overlap-i-1], tmp);
2224 out_mem[c][MAX_PERIOD+overlap-i-1] = MULT16_32_Q15(st->mode->window[i], tmp);
2225 }
2226 for (i=0;i<N;i++)
2227 out_mem[c][MAX_PERIOD-N+i] = e[i];
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002228
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002229 /* Apply pre-filter to the MDCT overlap for the next frame (post-filter will be applied then) */
2230 comb_filter(e, out_mem[c]+MAX_PERIOD, st->postfilter_period, st->postfilter_period, st->overlap,
2231 -st->postfilter_gain, -st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset,
2232 NULL, 0);
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002233 for (i=0;i<overlap;i++)
2234 out_mem[c][MAX_PERIOD+i] = e[i];
2235 } while (++c<C);
2236 }
Jean-Marc Valin1677aa92007-12-08 01:13:34 +11002237
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002238 deemphasis(out_syn, pcm, N, C, st->downsample, st->mode->preemph, st->preemph_memD);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002239
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04002240 st->loss_count++;
2241
Jean-Marc Valin8600f692008-02-29 15:14:12 +11002242 RESTORE_STACK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002243}
2244
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002245#ifdef FIXED_POINT
Jean-Marc Valin51c78622011-02-03 00:43:37 -05002246CELT_STATIC
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002247int 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 +11002248{
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002249#else
Jean-Marc Valin51c78622011-02-03 00:43:37 -05002250CELT_STATIC
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002251int 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 -04002252{
2253#endif
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -04002254 int c, i, N;
Timothy B. Terriberry320cf2e2010-12-17 05:52:06 -08002255 int spread_decision;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002256 opus_int32 bits;
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002257 ec_dec _dec;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002258 VARDECL(celt_sig, freq);
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002259 VARDECL(celt_norm, X);
2260 VARDECL(celt_ener, bandE);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002261 VARDECL(int, fine_quant);
2262 VARDECL(int, pulses);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002263 VARDECL(int, cap);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002264 VARDECL(int, offsets);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04002265 VARDECL(int, fine_priority);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -04002266 VARDECL(int, tf_res);
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002267 VARDECL(unsigned char, collapse_masks);
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002268 celt_sig *out_mem[2];
2269 celt_sig *decode_mem[2];
2270 celt_sig *overlap_mem[2];
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04002271 celt_sig *out_syn[2];
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002272 opus_val16 *lpc;
2273 opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
Jean-Marc Valinc890b582008-08-01 22:26:49 -04002274
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +10002275 int shortBlocks;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04002276 int isTransient;
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -04002277 int intra_ener;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002278 const int CC = CHANNELS(st->channels);
Jean-Marc Valin017fa852010-05-06 22:11:48 -04002279 int LM, M;
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002280 int effEnd;
Jean-Marc Valinb801da52010-09-28 14:56:20 -04002281 int codedBands;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04002282 int alloc_trim;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002283 int postfilter_pitch;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002284 opus_val16 postfilter_gain;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05002285 int intensity=0;
Jean-Marc Valine65978f2010-12-02 13:46:48 -05002286 int dual_stereo=0;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002287 opus_int32 total_bits;
2288 opus_int32 balance;
2289 opus_int32 tell;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002290 int dynalloc_logp;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002291 int postfilter_tapset;
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002292 int anti_collapse_rsv;
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002293 int anti_collapse_on=0;
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002294 int silence;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002295 int C = CHANNELS(st->stream_channels);
Jean-Marc Valinf62b3bb2011-03-09 11:56:29 -05002296 ALLOC_STACK;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11002297
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002298 frame_size *= st->downsample;
Jean-Marc Valin017fa852010-05-06 22:11:48 -04002299
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002300 c=0; do {
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002301 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
2302 out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
2303 overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002304 } while (++c<CC);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002305 lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*CC);
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002306 oldBandE = lpc+LPC_ORDER;
2307 oldLogE = oldBandE + 2*st->mode->nbEBands;
2308 oldLogE2 = oldLogE + 2*st->mode->nbEBands;
2309 backgroundLogE = oldLogE2 + 2*st->mode->nbEBands;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002310
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002311 if (st->signalling && data!=NULL)
2312 {
Jean-Marc Valind6bf19d2011-03-21 07:06:09 -04002313 int data0=data[0];
2314 /* Convert "standard mode" to Opus header */
2315 if (st->mode->Fs==48000 && st->mode->shortMdctSize==120)
2316 {
2317 data0 = fromOpus(data0);
2318 if (data0<0)
2319 return CELT_CORRUPTED_DATA;
2320 }
2321 st->end = IMAX(1, st->mode->effEBands-2*(data0>>5));
2322 LM = (data0>>3)&0x3;
2323 C = 1 + ((data0>>2)&0x1);
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002324 data++;
2325 len--;
2326 if (LM>st->mode->maxLM)
2327 return CELT_CORRUPTED_DATA;
2328 if (frame_size < st->mode->shortMdctSize<<LM)
Jean-Marc Valinef20e392011-03-18 15:34:11 -04002329 return CELT_BUFFER_TOO_SMALL;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002330 else
2331 frame_size = st->mode->shortMdctSize<<LM;
2332 } else {
2333 for (LM=0;LM<=st->mode->maxLM;LM++)
2334 if (st->mode->shortMdctSize<<LM==frame_size)
2335 break;
2336 if (LM>st->mode->maxLM)
2337 return CELT_BAD_ARG;
2338 }
2339 M=1<<LM;
2340
2341 if (len<0 || len>1275 || pcm==NULL)
2342 return CELT_BAD_ARG;
2343
Jean-Marc Valin04752672010-05-05 07:21:21 -04002344 N = M*st->mode->shortMdctSize;
Jean-Marc Valin01417232008-03-03 13:59:55 +11002345
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002346 effEnd = st->end;
2347 if (effEnd > st->mode->effEBands)
2348 effEnd = st->mode->effEBands;
2349
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002350 ALLOC(freq, IMAX(CC,C)*N, celt_sig); /**< Interleaved signal MDCTs */
2351 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
2352 ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002353 c=0; do
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002354 for (i=0;i<M*st->mode->eBands[st->start];i++)
2355 X[c*N+i] = 0;
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002356 while (++c<C);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002357 c=0; do
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002358 for (i=M*st->mode->eBands[effEnd];i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002359 X[c*N+i] = 0;
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002360 while (++c<C);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002361
Jean-Marc Valin65d35a32011-01-26 22:04:59 -05002362 if (data == NULL || len<=1)
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002363 {
Jean-Marc Valin017fa852010-05-06 22:11:48 -04002364 celt_decode_lost(st, pcm, N, LM);
Jean-Marc Valin8600f692008-02-29 15:14:12 +11002365 RESTORE_STACK;
Jean-Marc Valin37e788c2011-03-16 20:56:28 -04002366 return frame_size/st->downsample;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002367 }
Gregory Maxwell520eeae2009-02-09 01:33:21 -05002368 if (len<0) {
2369 RESTORE_STACK;
2370 return CELT_BAD_ARG;
2371 }
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002372
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002373 if (dec == NULL)
2374 {
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002375 ec_dec_init(&_dec,(unsigned char*)data,len);
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002376 dec = &_dec;
2377 }
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04002378
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002379 if (C<CC)
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002380 {
2381 for (i=0;i<st->mode->nbEBands;i++)
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002382 oldBandE[i]=MAX16(oldBandE[i],oldBandE[st->mode->nbEBands+i]);
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002383 }
2384
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002385 total_bits = len*8;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002386 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002387
Jean-Marc Valina0653ed2011-07-05 13:18:59 -04002388 if (tell >= total_bits)
2389 silence = 1;
2390 else if (tell==1)
Jean-Marc Valin65d35a32011-01-26 22:04:59 -05002391 silence = ec_dec_bit_logp(dec, 15);
2392 else
2393 silence = 0;
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002394 if (silence)
2395 {
Jean-Marc Valin13a7c262011-01-26 10:58:33 -05002396 /* Pretend we've read all the remaining bits */
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002397 tell = len*8;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002398 dec->nbits_total+=tell-ec_tell(dec);
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002399 }
2400
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002401 postfilter_gain = 0;
2402 postfilter_pitch = 0;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002403 postfilter_tapset = 0;
Jean-Marc Valinef986e42011-02-03 15:47:10 -05002404 if (st->start==0 && tell+16 <= total_bits)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002405 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002406 if(ec_dec_bit_logp(dec, 1))
2407 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002408 int qg, octave;
2409 octave = ec_dec_uint(dec, 6);
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002410 postfilter_pitch = (16<<octave)+ec_dec_bits(dec, 4+octave)-1;
Jean-Marc Valinef986e42011-02-03 15:47:10 -05002411 qg = ec_dec_bits(dec, 3);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002412 if (ec_tell(dec)+2<=total_bits)
Jean-Marc Valinef986e42011-02-03 15:47:10 -05002413 postfilter_tapset = ec_dec_icdf(dec, tapset_icdf, 2);
2414 postfilter_gain = QCONST16(.09375f,15)*(qg+1);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002415 }
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002416 tell = ec_tell(dec);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002417 }
2418
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002419 if (LM > 0 && tell+3 <= total_bits)
2420 {
Timothy B. Terriberrye86fb262010-12-17 14:50:19 -08002421 isTransient = ec_dec_bit_logp(dec, 3);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002422 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002423 }
Jean-Marc Valinf9fdbff2010-09-05 21:02:38 -04002424 else
2425 isTransient = 0;
Jean-Marc Valin017001a2010-08-05 15:42:50 -04002426
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04002427 if (isTransient)
2428 shortBlocks = M;
2429 else
2430 shortBlocks = 0;
2431
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002432 /* Decode the global flags (first symbols in the stream) */
2433 intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0;
2434 /* Get band energies */
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05002435 unquant_coarse_energy(st->mode, st->start, st->end, oldBandE,
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002436 intra_ener, dec, C, LM);
2437
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04002438 ALLOC(tf_res, st->mode->nbEBands, int);
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05002439 tf_decode(st->start, st->end, isTransient, tf_res, LM, dec);
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04002440
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002441 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002442 spread_decision = SPREAD_NORMAL;
2443 if (tell+4 <= total_bits)
2444 spread_decision = ec_dec_icdf(dec, spread_icdf, 5);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04002445
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002446 ALLOC(pulses, st->mode->nbEBands, int);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002447 ALLOC(cap, st->mode->nbEBands, int);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002448 ALLOC(offsets, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04002449 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002450
Timothy B. Terriberryce6d0902011-02-01 17:41:12 -08002451 init_caps(st->mode,cap,LM,C);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002452
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002453 dynalloc_logp = 6;
2454 total_bits<<=BITRES;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002455 tell = ec_tell_frac(dec);
Timothy B. Terriberryd6f61572010-12-30 09:04:16 -08002456 for (i=st->start;i<st->end;i++)
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002457 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002458 int width, quanta;
2459 int dynalloc_loop_logp;
2460 int boost;
2461 width = C*(st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
2462 /* quanta is 6 bits, but no more than 1 bit/sample
2463 and no less than 1/8 bit/sample */
2464 quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));
2465 dynalloc_loop_logp = dynalloc_logp;
2466 boost = 0;
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002467 while (tell+(dynalloc_loop_logp<<BITRES) < total_bits && boost < cap[i])
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002468 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002469 int flag;
2470 flag = ec_dec_bit_logp(dec, dynalloc_loop_logp);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002471 tell = ec_tell_frac(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002472 if (!flag)
2473 break;
2474 boost += quanta;
2475 total_bits -= quanta;
2476 dynalloc_loop_logp = 1;
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002477 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002478 offsets[i] = boost;
2479 /* Making dynalloc more likely */
2480 if (boost>0)
2481 dynalloc_logp = IMAX(2, dynalloc_logp-1);
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002482 }
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002483
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04002484 ALLOC(fine_quant, st->mode->nbEBands, int);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002485 alloc_trim = tell+(6<<BITRES) <= total_bits ?
2486 ec_dec_icdf(dec, trim_icdf, 7) : 5;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05002487
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002488 bits = ((opus_int32)len*8<<BITRES) - ec_tell_frac(dec) - 1;
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002489 anti_collapse_rsv = isTransient&&LM>=2&&bits>=(LM+2<<BITRES) ? (1<<BITRES) : 0;
2490 bits -= anti_collapse_rsv;
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002491 codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08002492 alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
2493 fine_quant, fine_priority, C, LM, dec, 0, 0);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002494
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05002495 unquant_fine_energy(st->mode, st->start, st->end, oldBandE, fine_quant, dec, C);
Jean-Marc Valin827f9312008-05-06 23:21:55 +10002496
Jean-Marc Valin8cbea172010-08-05 15:22:57 -04002497 /* Decode fixed codebook */
Jean-Marc Valin7e983192011-02-01 18:00:29 -05002498 ALLOC(collapse_masks, C*st->mode->nbEBands, unsigned char);
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002499 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 -08002500 NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res, 1,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08002501 len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng);
Jean-Marc Valin746b2a82010-05-14 22:12:33 -04002502
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002503 if (anti_collapse_rsv > 0)
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002504 {
2505 anti_collapse_on = ec_dec_bits(dec, 1);
2506 }
2507
Jean-Marc Valine3e2c262011-01-26 13:09:53 -05002508 unquant_energy_finalise(st->mode, st->start, st->end, oldBandE,
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002509 fine_quant, fine_priority, len*8-ec_tell(dec), dec, C);
Jean-Marc Valin30d51252010-06-21 17:55:28 -04002510
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002511 if (anti_collapse_on)
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002512 anti_collapse(st->mode, X, collapse_masks, LM, C, C, N,
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05002513 st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002514
Jean-Marc Valin02a35272010-08-27 16:00:01 -04002515 log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04002516
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002517 if (silence)
2518 {
2519 for (i=0;i<C*st->mode->nbEBands;i++)
2520 {
2521 bandE[i] = 0;
Gregory Maxwell8b631f22011-01-26 20:19:01 -05002522 oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002523 }
2524 }
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11002525 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002526 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11002527
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002528 CELT_MOVE(decode_mem[0], decode_mem[0]+N, DECODE_BUFFER_SIZE-N);
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002529 if (CC==2)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002530 CELT_MOVE(decode_mem[1], decode_mem[1]+N, DECODE_BUFFER_SIZE-N);
Jean-Marc Valin88619552009-10-04 21:35:36 -04002531
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002532 c=0; do
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002533 for (i=0;i<M*st->mode->eBands[st->start];i++)
2534 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002535 while (++c<C);
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002536 c=0; do {
2537 int bound = M*st->mode->eBands[effEnd];
2538 if (st->downsample!=1)
2539 bound = IMIN(bound, N/st->downsample);
Jean-Marc Valin23340e22011-02-03 23:21:00 -05002540 for (i=bound;i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002541 freq[c*N+i] = 0;
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002542 } while (++c<C);
Jean-Marc Valin3a0bc3d2010-02-21 15:10:22 -05002543
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002544 out_syn[0] = out_mem[0]+MAX_PERIOD-N;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002545 if (CC==2)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002546 out_syn[1] = out_mem[1]+MAX_PERIOD-N;
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04002547
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002548 if (CC==2&&C==1)
2549 {
2550 for (i=0;i<N;i++)
2551 freq[N+i] = freq[i];
2552 }
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002553 if (CC==1&&C==2)
2554 {
2555 for (i=0;i<N;i++)
2556 freq[i] = HALF32(ADD32(freq[i],freq[N+i]));
2557 }
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002558
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11002559 /* Compute inverse MDCTs */
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002560 compute_inv_mdcts(st->mode, shortBlocks, freq, out_syn, overlap_mem, CC, LM);
Jean-Marc Valinffa13472007-12-10 16:54:17 +11002561
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002562 c=0; do {
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05002563 st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD);
2564 st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD);
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05002565 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 -05002566 st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset,
2567 st->mode->window, st->overlap);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05002568 if (LM!=0)
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05002569 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 -05002570 st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset,
2571 st->mode->window, st->mode->overlap);
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05002572
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002573 } while (++c<CC);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05002574 st->postfilter_period_old = st->postfilter_period;
2575 st->postfilter_gain_old = st->postfilter_gain;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002576 st->postfilter_tapset_old = st->postfilter_tapset;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002577 st->postfilter_period = postfilter_pitch;
2578 st->postfilter_gain = postfilter_gain;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002579 st->postfilter_tapset = postfilter_tapset;
Jean-Marc Valina14e86d2011-02-11 16:27:27 -05002580 if (LM!=0)
2581 {
2582 st->postfilter_period_old = st->postfilter_period;
2583 st->postfilter_gain_old = st->postfilter_gain;
2584 st->postfilter_tapset_old = st->postfilter_tapset;
2585 }
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002586
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002587 if (C==1) {
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002588 for (i=0;i<st->mode->nbEBands;i++)
2589 oldBandE[st->mode->nbEBands+i]=oldBandE[i];
2590 }
2591
Jean-Marc Valin5677e342011-01-13 16:15:53 -05002592 /* In case start or end were to change */
Jean-Marc Valin5c2ac2b2011-01-22 14:48:20 -05002593 c=0; do
2594 {
2595 for (i=0;i<st->start;i++)
2596 oldBandE[c*st->mode->nbEBands+i]=0;
2597 for (i=st->end;i<st->mode->nbEBands;i++)
2598 oldBandE[c*st->mode->nbEBands+i]=0;
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002599 } while (++c<2);
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002600 if (!isTransient)
2601 {
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002602 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002603 oldLogE2[i] = oldLogE[i];
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002604 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002605 oldLogE[i] = oldBandE[i];
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002606 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002607 backgroundLogE[i] = MIN16(backgroundLogE[i] + M*QCONST16(0.001f,DB_SHIFT), oldBandE[i]);
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05002608 } else {
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002609 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05002610 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002611 }
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05002612 st->rng = dec->rng;
Jean-Marc Valin5677e342011-01-13 16:15:53 -05002613
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002614 deemphasis(out_syn, pcm, N, CC, st->downsample, st->mode->preemph, st->preemph_memD);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002615 st->loss_count = 0;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11002616 RESTORE_STACK;
Jean-Marc Valinef20e392011-03-18 15:34:11 -04002617 if (ec_tell(dec) > 8*len)
2618 return CELT_INTERNAL_ERROR;
2619 if(ec_get_error(dec))
2620 st->error = 1;
2621 return frame_size/st->downsample;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11002622}
2623
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002624#ifdef FIXED_POINT
2625#ifndef DISABLE_FLOAT_API
Jean-Marc Valin51c78622011-02-03 00:43:37 -05002626CELT_STATIC
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002627int 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 -04002628{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002629 int j, ret, C, N;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002630 VARDECL(opus_int16, out);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05002631 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04002632
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04002633 if (pcm==NULL)
2634 return CELT_BAD_ARG;
2635
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04002636 C = CHANNELS(st->channels);
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002637 N = frame_size;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002638
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002639 ALLOC(out, C*N, opus_int16);
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002640 ret=celt_decode_with_ec(st, data, len, out, frame_size, dec);
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002641 if (ret>0)
2642 for (j=0;j<C*ret;j++)
Jean-Marc Valinae01e112010-08-03 21:43:41 -04002643 pcm[j]=out[j]*(1.f/32768.f);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002644
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04002645 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002646 return ret;
2647}
2648#endif /*DISABLE_FLOAT_API*/
2649#else
Jean-Marc Valin51c78622011-02-03 00:43:37 -05002650CELT_STATIC
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002651int 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 -04002652{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002653 int j, ret, C, N;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002654 VARDECL(celt_sig, out);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05002655 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04002656
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04002657 if (pcm==NULL)
2658 return CELT_BAD_ARG;
2659
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04002660 C = CHANNELS(st->channels);
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002661 N = frame_size;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002662 ALLOC(out, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002663
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002664 ret=celt_decode_with_ec_float(st, data, len, out, frame_size, dec);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002665
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002666 if (ret>0)
2667 for (j=0;j<C*ret;j++)
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04002668 pcm[j] = FLOAT2INT16 (out[j]);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002669
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04002670 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002671 return ret;
2672}
2673#endif
John Ridges454d1d02009-05-21 22:38:39 -04002674
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002675int 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 -04002676{
2677 return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL);
2678}
2679
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04002680#ifndef DISABLE_FLOAT_API
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002681int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size)
2682{
2683 return celt_decode_with_ec_float(st, data, len, pcm, frame_size, NULL);
2684}
Jean-Marc Valin4424b5a2010-07-06 19:37:23 -04002685#endif /* DISABLE_FLOAT_API */
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002686
John Ridges454d1d02009-05-21 22:38:39 -04002687int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
2688{
2689 va_list ap;
Gregory Maxwell17169992009-06-04 15:15:34 -04002690
John Ridges454d1d02009-05-21 22:38:39 -04002691 va_start(ap, request);
2692 switch (request)
2693 {
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002694 case CELT_SET_START_BAND_REQUEST:
2695 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002696 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002697 if (value<0 || value>=st->mode->nbEBands)
2698 goto bad_arg;
2699 st->start = value;
2700 }
2701 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002702 case CELT_SET_END_BAND_REQUEST:
2703 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002704 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwell1928f8d2011-02-08 22:32:56 -05002705 if (value<1 || value>st->mode->nbEBands)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002706 goto bad_arg;
2707 st->end = value;
2708 }
2709 break;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002710 case CELT_SET_CHANNELS_REQUEST:
2711 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002712 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002713 if (value<1 || value>2)
2714 goto bad_arg;
2715 st->stream_channels = value;
2716 }
Jean-Marc Valindd2973d2011-03-11 17:46:02 -05002717 break;
Jean-Marc Valinef20e392011-03-18 15:34:11 -04002718 case CELT_GET_AND_CLEAR_ERROR_REQUEST:
2719 {
2720 int *value = va_arg(ap, int*);
2721 if (value==NULL)
2722 goto bad_arg;
2723 *value=st->error;
2724 st->error = 0;
2725 }
2726 break;
Jean-Marc Valinff96b162011-03-21 11:32:50 -04002727 case CELT_GET_LOOKAHEAD_REQUEST:
2728 {
2729 int *value = va_arg(ap, int*);
2730 if (value==NULL)
2731 goto bad_arg;
2732 *value = st->overlap/st->downsample;
2733 }
2734 break;
John Ridges454d1d02009-05-21 22:38:39 -04002735 case CELT_RESET_STATE:
2736 {
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04002737 CELT_MEMSET((char*)&st->DECODER_RESET_START, 0,
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05002738 celt_decoder_get_size_custom(st->mode, st->channels)-
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04002739 ((char*)&st->DECODER_RESET_START - (char*)st));
John Ridges454d1d02009-05-21 22:38:39 -04002740 }
2741 break;
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04002742#ifdef OPUS_BUILD
2743 case CELT_GET_MODE_REQUEST:
2744 {
2745 const CELTMode ** value = va_arg(ap, const CELTMode**);
2746 if (value==0)
2747 goto bad_arg;
2748 *value=st->mode;
2749 }
2750 break;
2751 case CELT_SET_SIGNALLING_REQUEST:
2752 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002753 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04002754 st->signalling = value;
2755 }
2756 break;
2757#endif
John Ridges454d1d02009-05-21 22:38:39 -04002758 default:
2759 goto bad_request;
2760 }
2761 va_end(ap);
2762 return CELT_OK;
John Ridges454d1d02009-05-21 22:38:39 -04002763bad_arg:
2764 va_end(ap);
2765 return CELT_BAD_ARG;
John Ridges454d1d02009-05-21 22:38:39 -04002766bad_request:
2767 va_end(ap);
2768 return CELT_UNIMPLEMENTED;
2769}
Jean-Marc Valinece94a02009-10-16 07:30:14 -04002770
2771const char *celt_strerror(int error)
2772{
2773 static const char *error_strings[8] = {
2774 "success",
2775 "invalid argument",
Jean-Marc Valinc5f99902011-03-18 15:47:53 -04002776 "buffer too small",
Jean-Marc Valinece94a02009-10-16 07:30:14 -04002777 "internal error",
2778 "corrupted stream",
2779 "request not implemented",
2780 "invalid state",
2781 "memory allocation failed"
2782 };
2783 if (error > 0 || error < -7)
2784 return "unknown error";
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002785 else
Jean-Marc Valinece94a02009-10-16 07:30:14 -04002786 return error_strings[-error];
2787}