blob: f14c7f80d323636ad431631f2d1273929fa3a253 [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
Jean-Marc Valincb05e7c2012-04-20 16:40:24 -040020 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +110022 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 Valin2779df72011-10-04 13:26:53 -040050#include "celt_lpc.h"
Jean-Marc Valineafd8a72011-01-23 00:24:45 -050051#include "vq.h"
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -050052
Ralph Gilesb0f4e902011-09-07 13:16:29 -070053#ifndef OPUS_VERSION
54#define OPUS_VERSION "unknown"
55#endif
56
Gregory Maxwellafc8d532011-09-28 15:13:26 -040057#ifdef CUSTOM_MODES
58#define OPUS_CUSTOM_NOSTATIC
59#else
60#define OPUS_CUSTOM_NOSTATIC static inline
61#endif
62
Timothy B. Terriberry845dfa12011-01-02 16:53:28 -080063static const unsigned char trim_icdf[11] = {126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0};
64/* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */
65static const unsigned char spread_icdf[4] = {25, 23, 2, 0};
Jean-Marc Valin4b087df2010-11-30 21:08:31 -050066
Jean-Marc Valin2ce5c632011-01-17 20:50:18 -050067static const unsigned char tapset_icdf[3]={2,1,0};
68
Gregory Maxwellfd17eab2011-10-04 03:31:45 -040069#ifdef CUSTOM_MODES
Jean-Marc Valind6bf19d2011-03-21 07:06:09 -040070static const unsigned char toOpusTable[20] = {
71 0xE0, 0xE8, 0xF0, 0xF8,
72 0xC0, 0xC8, 0xD0, 0xD8,
73 0xA0, 0xA8, 0xB0, 0xB8,
74 0x00, 0x00, 0x00, 0x00,
75 0x80, 0x88, 0x90, 0x98,
76};
77
78static const unsigned char fromOpusTable[16] = {
79 0x80, 0x88, 0x90, 0x98,
80 0x40, 0x48, 0x50, 0x58,
81 0x20, 0x28, 0x30, 0x38,
82 0x00, 0x08, 0x10, 0x18
83};
84
85static inline int toOpus(unsigned char c)
86{
87 int ret=0;
88 if (c<0xA0)
89 ret = toOpusTable[c>>3];
90 if (ret == 0)
91 return -1;
92 else
93 return ret|(c&0x7);
94}
95
96static inline int fromOpus(unsigned char c)
97{
98 if (c<0x80)
99 return -1;
100 else
101 return fromOpusTable[(c>>3)-16] | (c&0x7);
102}
Ralph Giles120800f2011-11-25 13:02:00 -0800103#endif /* CUSTOM_MODES */
Jean-Marc Valind6bf19d2011-03-21 07:06:09 -0400104
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400105#define COMBFILTER_MAXPERIOD 1024
Jean-Marc Valind1212602011-01-25 13:11:36 -0500106#define COMBFILTER_MINPERIOD 15
Jean-Marc Valin6bf04622010-09-30 10:16:22 -0400107
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400108static int resampling_factor(opus_int32 rate)
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500109{
110 int ret;
111 switch (rate)
112 {
113 case 48000:
114 ret = 1;
115 break;
116 case 24000:
117 ret = 2;
118 break;
119 case 16000:
120 ret = 3;
121 break;
122 case 12000:
123 ret = 4;
124 break;
125 case 8000:
126 ret = 6;
127 break;
128 default:
Jean-Marc Valin64ae0a92011-10-29 17:28:51 -0400129#ifndef CUSTOM_MODES
Gregory Maxwellfd17eab2011-10-04 03:31:45 -0400130 celt_assert(0);
131#endif
Jean-Marc Valin64ae0a92011-10-29 17:28:51 -0400132 ret = 0;
133 break;
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500134 }
135 return ret;
136}
137
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400138/** Encoder state
Jean-Marc Valin276de722008-02-20 17:45:51 +1100139 @brief Encoder state
140 */
Jean-Marc Valin242da532011-09-05 20:53:33 -0400141struct OpusCustomEncoder {
142 const OpusCustomMode *mode; /**< Mode used by the encoder */
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100143 int overlap;
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100144 int channels;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -0500145 int stream_channels;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400146
Gregory Maxwell2dd3d322009-06-05 14:05:51 -0400147 int force_intra;
Jean-Marc Valin0b405d12011-02-04 01:03:42 -0500148 int clip;
Jean-Marc Valind539c6b2011-02-03 13:36:03 -0500149 int disable_pf;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400150 int complexity;
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500151 int upsample;
Jean-Marc Valinc09807d2010-08-27 17:17:50 -0400152 int start, end;
153
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400154 opus_int32 bitrate;
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500155 int vbr;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -0500156 int signalling;
Jean-Marc Valin9faf7402010-12-04 10:27:22 -0500157 int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */
Jean-Marc Valin69653882011-04-21 10:41:13 -0400158 int loss_rate;
Jean-Marc Valinc09807d2010-08-27 17:17:50 -0400159
160 /* Everything beyond this point gets cleared on a reset */
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -0500161#define ENCODER_RESET_START rng
Jean-Marc Valinc09807d2010-08-27 17:17:50 -0400162
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400163 opus_uint32 rng;
Timothy B. Terriberry320cf2e2010-12-17 05:52:06 -0800164 int spread_decision;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400165 opus_val32 delayedIntra;
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -0400166 int tonal_average;
Jean-Marc Valindfd6e712010-12-09 23:23:34 -0500167 int lastCodedBands;
Jean-Marc Valin8d367022011-01-17 16:37:51 -0500168 int hf_average;
169 int tapset_decision;
Jean-Marc Valin527db5c2009-06-02 07:56:19 -0400170
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400171 int prefilter_period;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400172 opus_val16 prefilter_gain;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500173 int prefilter_tapset;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -0500174#ifdef RESYNTH
175 int prefilter_period_old;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400176 opus_val16 prefilter_gain_old;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500177 int prefilter_tapset_old;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -0500178#endif
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -0500179 int consec_transient;
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400180
Gregory Maxwell86dd9842011-08-12 19:03:29 -0400181 opus_val32 preemph_memE[2];
182 opus_val32 preemph_memD[2];
183
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400184 /* VBR-related parameters */
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400185 opus_int32 vbr_reservoir;
186 opus_int32 vbr_drift;
187 opus_int32 vbr_offset;
188 opus_int32 vbr_count;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -0400189
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400190#ifdef RESYNTH
191 celt_sig syn_mem[2][2*MAX_PERIOD];
192#endif
193
Jean-Marc Valinca8b9922010-08-27 16:23:03 -0400194 celt_sig in_mem[1]; /* Size = channels*mode->overlap */
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400195 /* celt_sig prefilter_mem[], Size = channels*COMBFILTER_PERIOD */
Jean-Marc Valinca8b9922010-08-27 16:23:03 -0400196 /* celt_sig overlap_mem[], Size = channels*mode->overlap */
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400197 /* opus_val16 oldEBands[], Size = 2*channels*mode->nbEBands */
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100198};
199
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -0500200int celt_encoder_get_size(int channels)
201{
Jean-Marc Valin06237d72011-09-01 13:20:40 -0400202 CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
203 return opus_custom_encoder_get_size(mode, channels);
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -0500204}
205
Gregory Maxwellafc8d532011-09-28 15:13:26 -0400206OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_get_size(const CELTMode *mode, int channels)
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400207{
208 int size = sizeof(struct CELTEncoder)
209 + (2*channels*mode->overlap-1)*sizeof(celt_sig)
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400210 + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig)
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400211 + 3*channels*mode->nbEBands*sizeof(opus_val16);
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400212 return size;
213}
214
Jean-Marc Valin06237d72011-09-01 13:20:40 -0400215#ifdef CUSTOM_MODES
216CELTEncoder *opus_custom_encoder_create(const CELTMode *mode, int channels, int *error)
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500217{
Jean-Marc Valin875f8db2011-08-31 16:43:08 -0400218 int ret;
Jean-Marc Valin06237d72011-09-01 13:20:40 -0400219 CELTEncoder *st = (CELTEncoder *)opus_alloc(opus_custom_encoder_get_size(mode, channels));
Jean-Marc Valin875f8db2011-08-31 16:43:08 -0400220 /* init will handle the NULL case */
Jean-Marc Valin06237d72011-09-01 13:20:40 -0400221 ret = opus_custom_encoder_init(st, mode, channels);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400222 if (ret != OPUS_OK)
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -0500223 {
Jean-Marc Valin06237d72011-09-01 13:20:40 -0400224 opus_custom_encoder_destroy(st);
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -0500225 st = NULL;
226 }
Jean-Marc Valin06237d72011-09-01 13:20:40 -0400227 if (error)
228 *error = ret;
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -0500229 return st;
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -0400230}
Jean-Marc Valin06237d72011-09-01 13:20:40 -0400231#endif /* CUSTOM_MODES */
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100232
Gregory Maxwell64a35412011-09-02 10:31:17 -0400233int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels)
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500234{
Jean-Marc Valin875f8db2011-08-31 16:43:08 -0400235 int ret;
Jean-Marc Valin06237d72011-09-01 13:20:40 -0400236 ret = opus_custom_encoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400237 if (ret != OPUS_OK)
Jean-Marc Valin875f8db2011-08-31 16:43:08 -0400238 return ret;
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500239 st->upsample = resampling_factor(sampling_rate);
Gregory Maxwellfd17eab2011-10-04 03:31:45 -0400240 return OPUS_OK;
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500241}
242
Gregory Maxwellafc8d532011-09-28 15:13:26 -0400243OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels)
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -0400244{
Jean-Marc Valin80ed1472009-10-15 21:45:32 -0400245 if (channels < 0 || channels > 2)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400246 return OPUS_BAD_ARG;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100247
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -0500248 if (st==NULL || mode==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400249 return OPUS_ALLOC_FAIL;
Jean-Marc Valin6d3829f2010-08-27 17:52:38 -0400250
Jean-Marc Valin06237d72011-09-01 13:20:40 -0400251 OPUS_CLEAR((char*)st, opus_custom_encoder_get_size(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 Valin663a7fe2011-09-06 14:05:19 -0400265 st->bitrate = OPUS_BITRATE_MAX;
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500266 st->vbr = 0;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -0400267 st->force_intra = 0;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -0400268 st->complexity = 5;
Jean-Marc Valina76a0b22008-01-17 22:43:05 +1100269
Jean-Marc Valin8298cbb2011-11-06 23:27:16 -0500270 opus_custom_encoder_ctl(st, OPUS_RESET_STATE);
271
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400272 return OPUS_OK;
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100273}
274
Jean-Marc Valin06237d72011-09-01 13:20:40 -0400275#ifdef CUSTOM_MODES
276void opus_custom_encoder_destroy(CELTEncoder *st)
Jean-Marc Valin14191b32007-11-30 12:15:49 +1100277{
Jean-Marc Valin07f88402011-08-29 15:08:51 -0400278 opus_free(st);
Jean-Marc Valin14191b32007-11-30 12:15:49 +1100279}
Jean-Marc Valin06237d72011-09-01 13:20:40 -0400280#endif /* CUSTOM_MODES */
Jean-Marc Valin14191b32007-11-30 12:15:49 +1100281
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400282static inline opus_val16 SIG2WORD16(celt_sig x)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -0400283{
284#ifdef FIXED_POINT
Jean-Marc Valin42074382008-02-27 11:08:53 +1100285 x = PSHR32(x, SIG_SHIFT);
Jean-Marc Valinabdfc382008-04-18 15:57:18 +1000286 x = MAX32(x, -32768);
287 x = MIN32(x, 32767);
Jean-Marc Valin42074382008-02-27 11:08:53 +1100288 return EXTRACT16(x);
289#else
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400290 return (opus_val16)x;
Jean-Marc Valin42074382008-02-27 11:08:53 +1100291#endif
292}
293
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400294static int transient_analysis(const opus_val32 * restrict in, int len, int C,
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -0500295 int overlap)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000296{
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500297 int i;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400298 VARDECL(opus_val16, tmp);
299 opus_val32 mem0=0,mem1=0;
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500300 int is_transient = 0;
301 int block;
302 int N;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400303 VARDECL(opus_val16, bins);
Jean-Marc Valin0ceccb22008-07-03 20:41:06 -0400304 SAVE_STACK;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400305 ALLOC(tmp, len, opus_val16);
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400306
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500307 block = overlap/2;
308 N=len/block;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400309 ALLOC(bins, N, opus_val16);
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400310 if (C==1)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000311 {
312 for (i=0;i<len;i++)
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400313 tmp[i] = SHR32(in[i],SIG_SHIFT);
Jean-Marc Valin9c30de52010-04-19 13:32:15 -0400314 } else {
315 for (i=0;i<len;i++)
Jean-Marc Valin933dd832010-10-24 00:08:16 -0400316 tmp[i] = SHR32(ADD32(in[i],in[i+len]), SIG_SHIFT+1);
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000317 }
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400318
319 /* High-pass filter: (1 - 2*z^-1 + z^-2) / (1 - z^-1 + .5*z^-2) */
320 for (i=0;i<len;i++)
321 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400322 opus_val32 x,y;
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400323 x = tmp[i];
324 y = ADD32(mem0, x);
325#ifdef FIXED_POINT
326 mem0 = mem1 + y - SHL32(x,1);
327 mem1 = x - SHR32(y,1);
328#else
329 mem0 = mem1 + y - 2*x;
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400330 mem1 = x - .5f*y;
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400331#endif
332 tmp[i] = EXTRACT16(SHR(y,2));
333 }
334 /* First few samples are bad because we don't propagate the memory */
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500335 for (i=0;i<12;i++)
Jean-Marc Valin2794b632010-10-13 17:32:57 -0400336 tmp[i] = 0;
337
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500338 for (i=0;i<N;i++)
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000339 {
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500340 int j;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400341 opus_val16 max_abs=0;
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500342 for (j=0;j<block;j++)
Jean-Marc Valin168888f2011-03-02 17:26:48 -0500343 max_abs = MAX16(max_abs, ABS16(tmp[i*block+j]));
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500344 bins[i] = max_abs;
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000345 }
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500346 for (i=0;i<N;i++)
Jean-Marc Valin4a8c1f12010-10-13 18:03:50 -0400347 {
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500348 int j;
349 int conseq=0;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400350 opus_val16 t1, t2, t3;
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500351
352 t1 = MULT16_16_Q15(QCONST16(.15f, 15), bins[i]);
353 t2 = MULT16_16_Q15(QCONST16(.4f, 15), bins[i]);
354 t3 = MULT16_16_Q15(QCONST16(.15f, 15), bins[i]);
355 for (j=0;j<i;j++)
356 {
357 if (bins[j] < t1)
358 conseq++;
359 if (bins[j] < t2)
360 conseq++;
361 else
362 conseq = 0;
363 }
364 if (conseq>=3)
365 is_transient=1;
366 conseq = 0;
367 for (j=i+1;j<N;j++)
368 {
369 if (bins[j] < t3)
370 conseq++;
371 else
372 conseq = 0;
373 }
374 if (conseq>=7)
375 is_transient=1;
Jean-Marc Valin4a8c1f12010-10-13 18:03:50 -0400376 }
Jean-Marc Valin0ceccb22008-07-03 20:41:06 -0400377 RESTORE_STACK;
Jean-Marc Valinf334c822011-08-11 16:21:58 -0400378#ifdef FUZZING
379 is_transient = rand()&0x1;
380#endif
Jean-Marc Valinfddc5212010-12-09 14:28:26 -0500381 return is_transient;
Jean-Marc Valin9375aa42008-06-27 07:57:35 +1000382}
383
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400384/** Apply window and compute the MDCT for all sub-frames and
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400385 all channels in a frame */
Ralph Giles120800f2011-11-25 13:02:00 -0800386static 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 +1100387{
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000388 if (C==1 && !shortBlocks)
Jean-Marc Valinda721882007-11-30 15:17:42 +1100389 {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000390 const int overlap = OVERLAP(mode);
Jean-Marc Valina6b4e252011-08-15 10:20:06 -0400391 clt_mdct_forward(&mode->mdct, in, out, mode->window, overlap, mode->maxLM-LM, 1);
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400392 } else {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000393 const int overlap = OVERLAP(mode);
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400394 int N = mode->shortMdctSize<<LM;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400395 int B = 1;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000396 int b, c;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400397 if (shortBlocks)
398 {
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400399 N = mode->shortMdctSize;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400400 B = shortBlocks;
Jean-Marc Valinaa4f58b2009-10-03 09:27:59 -0400401 }
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400402 c=0; do {
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000403 for (b=0;b<B;b++)
404 {
Jean-Marc Valina6b4e252011-08-15 10:20:06 -0400405 /* Interleaving the sub-frames while doing the MDCTs */
406 clt_mdct_forward(&mode->mdct, in+c*(B*N+overlap)+b*N, &out[b+c*N*B], mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM, B);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000407 }
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400408 } while (++c<C);
Jean-Marc Valinda721882007-11-30 15:17:42 +1100409 }
Jean-Marc Valinda721882007-11-30 15:17:42 +1100410}
411
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400412/** Compute the IMDCT and apply window for all sub-frames and
Jean-Marc Valin56522ad2009-06-05 17:17:25 -0400413 all channels in a frame */
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -0400414static void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig *X,
Jean-Marc Valin7a08ddd2010-10-18 14:55:42 -0400415 celt_sig * restrict out_mem[],
Ralph Giles120800f2011-11-25 13:02:00 -0800416 celt_sig * restrict overlap_mem[], int C, int LM)
Jean-Marc Valin1677aa92007-12-08 01:13:34 +1100417{
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -0400418 int c;
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400419 const int N = mode->shortMdctSize<<LM;
Jean-Marc Valinb18ec0b2008-04-11 04:07:52 +1000420 const int overlap = OVERLAP(mode);
Jean-Marc Valindbeb86f2011-08-15 10:01:00 -0400421 VARDECL(opus_val32, x);
422 SAVE_STACK;
423
424 ALLOC(x, N+overlap, opus_val32);
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400425 c=0; do {
Jean-Marc Valinb886ddc2008-03-25 14:38:55 +1100426 int j;
Jean-Marc Valindbeb86f2011-08-15 10:01:00 -0400427 int b;
428 int N2 = N;
429 int B = 1;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400430
Jean-Marc Valindbeb86f2011-08-15 10:01:00 -0400431 if (shortBlocks)
432 {
433 N2 = mode->shortMdctSize;
434 B = shortBlocks;
435 }
436 /* Prevents problems from the imdct doing the overlap-add */
Jean-Marc Valinbe89c392011-08-30 12:39:51 -0400437 OPUS_CLEAR(x, overlap);
Jean-Marc Valinde678582009-10-03 10:36:27 -0400438
Jean-Marc Valindbeb86f2011-08-15 10:01:00 -0400439 for (b=0;b<B;b++)
440 {
441 /* IMDCT on the interleaved the sub-frames */
442 clt_mdct_backward(&mode->mdct, &X[b+c*N2*B], x+N2*b, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM, B);
443 }
Jean-Marc Valinde678582009-10-03 10:36:27 -0400444
Jean-Marc Valindbeb86f2011-08-15 10:01:00 -0400445 for (j=0;j<overlap;j++)
446 out_mem[c][j] = x[j] + overlap_mem[c][j];
447 for (;j<N;j++)
448 out_mem[c][j] = x[j];
449 for (j=0;j<overlap;j++)
450 overlap_mem[c][j] = x[N+j];
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400451 } while (++c<C);
Jean-Marc Valindbeb86f2011-08-15 10:01:00 -0400452 RESTORE_STACK;
Jean-Marc Valin1677aa92007-12-08 01:13:34 +1100453}
454
Ralph Giles120800f2011-11-25 13:02:00 -0800455static 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 -0400456{
457 int c;
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500458 int count=0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400459 c=0; do {
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400460 int j;
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400461 celt_sig * restrict x;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400462 opus_val16 * restrict y;
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400463 celt_sig m = mem[c];
Jean-Marc Valinf67b4472010-08-27 01:32:40 -0400464 x =in[c];
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400465 y = pcm+c;
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400466 for (j=0;j<N;j++)
467 {
Jean-Marc Valinaf1fce92010-07-16 11:05:06 -0400468 celt_sig tmp = *x + m;
469 m = MULT16_32_Q15(coef[0], tmp)
470 - MULT16_32_Q15(coef[1], *x);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400471 tmp = SHL32(MULT16_32_Q15(coef[3], tmp), 2);
Jean-Marc Valin903dbf72010-08-26 20:06:49 -0400472 x++;
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500473 /* Technically the store could be moved outside of the if because
474 the stores we don't want will just be overwritten */
Jean-Marc Valin66820f32012-01-31 02:03:39 -0500475 if (count==0)
476 *y = SCALEOUT(SIG2WORD16(tmp));
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500477 if (++count==downsample)
478 {
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500479 y+=C;
480 count=0;
481 }
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400482 }
Jean-Marc Valin64209a32010-04-05 09:26:22 -0400483 mem[c] = m;
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400484 } while (++c<C);
Jean-Marc Valine12017e2009-10-03 13:57:31 -0400485}
486
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400487static void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
488 opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
489 const opus_val16 *window, int overlap)
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400490{
491 int i;
492 /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400493 opus_val16 g00, g01, g02, g10, g11, g12;
494 static const opus_val16 gains[3][3] = {
Jean-Marc Valin61f40412011-01-27 17:14:33 -0500495 {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
496 {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
497 {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500498 g00 = MULT16_16_Q15(g0, gains[tapset0][0]);
499 g01 = MULT16_16_Q15(g0, gains[tapset0][1]);
500 g02 = MULT16_16_Q15(g0, gains[tapset0][2]);
501 g10 = MULT16_16_Q15(g1, gains[tapset1][0]);
502 g11 = MULT16_16_Q15(g1, gains[tapset1][1]);
503 g12 = MULT16_16_Q15(g1, gains[tapset1][2]);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400504 for (i=0;i<overlap;i++)
505 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400506 opus_val16 f;
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400507 f = MULT16_16_Q15(window[i],window[i]);
508 y[i] = x[i]
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500509 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g00),x[i-T0])
510 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),x[i-T0-1])
511 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),x[i-T0+1])
512 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),x[i-T0-2])
513 + MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),x[i-T0+2])
514 + MULT16_32_Q15(MULT16_16_Q15(f,g10),x[i-T1])
515 + MULT16_32_Q15(MULT16_16_Q15(f,g11),x[i-T1-1])
516 + MULT16_32_Q15(MULT16_16_Q15(f,g11),x[i-T1+1])
517 + MULT16_32_Q15(MULT16_16_Q15(f,g12),x[i-T1-2])
518 + MULT16_32_Q15(MULT16_16_Q15(f,g12),x[i-T1+2]);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400519
520 }
521 for (i=overlap;i<N;i++)
522 y[i] = x[i]
Jean-Marc Valindfa847a2011-01-17 11:37:08 -0500523 + MULT16_32_Q15(g10,x[i-T1])
524 + MULT16_32_Q15(g11,x[i-T1-1])
525 + MULT16_32_Q15(g11,x[i-T1+1])
526 + MULT16_32_Q15(g12,x[i-T1-2])
527 + MULT16_32_Q15(g12,x[i-T1+2]);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400528}
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400529
Jean-Marc Valina8160dd2010-10-12 14:55:16 -0400530static const signed char tf_select_table[4][8] = {
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400531 {0, -1, 0, -1, 0,-1, 0,-1},
Jean-Marc Valin41a15e62010-12-27 16:33:38 -0500532 {0, -1, 0, -2, 1, 0, 1,-1},
533 {0, -2, 0, -3, 2, 0, 1,-1},
Jean-Marc Valin2b134012011-01-12 16:13:46 -0500534 {0, -2, 0, -3, 3, 0, 1,-1},
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400535};
536
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400537static opus_val32 l1_metric(const celt_norm *tmp, int N, int LM, int width)
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400538{
539 int i, j;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400540 static const opus_val16 sqrtM_1[4] = {Q15ONE, QCONST16(.70710678f,15), QCONST16(0.5f,15), QCONST16(0.35355339f,15)};
541 opus_val32 L1;
542 opus_val16 bias;
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400543 L1=0;
544 for (i=0;i<1<<LM;i++)
545 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400546 opus_val32 L2 = 0;
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400547 for (j=0;j<N>>LM;j++)
548 L2 = MAC16_16(L2, tmp[(j<<LM)+i], tmp[(j<<LM)+i]);
549 L1 += celt_sqrt(L2);
550 }
551 L1 = MULT16_32_Q15(sqrtM_1[LM], L1);
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400552 if (width==1)
553 bias = QCONST16(.12f,15)*LM;
554 else if (width==2)
555 bias = QCONST16(.05f,15)*LM;
556 else
557 bias = QCONST16(.02f,15)*LM;
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400558 L1 = MAC16_32_Q15(L1, bias, L1);
559 return L1;
560}
561
Gregory Maxwell06d57b22011-08-01 22:02:25 -0400562static int tf_analysis(const CELTMode *m, int len, int C, int isTransient,
563 int *tf_res, int nbCompressedBytes, celt_norm *X, int N0, int LM,
564 int *tf_sum)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400565{
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400566 int i;
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400567 VARDECL(int, metric);
568 int cost0;
569 int cost1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400570 VARDECL(int, path0);
571 VARDECL(int, path1);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400572 VARDECL(celt_norm, tmp);
573 int lambda;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400574 int tf_select=0;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400575 SAVE_STACK;
576
Jean-Marc Valin6bf3b0a2010-07-19 14:32:40 -0400577 if (nbCompressedBytes<15*C)
578 {
Jean-Marc Valina3a066c2010-11-04 15:15:54 -0400579 *tf_sum = 0;
Jean-Marc Valin6bf3b0a2010-07-19 14:32:40 -0400580 for (i=0;i<len;i++)
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400581 tf_res[i] = isTransient;
Jean-Marc Valin6bf3b0a2010-07-19 14:32:40 -0400582 return 0;
583 }
Jean-Marc Valin73319772010-05-28 21:12:39 -0400584 if (nbCompressedBytes<40)
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400585 lambda = 12;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400586 else if (nbCompressedBytes<60)
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400587 lambda = 6;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400588 else if (nbCompressedBytes<100)
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400589 lambda = 4;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400590 else
Jean-Marc Valin54fb7e52010-10-15 11:26:32 -0400591 lambda = 3;
Jean-Marc Valin73319772010-05-28 21:12:39 -0400592
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400593 ALLOC(metric, len, int);
594 ALLOC(tmp, (m->eBands[len]-m->eBands[len-1])<<LM, celt_norm);
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400595 ALLOC(path0, len, int);
596 ALLOC(path1, len, int);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400597
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400598 *tf_sum = 0;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400599 for (i=0;i<len;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400600 {
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400601 int j, k, N;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400602 opus_val32 L1, best_L1;
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400603 int best_level=0;
604 N = (m->eBands[i+1]-m->eBands[i])<<LM;
605 for (j=0;j<N;j++)
606 tmp[j] = X[j+(m->eBands[i]<<LM)];
Jean-Marc Valin20e4c6a2010-12-21 22:27:08 -0500607 /* Just add the right channel if we're in stereo */
Jean-Marc Valina3a066c2010-11-04 15:15:54 -0400608 if (C==2)
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400609 for (j=0;j<N;j++)
Jean-Marc Valina3a066c2010-11-04 15:15:54 -0400610 tmp[j] = ADD16(tmp[j],X[N0+j+(m->eBands[i]<<LM)]);
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400611 L1 = l1_metric(tmp, N, isTransient ? LM : 0, N>>LM);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400612 best_L1 = L1;
613 /*printf ("%f ", L1);*/
614 for (k=0;k<LM;k++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400615 {
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400616 int B;
617
618 if (isTransient)
619 B = (LM-k-1);
620 else
621 B = k+1;
622
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400623 if (isTransient)
624 haar1(tmp, N>>(LM-k), 1<<(LM-k));
625 else
626 haar1(tmp, N>>k, 1<<k);
627
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400628 L1 = l1_metric(tmp, N, B, N>>LM);
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400629
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400630 if (L1 < best_L1)
631 {
632 best_L1 = L1;
633 best_level = k+1;
634 }
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400635 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400636 /*printf ("%d ", isTransient ? LM-best_level : best_level);*/
637 if (isTransient)
638 metric[i] = best_level;
639 else
640 metric[i] = -best_level;
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400641 *tf_sum += metric[i];
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400642 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400643 /*printf("\n");*/
Jean-Marc Valin92675062011-09-11 22:00:46 -0400644 /* NOTE: Future optimized implementations could detect extreme transients and set
645 tf_select = 1 but so far we have not found a reliable way of making this useful */
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -0400646 tf_select = 0;
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400647
Jean-Marc Valin88232612010-05-28 18:01:02 -0400648 cost0 = 0;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400649 cost1 = isTransient ? 0 : lambda;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400650 /* Viterbi forward pass */
651 for (i=1;i<len;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400652 {
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400653 int curr0, curr1;
654 int from0, from1;
Jean-Marc Valin581fdba2010-05-28 06:56:23 -0400655
Jean-Marc Valin88232612010-05-28 18:01:02 -0400656 from0 = cost0;
657 from1 = cost1 + lambda;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400658 if (from0 < from1)
659 {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400660 curr0 = from0;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400661 path0[i]= 0;
662 } else {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400663 curr0 = from1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400664 path0[i]= 1;
665 }
666
Jean-Marc Valin88232612010-05-28 18:01:02 -0400667 from0 = cost0 + lambda;
668 from1 = cost1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400669 if (from0 < from1)
670 {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400671 curr1 = from0;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400672 path1[i]= 0;
673 } else {
Jean-Marc Valin88232612010-05-28 18:01:02 -0400674 curr1 = from1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400675 path1[i]= 1;
676 }
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400677 cost0 = curr0 + abs(metric[i]-tf_select_table[LM][4*isTransient+2*tf_select+0]);
678 cost1 = curr1 + abs(metric[i]-tf_select_table[LM][4*isTransient+2*tf_select+1]);
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400679 }
Jean-Marc Valin88232612010-05-28 18:01:02 -0400680 tf_res[len-1] = cost0 < cost1 ? 0 : 1;
Jean-Marc Valin9d420c52010-05-28 17:26:27 -0400681 /* Viterbi backward pass to check the decisions */
682 for (i=len-2;i>=0;i--)
683 {
684 if (tf_res[i+1] == 1)
685 tf_res[i] = path1[i+1];
686 else
687 tf_res[i] = path0[i+1];
688 }
Jean-Marc Valin71ae6d42010-06-27 21:55:08 -0400689 RESTORE_STACK;
Jean-Marc Valinf334c822011-08-11 16:21:58 -0400690#ifdef FUZZING
691 tf_select = rand()&0x1;
692 tf_res[0] = rand()&0x1;
693 for (i=1;i<len;i++)
694 tf_res[i] = tf_res[i-1] ^ ((rand()&0xF) == 0);
695#endif
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400696 return tf_select;
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -0400697}
698
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -0500699static 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 -0400700{
701 int curr, i;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800702 int tf_select_rsv;
703 int tf_changed;
704 int logp;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400705 opus_uint32 budget;
706 opus_uint32 tell;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800707 budget = enc->storage*8;
708 tell = ec_tell(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800709 logp = isTransient ? 2 : 4;
710 /* Reserve space to code the tf_select decision. */
711 tf_select_rsv = LM>0 && tell+logp+1 <= budget;
712 budget -= tf_select_rsv;
713 curr = tf_changed = 0;
714 for (i=start;i<end;i++)
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400715 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800716 if (tell+logp<=budget)
717 {
718 ec_enc_bit_logp(enc, tf_res[i] ^ curr, logp);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800719 tell = ec_tell(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800720 curr = tf_res[i];
721 tf_changed |= curr;
722 }
723 else
724 tf_res[i] = curr;
725 logp = isTransient ? 4 : 5;
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400726 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800727 /* Only code tf_select if it would actually make a difference. */
728 if (tf_select_rsv &&
729 tf_select_table[LM][4*isTransient+0+tf_changed]!=
730 tf_select_table[LM][4*isTransient+2+tf_changed])
731 ec_enc_bit_logp(enc, tf_select, 1);
732 else
733 tf_select = 0;
Jean-Marc Valin2ed5e672010-07-13 16:50:11 -0400734 for (i=start;i<end;i++)
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400735 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
Jean-Marc Valin0f8fc0b2010-10-12 23:25:58 -0400736 /*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 -0400737}
738
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -0500739static 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 -0400740{
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400741 int i, curr, tf_select;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800742 int tf_select_rsv;
743 int tf_changed;
744 int logp;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400745 opus_uint32 budget;
746 opus_uint32 tell;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800747
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800748 budget = dec->storage*8;
749 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800750 logp = isTransient ? 2 : 4;
751 tf_select_rsv = LM>0 && tell+logp+1<=budget;
752 budget -= tf_select_rsv;
753 tf_changed = curr = 0;
754 for (i=start;i<end;i++)
Timothy B. Terriberry509ad202010-12-27 18:20:20 -0800755 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800756 if (tell+logp<=budget)
757 {
758 curr ^= ec_dec_bit_logp(dec, logp);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800759 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800760 tf_changed |= curr;
761 }
762 tf_res[i] = curr;
763 logp = isTransient ? 4 : 5;
764 }
765 tf_select = 0;
766 if (tf_select_rsv &&
767 tf_select_table[LM][4*isTransient+0+tf_changed] !=
768 tf_select_table[LM][4*isTransient+2+tf_changed])
769 {
770 tf_select = ec_dec_bit_logp(dec, 1);
771 }
772 for (i=start;i<end;i++)
773 {
774 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
Timothy B. Terriberry509ad202010-12-27 18:20:20 -0800775 }
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400776}
777
Timothy B. Terriberryce6d0902011-02-01 17:41:12 -0800778static void init_caps(const CELTMode *m,int *cap,int LM,int C)
779{
780 int i;
781 for (i=0;i<m->nbEBands;i++)
782 {
783 int N;
784 N=(m->eBands[i+1]-m->eBands[i])<<LM;
785 cap[i] = (m->cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2;
786 }
787}
788
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400789static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X,
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400790 const opus_val16 *bandLogE, int end, int LM, int C, int N0)
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400791{
792 int i;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400793 opus_val32 diff=0;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500794 int c;
Jean-Marc Valin4b087df2010-11-30 21:08:31 -0500795 int trim_index = 5;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400796 if (C==2)
797 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400798 opus_val16 sum = 0; /* Q10 */
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400799 /* Compute inter-channel correlation for low frequencies */
800 for (i=0;i<8;i++)
801 {
802 int j;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400803 opus_val32 partial = 0;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400804 for (j=m->eBands[i]<<LM;j<m->eBands[i+1]<<LM;j++)
805 partial = MAC16_16(partial, X[j], X[N0+j]);
806 sum = ADD16(sum, EXTRACT16(SHR32(partial, 18)));
807 }
808 sum = MULT16_16_Q15(QCONST16(1.f/8, 15), sum);
809 /*printf ("%f\n", sum);*/
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400810 if (sum > QCONST16(.995f,10))
Jean-Marc Valin4b087df2010-11-30 21:08:31 -0500811 trim_index-=4;
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400812 else if (sum > QCONST16(.92f,10))
Jean-Marc Valin4b087df2010-11-30 21:08:31 -0500813 trim_index-=3;
814 else if (sum > QCONST16(.85f,10))
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400815 trim_index-=2;
Gregory Maxwell60c316b2010-11-04 20:14:19 -0400816 else if (sum > QCONST16(.8f,10))
Jean-Marc Valinc40addc2010-10-22 14:57:07 -0400817 trim_index-=1;
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400818 }
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500819
820 /* Estimate spectral tilt */
Gregory Maxwell9743bf32010-11-04 20:45:09 -0400821 c=0; do {
Gregory Maxwell7007f1b2011-02-08 16:17:47 -0500822 for (i=0;i<end-1;i++)
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400823 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400824 diff += bandLogE[i+c*m->nbEBands]*(opus_int32)(2+2*i-m->nbEBands);
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400825 }
Gregory Maxwellf93d81b2011-08-07 00:57:31 -0400826 } while (++c<C);
Jean-Marc Valin817220e2011-08-08 11:33:17 -0400827 /* We divide by two here to avoid making the tilt larger for stereo as a
828 result of a bug in the loop above */
829 diff /= 2*C*(end-1);
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400830 /*printf("%f\n", diff);*/
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500831 if (diff > QCONST16(2.f, DB_SHIFT))
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400832 trim_index--;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500833 if (diff > QCONST16(8.f, DB_SHIFT))
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400834 trim_index--;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500835 if (diff < -QCONST16(4.f, DB_SHIFT))
Jean-Marc Valin90377572010-10-22 15:12:01 -0400836 trim_index++;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500837 if (diff < -QCONST16(10.f, DB_SHIFT))
838 trim_index++;
839
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400840 if (trim_index<0)
841 trim_index = 0;
Jean-Marc Valin546dfa12010-12-10 17:18:17 -0500842 if (trim_index>10)
843 trim_index = 10;
Jean-Marc Valinf334c822011-08-11 16:21:58 -0400844#ifdef FUZZING
845 trim_index = rand()%11;
846#endif
Jean-Marc Valinc5792de2010-10-19 14:24:50 -0400847 return trim_index;
848}
849
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500850static int stereo_analysis(const CELTMode *m, const celt_norm *X,
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -0500851 int LM, int N0)
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500852{
853 int i;
854 int thetas;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400855 opus_val32 sumLR = EPSILON, sumMS = EPSILON;
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500856
857 /* Use the L1 norm to model the entropy of the L/R signal vs the M/S signal */
858 for (i=0;i<13;i++)
859 {
860 int j;
861 for (j=m->eBands[i]<<LM;j<m->eBands[i+1]<<LM;j++)
862 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400863 opus_val16 L, R, M, S;
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500864 L = X[j];
865 R = X[N0+j];
866 M = L+R;
867 S = L-R;
868 sumLR += EXTEND32(ABS16(L)) + EXTEND32(ABS16(R));
869 sumMS += EXTEND32(ABS16(M)) + EXTEND32(ABS16(S));
870 }
871 }
872 sumMS = MULT16_32_Q15(QCONST16(0.707107f, 15), sumMS);
873 thetas = 13;
874 /* We don't need thetas for lower bands with LM<=1 */
875 if (LM<=1)
876 thetas -= 8;
877 return MULT16_32_Q15((m->eBands[13]<<(LM+1))+thetas, sumMS)
878 > MULT16_32_Q15(m->eBands[13]<<(LM+1), sumLR);
879}
880
Jean-Marc Valin222494f2011-08-17 15:53:37 -0400881int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +1100882{
Jean-Marc Valin7a08ddd2010-10-18 14:55:42 -0400883 int i, c, N;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400884 opus_int32 bits;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800885 ec_enc _enc;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400886 VARDECL(celt_sig, in);
887 VARDECL(celt_sig, freq);
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400888 VARDECL(celt_norm, X);
889 VARDECL(celt_ener, bandE);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400890 VARDECL(opus_val16, bandLogE);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400891 VARDECL(int, fine_quant);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400892 VARDECL(opus_val16, error);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400893 VARDECL(int, pulses);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -0800894 VARDECL(int, cap);
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400895 VARDECL(int, offsets);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -0400896 VARDECL(int, fine_priority);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -0400897 VARDECL(int, tf_res);
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -0800898 VARDECL(unsigned char, collapse_masks);
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400899 celt_sig *prefilter_mem;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400900 opus_val16 *oldBandE, *oldLogE, *oldLogE2;
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000901 int shortBlocks=0;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -0400902 int isTransient=0;
Ralph Giles120800f2011-11-25 13:02:00 -0800903 const int CC = st->channels;
904 const int C = st->stream_channels;
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400905 int LM, M;
Jean-Marc Valin890a9c02010-06-13 08:06:28 -0400906 int tf_select;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400907 int nbFilledBytes, nbAvailableBytes;
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400908 int effEnd;
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400909 int codedBands;
Jean-Marc Valinccd5a612010-10-13 01:11:55 -0400910 int tf_sum;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -0400911 int alloc_trim;
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -0500912 int pitch_index=COMBFILTER_MINPERIOD;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400913 opus_val16 gain1 = 0;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -0500914 int intensity=0;
Jean-Marc Valine65978f2010-12-02 13:46:48 -0500915 int dual_stereo=0;
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -0500916 int effectiveBytes;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400917 opus_val16 pf_threshold;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800918 int dynalloc_logp;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400919 opus_int32 vbr_rate;
920 opus_int32 total_bits;
921 opus_int32 total_boost;
922 opus_int32 balance;
923 opus_int32 tell;
Jean-Marc Valin8d367022011-01-17 16:37:51 -0500924 int prefilter_tapset=0;
925 int pf_on;
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -0800926 int anti_collapse_rsv;
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -0500927 int anti_collapse_on=0;
Jean-Marc Valinde79c372011-01-26 09:24:33 -0500928 int silence=0;
Jean-Marc Valinf62b3bb2011-03-09 11:56:29 -0500929 ALLOC_STACK;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100930
Jean-Marc Valinb3dae4b2011-02-04 21:50:54 -0500931 if (nbCompressedBytes<2 || pcm==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400932 return OPUS_BAD_ARG;
Gregory Maxwell520eeae2009-02-09 01:33:21 -0500933
Jean-Marc Valin913a1742011-01-29 10:00:20 -0500934 frame_size *= st->upsample;
Gregory Maxwell95becbe2011-02-03 21:06:43 -0500935 for (LM=0;LM<=st->mode->maxLM;LM++)
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400936 if (st->mode->shortMdctSize<<LM==frame_size)
937 break;
Gregory Maxwell95becbe2011-02-03 21:06:43 -0500938 if (LM>st->mode->maxLM)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400939 return OPUS_BAD_ARG;
Jean-Marc Valin017fa852010-05-06 22:11:48 -0400940 M=1<<LM;
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500941 N = M*st->mode->shortMdctSize;
Jean-Marc Valin8679a802008-10-18 07:44:35 -0400942
Jean-Marc Valin00a98f52011-01-31 11:19:03 -0500943 prefilter_mem = st->in_mem+CC*(st->overlap);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400944 oldBandE = (opus_val16*)(st->in_mem+CC*(2*st->overlap+COMBFILTER_MAXPERIOD));
Jean-Marc Valin00a98f52011-01-31 11:19:03 -0500945 oldLogE = oldBandE + CC*st->mode->nbEBands;
946 oldLogE2 = oldLogE + CC*st->mode->nbEBands;
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -0400947
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400948 if (enc==NULL)
949 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800950 tell=1;
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400951 nbFilledBytes=0;
952 } else {
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -0800953 tell=ec_tell(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800954 nbFilledBytes=(tell+4)>>3;
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -0400955 }
Jean-Marc Valine6acfe02011-03-11 16:31:24 -0500956
Gregory Maxwellfd17eab2011-10-04 03:31:45 -0400957#ifdef CUSTOM_MODES
Jean-Marc Valine6acfe02011-03-11 16:31:24 -0500958 if (st->signalling && enc==NULL)
959 {
960 int tmp = (st->mode->effEBands-st->end)>>1;
961 st->end = IMAX(1, st->mode->effEBands-tmp);
962 compressed[0] = tmp<<5;
963 compressed[0] |= LM<<3;
964 compressed[0] |= (C==2)<<2;
Jean-Marc Valind6bf19d2011-03-21 07:06:09 -0400965 /* Convert "standard mode" to Opus header */
966 if (st->mode->Fs==48000 && st->mode->shortMdctSize==120)
967 {
968 int c0 = toOpus(compressed[0]);
969 if (c0<0)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400970 return OPUS_BAD_ARG;
Jean-Marc Valind6bf19d2011-03-21 07:06:09 -0400971 compressed[0] = c0;
972 }
Jean-Marc Valine6acfe02011-03-11 16:31:24 -0500973 compressed++;
974 nbCompressedBytes--;
975 }
Gregory Maxwellfd17eab2011-10-04 03:31:45 -0400976#else
977 celt_assert(st->signalling==0);
978#endif
Jean-Marc Valine6acfe02011-03-11 16:31:24 -0500979
980 /* Can't produce more than 1275 output bytes */
981 nbCompressedBytes = IMIN(nbCompressedBytes,1275);
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -0400982 nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
983
Jean-Marc Valin663a7fe2011-09-06 14:05:19 -0400984 if (st->vbr && st->bitrate!=OPUS_BITRATE_MAX)
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500985 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400986 opus_int32 den=st->mode->Fs>>BITRES;
Jean-Marc Valin23340e22011-02-03 23:21:00 -0500987 vbr_rate=(st->bitrate*frame_size+(den>>1))/den;
Gregory Maxwellfd17eab2011-10-04 03:31:45 -0400988#ifdef CUSTOM_MODES
Jean-Marc Valine6acfe02011-03-11 16:31:24 -0500989 if (st->signalling)
990 vbr_rate -= 8<<BITRES;
Gregory Maxwellfd17eab2011-10-04 03:31:45 -0400991#endif
Jean-Marc Valin3beb70e2011-03-01 18:08:15 -0500992 effectiveBytes = vbr_rate>>(3+BITRES);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500993 } else {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400994 opus_int32 tmp;
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -0500995 vbr_rate = 0;
996 tmp = st->bitrate*frame_size;
997 if (tell>1)
998 tmp += tell;
Jean-Marc Valin663a7fe2011-09-06 14:05:19 -0400999 if (st->bitrate!=OPUS_BITRATE_MAX)
Jean-Marc Valin66ff26f2011-08-15 22:37:11 -04001000 nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes,
1001 (tmp+4*st->mode->Fs)/(8*st->mode->Fs)-!!st->signalling));
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001002 effectiveBytes = nbCompressedBytes;
1003 }
1004
1005 if (enc==NULL)
1006 {
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001007 ec_enc_init(&_enc, compressed, nbCompressedBytes);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001008 enc = &_enc;
1009 }
1010
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001011 if (vbr_rate>0)
1012 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001013 /* Computes the max bit-rate allowed in VBR mode to avoid violating the
1014 target rate and buffering.
1015 We must do this up front so that bust-prevention logic triggers
1016 correctly if we don't have enough bits. */
1017 if (st->constrained_vbr)
1018 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001019 opus_int32 vbr_bound;
1020 opus_int32 max_allowed;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001021 /* We could use any multiple of vbr_rate as bound (depending on the
1022 delay).
Gregory Maxwell420c3252011-01-27 22:35:50 -05001023 This is clamped to ensure we use at least two bytes if the encoder
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001024 was entirely empty, but to allow 0 in hybrid mode. */
1025 vbr_bound = vbr_rate;
Gregory Maxwell420c3252011-01-27 22:35:50 -05001026 max_allowed = IMIN(IMAX(tell==1?2:0,
Gregory Maxwell75d27802011-08-30 14:02:41 -04001027 (vbr_rate+vbr_bound-st->vbr_reservoir)>>(BITRES+3)),
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001028 nbAvailableBytes);
1029 if(max_allowed < nbAvailableBytes)
1030 {
1031 nbCompressedBytes = nbFilledBytes+max_allowed;
1032 nbAvailableBytes = max_allowed;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001033 ec_enc_shrink(enc, nbCompressedBytes);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001034 }
1035 }
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001036 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001037 total_bits = nbCompressedBytes*8;
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001038
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001039 effEnd = st->end;
1040 if (effEnd > st->mode->effEBands)
1041 effEnd = st->mode->effEBands;
1042
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001043 ALLOC(in, CC*(N+st->overlap), celt_sig);
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001044
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001045 /* Find pitch period and gain */
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +11001046 {
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001047 VARDECL(celt_sig, _pre);
1048 celt_sig *pre[2];
1049 SAVE_STACK;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001050 ALLOC(_pre, CC*(N+COMBFILTER_MAXPERIOD), celt_sig);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001051
1052 pre[0] = _pre;
1053 pre[1] = _pre + (N+COMBFILTER_MAXPERIOD);
1054
Jean-Marc Valinde79c372011-01-26 09:24:33 -05001055 silence = 1;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001056 c=0; do {
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001057 int count = 0;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001058 const opus_val16 * restrict pcmp = pcm+c;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001059 celt_sig * restrict inp = in+c*(N+st->overlap)+st->overlap;
1060
1061 for (i=0;i<N;i++)
1062 {
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001063 celt_sig x, tmp;
1064
1065 x = SCALEIN(*pcmp);
Jean-Marc Valin0b405d12011-02-04 01:03:42 -05001066#ifndef FIXED_POINT
Gregory Maxwell58ecb1a2011-05-09 13:16:30 -04001067 if (!(x==x))
1068 x = 0;
Jean-Marc Valin0b405d12011-02-04 01:03:42 -05001069 if (st->clip)
1070 x = MAX32(-65536.f, MIN32(65536.f,x));
1071#endif
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001072 if (++count==st->upsample)
1073 {
1074 count=0;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001075 pcmp+=CC;
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001076 } else {
1077 x = 0;
1078 }
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001079 /* Apply pre-emphasis */
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001080 tmp = MULT16_16(st->mode->preemph[2], x);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001081 *inp = tmp + st->preemph_memE[c];
1082 st->preemph_memE[c] = MULT16_32_Q15(st->mode->preemph[1], *inp)
1083 - MULT16_32_Q15(st->mode->preemph[0], tmp);
Jean-Marc Valinde79c372011-01-26 09:24:33 -05001084 silence = silence && *inp == 0;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001085 inp++;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001086 }
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001087 OPUS_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD);
1088 OPUS_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+st->overlap)+st->overlap, N);
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001089 } while (++c<CC);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001090
Jean-Marc Valinf334c822011-08-11 16:21:58 -04001091#ifdef FUZZING
1092 if ((rand()&0x3F)==0)
1093 silence = 1;
1094#endif
Jean-Marc Valin65d35a32011-01-26 22:04:59 -05001095 if (tell==1)
1096 ec_enc_bit_logp(enc, silence, 15);
1097 else
1098 silence=0;
Jean-Marc Valinde79c372011-01-26 09:24:33 -05001099 if (silence)
1100 {
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001101 /*In VBR mode there is no need to send more than the minimum. */
1102 if (vbr_rate>0)
1103 {
Jean-Marc Valin65d35a32011-01-26 22:04:59 -05001104 effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2);
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001105 total_bits=nbCompressedBytes*8;
1106 nbAvailableBytes=2;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001107 ec_enc_shrink(enc, nbCompressedBytes);
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001108 }
Jean-Marc Valin13a7c262011-01-26 10:58:33 -05001109 /* Pretend we've filled all the remaining bits with zeros
1110 (that's what the initialiser did anyway) */
Jean-Marc Valinde79c372011-01-26 09:24:33 -05001111 tell = nbCompressedBytes*8;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001112 enc->nbits_total+=tell-ec_tell(enc);
Jean-Marc Valinde79c372011-01-26 09:24:33 -05001113 }
Jean-Marc Valind539c6b2011-02-03 13:36:03 -05001114 if (nbAvailableBytes>12*C && st->start==0 && !silence && !st->disable_pf && st->complexity >= 5)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001115 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001116 VARDECL(opus_val16, pitch_buf);
1117 ALLOC(pitch_buf, (COMBFILTER_MAXPERIOD+N)>>1, opus_val16);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001118
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001119 pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC);
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05001120 pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N,
Jean-Marc Valine3e2c262011-01-26 13:09:53 -05001121 COMBFILTER_MAXPERIOD-COMBFILTER_MINPERIOD, &pitch_index);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001122 pitch_index = COMBFILTER_MAXPERIOD-pitch_index;
1123
1124 gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD,
1125 N, &pitch_index, st->prefilter_period, st->prefilter_gain);
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001126 if (pitch_index > COMBFILTER_MAXPERIOD-2)
1127 pitch_index = COMBFILTER_MAXPERIOD-2;
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -05001128 gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1);
Jean-Marc Valin69653882011-04-21 10:41:13 -04001129 if (st->loss_rate>2)
1130 gain1 = HALF32(gain1);
1131 if (st->loss_rate>4)
1132 gain1 = HALF32(gain1);
1133 if (st->loss_rate>8)
1134 gain1 = 0;
Jean-Marc Valin8d367022011-01-17 16:37:51 -05001135 prefilter_tapset = st->tapset_decision;
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -05001136 } else {
1137 gain1 = 0;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001138 }
Jean-Marc Valin6ba0b352010-12-20 11:40:30 -05001139
1140 /* Gain threshold for enabling the prefilter/postfilter */
1141 pf_threshold = QCONST16(.2f,15);
1142
1143 /* Adjusting the threshold based on rate and continuity */
1144 if (abs(pitch_index-st->prefilter_period)*10>pitch_index)
1145 pf_threshold += QCONST16(.2f,15);
1146 if (nbAvailableBytes<25)
1147 pf_threshold += QCONST16(.1f,15);
1148 if (nbAvailableBytes<35)
1149 pf_threshold += QCONST16(.1f,15);
1150 if (st->prefilter_gain > QCONST16(.4f,15))
1151 pf_threshold -= QCONST16(.1f,15);
1152 if (st->prefilter_gain > QCONST16(.55f,15))
1153 pf_threshold -= QCONST16(.1f,15);
1154
1155 /* Hard threshold at 0.2 */
1156 pf_threshold = MAX16(pf_threshold, QCONST16(.2f,15));
1157 if (gain1<pf_threshold)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001158 {
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001159 if(st->start==0 && tell+16<=total_bits)
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001160 ec_enc_bit_logp(enc, 0, 1);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001161 gain1 = 0;
Jean-Marc Valin8d367022011-01-17 16:37:51 -05001162 pf_on = 0;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001163 } else {
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001164 /*This block is not gated by a total bits check only because
1165 of the nbAvailableBytes check above.*/
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001166 int qg;
1167 int octave;
Jean-Marc Valin6ba0b352010-12-20 11:40:30 -05001168
Jean-Marc Valinb417d832011-01-27 17:19:49 -05001169 if (ABS16(gain1-st->prefilter_gain)<QCONST16(.1f,15))
Jean-Marc Valin6ba0b352010-12-20 11:40:30 -05001170 gain1=st->prefilter_gain;
1171
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001172#ifdef FIXED_POINT
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001173 qg = ((gain1+1536)>>10)/3-1;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001174#else
Gregory Maxwell662587d2011-08-01 20:41:54 -04001175 qg = (int)floor(.5f+gain1*32/3)-1;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001176#endif
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001177 qg = IMAX(0, IMIN(7, qg));
Timothy B. Terriberrye86fb262010-12-17 14:50:19 -08001178 ec_enc_bit_logp(enc, 1, 1);
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001179 pitch_index += 1;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001180 octave = EC_ILOG(pitch_index)-5;
1181 ec_enc_uint(enc, octave, 6);
1182 ec_enc_bits(enc, pitch_index-(16<<octave), 4+octave);
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001183 pitch_index -= 1;
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001184 ec_enc_bits(enc, qg, 3);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001185 if (ec_tell(enc)+2<=total_bits)
Jean-Marc Valinef986e42011-02-03 15:47:10 -05001186 ec_enc_icdf(enc, prefilter_tapset, tapset_icdf, 2);
1187 else
1188 prefilter_tapset = 0;
1189 gain1 = QCONST16(0.09375f,15)*(qg+1);
Jean-Marc Valin8d367022011-01-17 16:37:51 -05001190 pf_on = 1;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001191 }
1192 /*printf("%d %f\n", pitch_index, gain1);*/
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001193
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001194 c=0; do {
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05001195 int offset = st->mode->shortMdctSize-st->mode->overlap;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001196 st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001197 OPUS_COPY(in+c*(N+st->overlap), st->in_mem+c*(st->overlap), st->overlap);
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05001198 if (offset)
1199 comb_filter(in+c*(N+st->overlap)+st->overlap, pre[c]+COMBFILTER_MAXPERIOD,
1200 st->prefilter_period, st->prefilter_period, offset, -st->prefilter_gain, -st->prefilter_gain,
1201 st->prefilter_tapset, st->prefilter_tapset, NULL, 0);
1202
1203 comb_filter(in+c*(N+st->overlap)+st->overlap+offset, pre[c]+COMBFILTER_MAXPERIOD+offset,
1204 st->prefilter_period, pitch_index, N-offset, -st->prefilter_gain, -gain1,
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001205 st->prefilter_tapset, prefilter_tapset, st->mode->window, st->mode->overlap);
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001206 OPUS_COPY(st->in_mem+c*(st->overlap), in+c*(N+st->overlap)+N, st->overlap);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001207
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001208 if (N>COMBFILTER_MAXPERIOD)
1209 {
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001210 OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001211 } else {
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001212 OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, prefilter_mem+c*COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD-N);
1213 OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001214 }
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001215 } while (++c<CC);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001216
1217 RESTORE_STACK;
Jean-Marc Valin6f7e83d2007-12-01 00:36:41 +11001218 }
Jean-Marc Valin2014ca32009-06-18 23:33:04 -04001219
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001220 isTransient = 0;
1221 shortBlocks = 0;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001222 if (LM>0 && ec_tell(enc)+3<=total_bits)
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001223 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001224 if (st->complexity > 1)
1225 {
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001226 isTransient = transient_analysis(in, N+st->overlap, CC,
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05001227 st->overlap);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001228 if (isTransient)
1229 shortBlocks = M;
1230 }
1231 ec_enc_bit_logp(enc, isTransient, 3);
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001232 }
Jean-Marc Valinc5f2a9d2008-10-26 22:00:26 -04001233
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001234 ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */
1235 ALLOC(bandE,st->mode->nbEBands*CC, celt_ener);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001236 ALLOC(bandLogE,st->mode->nbEBands*CC, opus_val16);
Jean-Marc Valin32ec58c2009-05-01 21:28:58 -04001237 /* Compute MDCTs */
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001238 compute_mdcts(st->mode, shortBlocks, in, freq, CC, LM);
Jean-Marc Valin08a82ff2009-06-14 14:05:19 -04001239
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001240 if (CC==2&&C==1)
1241 {
1242 for (i=0;i<N;i++)
1243 freq[i] = ADD32(HALF32(freq[i]), HALF32(freq[N+i]));
1244 }
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001245 if (st->upsample != 1)
1246 {
1247 c=0; do
1248 {
1249 int bound = N/st->upsample;
1250 for (i=0;i<bound;i++)
1251 freq[c*N+i] *= st->upsample;
1252 for (;i<N;i++)
1253 freq[c*N+i] = 0;
1254 } while (++c<C);
1255 }
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001256 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
Jean-Marc Valin8d4ac152008-02-29 17:24:02 +11001257
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001258 compute_band_energies(st->mode, freq, bandE, effEnd, C, M);
Jean-Marc Valin504fb3c2010-08-06 15:56:22 -04001259
1260 amp2Log2(st->mode, effEnd, st->end, bandE, bandLogE, C);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001261
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11001262 /* Band normalisation */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001263 normalise_bands(st->mode, freq, X, bandE, effEnd, C, M);
Jean-Marc Valin4c77ea92009-09-14 22:50:41 -04001264
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -04001265 ALLOC(tf_res, st->mode->nbEBands, int);
Gregory Maxwell06d57b22011-08-01 22:02:25 -04001266 tf_select = tf_analysis(st->mode, effEnd, C, isTransient, tf_res, effectiveBytes, X, N, LM, &tf_sum);
Jean-Marc Valin8200b2d2010-10-15 02:18:47 -04001267 for (i=effEnd;i<st->end;i++)
1268 tf_res[i] = tf_res[effEnd-1];
1269
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001270 ALLOC(error, C*st->mode->nbEBands, opus_val16);
Jean-Marc Valin5e7f02d2010-08-08 09:48:22 -04001271 quant_coarse_energy(st->mode, st->start, st->end, effEnd, bandLogE,
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001272 oldBandE, total_bits, error, enc,
Timothy B. Terriberryef2e6502010-11-09 01:43:18 -08001273 C, LM, nbAvailableBytes, st->force_intra,
Jean-Marc Valineda2dee2011-04-21 16:04:27 -04001274 &st->delayedIntra, st->complexity >= 4, st->loss_rate);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001275
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001276 tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc);
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001277
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001278 st->spread_decision = SPREAD_NORMAL;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001279 if (ec_tell(enc)+4<=total_bits)
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -04001280 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001281 if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C)
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001282 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001283 if (st->complexity == 0)
1284 st->spread_decision = SPREAD_NONE;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001285 } else {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001286 st->spread_decision = spreading_decision(st->mode, X,
Jean-Marc Valin8d367022011-01-17 16:37:51 -05001287 &st->tonal_average, st->spread_decision, &st->hf_average,
1288 &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M);
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001289 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001290 ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5);
Jean-Marc Valin1d17b9a2010-08-31 14:51:58 -04001291 }
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04001292
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001293 ALLOC(cap, st->mode->nbEBands, int);
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001294 ALLOC(offsets, st->mode->nbEBands, int);
1295
Timothy B. Terriberryce6d0902011-02-01 17:41:12 -08001296 init_caps(st->mode,cap,LM,C);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001297 for (i=0;i<st->mode->nbEBands;i++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001298 offsets[i] = 0;
1299 /* Dynamic allocation code */
1300 /* Make sure that dynamic allocation can't make us bust the budget */
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001301 if (effectiveBytes > 50 && LM>=1)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001302 {
1303 int t1, t2;
1304 if (LM <= 1)
1305 {
1306 t1 = 3;
1307 t2 = 5;
1308 } else {
1309 t1 = 2;
1310 t2 = 4;
1311 }
Gregory Maxwell7007f1b2011-02-08 16:17:47 -05001312 for (i=st->start+1;i<st->end-1;i++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001313 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001314 opus_val32 d2;
Jean-Marc Valina3a066c2010-11-04 15:15:54 -04001315 d2 = 2*bandLogE[i]-bandLogE[i-1]-bandLogE[i+1];
1316 if (C==2)
1317 d2 = HALF32(d2 + 2*bandLogE[i+st->mode->nbEBands]-
1318 bandLogE[i-1+st->mode->nbEBands]-bandLogE[i+1+st->mode->nbEBands]);
Jean-Marc Valinf334c822011-08-11 16:21:58 -04001319#ifdef FUZZING
1320 if((rand()&0xF)==0)
1321 {
1322 offsets[i] += 1;
1323 if((rand()&0x3)==0)
1324 offsets[i] += 1+(rand()&0x3);
1325 }
1326#else
Jean-Marc Valina3a066c2010-11-04 15:15:54 -04001327 if (d2 > SHL16(t1,DB_SHIFT))
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001328 offsets[i] += 1;
Jean-Marc Valina3a066c2010-11-04 15:15:54 -04001329 if (d2 > SHL16(t2,DB_SHIFT))
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001330 offsets[i] += 1;
Jean-Marc Valinf334c822011-08-11 16:21:58 -04001331#endif
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001332 }
1333 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001334 dynalloc_logp = 6;
1335 total_bits<<=BITRES;
1336 total_boost = 0;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001337 tell = ec_tell_frac(enc);
Timothy B. Terriberryd6f61572010-12-30 09:04:16 -08001338 for (i=st->start;i<st->end;i++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001339 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001340 int width, quanta;
1341 int dynalloc_loop_logp;
1342 int boost;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001343 int j;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001344 width = C*(st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
1345 /* quanta is 6 bits, but no more than 1 bit/sample
1346 and no less than 1/8 bit/sample */
1347 quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));
1348 dynalloc_loop_logp = dynalloc_logp;
1349 boost = 0;
1350 for (j = 0; tell+(dynalloc_loop_logp<<BITRES) < total_bits-total_boost
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001351 && boost < cap[i]; j++)
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001352 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001353 int flag;
1354 flag = j<offsets[i];
1355 ec_enc_bit_logp(enc, flag, dynalloc_loop_logp);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001356 tell = ec_tell_frac(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001357 if (!flag)
1358 break;
1359 boost += quanta;
1360 total_boost += quanta;
1361 dynalloc_loop_logp = 1;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001362 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001363 /* Making dynalloc more likely */
1364 if (j)
1365 dynalloc_logp = IMAX(2, dynalloc_logp-1);
1366 offsets[i] = boost;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001367 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001368 alloc_trim = 5;
1369 if (tell+(6<<BITRES) <= total_bits - total_boost)
1370 {
1371 alloc_trim = alloc_trim_analysis(st->mode, X, bandLogE,
Gregory Maxwell7007f1b2011-02-08 16:17:47 -05001372 st->end, LM, C, N);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001373 ec_enc_icdf(enc, alloc_trim, trim_icdf, 7);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001374 tell = ec_tell_frac(enc);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001375 }
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04001376
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001377 /* Variable bitrate */
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001378 if (vbr_rate>0)
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001379 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001380 opus_val16 alpha;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001381 opus_int32 delta;
Gregory Maxwella9411472010-10-28 03:52:21 -04001382 /* The target rate in 8th bits per frame */
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001383 opus_int32 target;
1384 opus_int32 min_allowed;
Gregory Maxwellde0b9772011-08-23 02:00:55 -04001385 int lm_diff = st->mode->maxLM - LM;
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001386
Gregory Maxwellde0b9772011-08-23 02:00:55 -04001387 target = vbr_rate + (st->vbr_offset>>lm_diff) - ((40*C+20)<<BITRES);
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001388
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001389 /* Shortblocks get a large boost in bitrate, but since they
Jean-Marc Valinccd5a612010-10-13 01:11:55 -04001390 are uncommon long blocks are not greatly affected */
1391 if (shortBlocks || tf_sum < -2*(st->end-st->start))
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001392 target = 7*target/4;
Jean-Marc Valinccd5a612010-10-13 01:11:55 -04001393 else if (tf_sum < -(st->end-st->start))
1394 target = 3*target/2;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04001395 else if (M > 1)
Jean-Marc Valinccd5a612010-10-13 01:11:55 -04001396 target-=(target+14)/28;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001397
Gregory Maxwella9411472010-10-28 03:52:21 -04001398 /* The current offset is removed from the target and the space used
1399 so far is added*/
Jean-Marc Valina4badac2010-12-03 15:20:11 -05001400 target=target+tell;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001401
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001402 /* In VBR mode the frame size must not be reduced so much that it would
1403 result in the encoder running out of bits.
1404 The margin of 2 bytes ensures that none of the bust-prevention logic
1405 in the decoder will have triggered so far. */
Gregory Maxwell75d27802011-08-30 14:02:41 -04001406 min_allowed = ((tell+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3)) + 2 - nbFilledBytes;
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001407
Gregory Maxwell75d27802011-08-30 14:02:41 -04001408 nbAvailableBytes = (target+(1<<(BITRES+2)))>>(BITRES+3);
Gregory Maxwelld85018c2011-01-13 14:38:24 -05001409 nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes);
1410 nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes) - nbFilledBytes;
Jean-Marc Valin6b565262011-01-12 11:27:03 -05001411
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001412 /* By how much did we "miss" the target on that frame */
1413 delta = target - vbr_rate;
1414
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001415 target=nbAvailableBytes<<(BITRES+3);
1416
Gregory Maxwellfdd86752011-04-13 17:08:22 -04001417 /*If the frame is silent we don't adjust our drift, otherwise
1418 the encoder will shoot to very high rates after hitting a
1419 span of silence, but we do allow the bitres to refill.
1420 This means that we'll undershoot our target in CVBR/VBR modes
1421 on files with lots of silence. */
1422 if(silence)
1423 {
1424 nbAvailableBytes = 2;
1425 target = 2*8<<BITRES;
1426 delta = 0;
1427 }
1428
Gregory Maxwella9411472010-10-28 03:52:21 -04001429 if (st->vbr_count < 970)
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001430 {
1431 st->vbr_count++;
Gregory Maxwella9411472010-10-28 03:52:21 -04001432 alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+20),16));
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001433 } else
1434 alpha = QCONST16(.001f,15);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001435 /* How many bits have we used in excess of what we're allowed */
Jean-Marc Valin9faf7402010-12-04 10:27:22 -05001436 if (st->constrained_vbr)
1437 st->vbr_reservoir += target - vbr_rate;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001438 /*printf ("%d\n", st->vbr_reservoir);*/
1439
1440 /* Compute the offset we need to apply in order to reach the target */
Jean-Marc Valin803ec8c2011-09-23 23:48:40 -04001441 st->vbr_drift += (opus_int32)MULT16_32_Q15(alpha,(delta*(1<<lm_diff))-st->vbr_offset-st->vbr_drift);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001442 st->vbr_offset = -st->vbr_drift;
1443 /*printf ("%d\n", st->vbr_drift);*/
1444
Jean-Marc Valin9faf7402010-12-04 10:27:22 -05001445 if (st->constrained_vbr && st->vbr_reservoir < 0)
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001446 {
1447 /* We're under the min value -- increase rate */
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001448 int adjust = (-st->vbr_reservoir)/(8<<BITRES);
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001449 /* Unless we're just coding silence */
1450 nbAvailableBytes += silence?0:adjust;
Gregory Maxwellfac6c982010-10-28 15:00:37 -04001451 st->vbr_reservoir = 0;
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001452 /*printf ("+%d\n", adjust);*/
1453 }
Gregory Maxwelld85018c2011-01-13 14:38:24 -05001454 nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes);
Jean-Marc Valinbd5d54a2009-10-20 00:25:31 -04001455 /* This moves the raw bits to take into account the new compressed size */
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001456 ec_enc_shrink(enc, nbCompressedBytes);
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001457 }
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001458 if (C==2)
1459 {
1460 int effectiveRate;
1461
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001462 /* Always use MS for 2.5 ms frames until we can do a better analysis */
1463 if (LM!=0)
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05001464 dual_stereo = stereo_analysis(st->mode, X, LM, N);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08001465
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001466 /* Account for coarse energy */
Jean-Marc Valine5e9aa72010-12-02 16:09:51 -05001467 effectiveRate = (8*effectiveBytes - 80)>>LM;
1468
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001469 /* effectiveRate in kb/s */
1470 effectiveRate = 2*effectiveRate/5;
1471 if (effectiveRate<35)
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -05001472 intensity = 8;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001473 else if (effectiveRate<50)
1474 intensity = 12;
1475 else if (effectiveRate<68)
1476 intensity = 16;
1477 else if (effectiveRate<84)
1478 intensity = 18;
1479 else if (effectiveRate<102)
1480 intensity = 19;
1481 else if (effectiveRate<130)
1482 intensity = 20;
1483 else
1484 intensity = 100;
1485 intensity = IMIN(st->end,IMAX(st->start, intensity));
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05001486 }
1487
Jean-Marc Valinbe04f5a2010-08-07 21:42:03 -04001488 /* Bit allocation */
1489 ALLOC(fine_quant, st->mode->nbEBands, int);
1490 ALLOC(pulses, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04001491 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +11001492
Timothy B. Terriberry285bc372011-02-06 13:29:00 -08001493 /* bits = packet size - where we are - safety*/
Gregory Maxwell75d27802011-08-30 14:02:41 -04001494 bits = (((opus_int32)nbCompressedBytes*8)<<BITRES) - ec_tell_frac(enc) - 1;
1495 anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0;
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08001496 bits -= anti_collapse_rsv;
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08001497 codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08001498 alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
1499 fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands);
Jean-Marc Valindfd6e712010-12-09 23:23:34 -05001500 st->lastCodedBands = codedBands;
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -05001501
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05001502 quant_fine_energy(st->mode, st->start, st->end, oldBandE, error, fine_quant, enc, C);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04001503
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +02001504#ifdef MEASURE_NORM_MSE
Jean-Marc Valin44092242010-07-29 18:32:54 +02001505 float X0[3000];
1506 float bandE0[60];
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001507 c=0; do
Jean-Marc Valin44092242010-07-29 18:32:54 +02001508 for (i=0;i<N;i++)
1509 X0[i+c*N] = X[i+c*N];
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001510 while (++c<C);
Jean-Marc Valin44092242010-07-29 18:32:54 +02001511 for (i=0;i<C*st->mode->nbEBands;i++)
Jean-Marc Valin7b5a0862010-07-29 15:01:24 +02001512 bandE0[i] = bandE[i];
1513#endif
1514
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11001515 /* Residual quantisation */
Jean-Marc Valin7e983192011-02-01 18:00:29 -05001516 ALLOC(collapse_masks, C*st->mode->nbEBands, unsigned char);
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08001517 quant_all_bands(1, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks,
Gregory Maxwelld830d082011-08-15 16:05:40 -04001518 bandE, pulses, shortBlocks, st->spread_decision, dual_stereo, intensity, tf_res,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08001519 nbCompressedBytes*(8<<BITRES)-anti_collapse_rsv, balance, enc, LM, codedBands, &st->rng);
Jean-Marc Valin39710532009-06-09 00:10:32 -04001520
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08001521 if (anti_collapse_rsv > 0)
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001522 {
1523 anti_collapse_on = st->consec_transient<2;
Jean-Marc Valinf334c822011-08-11 16:21:58 -04001524#ifdef FUZZING
1525 anti_collapse_on = rand()&0x1;
1526#endif
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001527 ec_enc_bits(enc, anti_collapse_on, 1);
1528 }
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001529 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 -04001530
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001531 if (silence)
1532 {
1533 for (i=0;i<C*st->mode->nbEBands;i++)
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001534 oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
Gregory Maxwell8b631f22011-01-26 20:19:01 -05001535 }
1536
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001537#ifdef RESYNTH
Jean-Marc Valin37ab9c62008-11-08 09:14:38 -05001538 /* Re-synthesis of the coded audio if required */
Jean-Marc Valin18ddc022008-02-22 14:24:50 +11001539 {
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001540 celt_sig *out_mem[2];
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001541 celt_sig *overlap_mem[2];
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001542
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001543 log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
Jean-Marc Valin4b000c32011-01-26 20:30:21 -05001544 if (silence)
1545 {
1546 for (i=0;i<C*st->mode->nbEBands;i++)
1547 bandE[i] = 0;
1548 }
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04001549
1550#ifdef MEASURE_NORM_MSE
1551 measure_norm_mse(st->mode, X, X0, bandE, bandE0, M, N, C);
1552#endif
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001553 if (anti_collapse_on)
1554 {
Jean-Marc Valinfdb039b2012-03-05 17:13:59 -05001555 anti_collapse(st->mode, X, collapse_masks, LM, C, N,
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05001556 st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001557 }
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04001558
Jean-Marc Valin88619552009-10-04 21:35:36 -04001559 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04001560 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valin88619552009-10-04 21:35:36 -04001561
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001562 OPUS_MOVE(st->syn_mem[0], st->syn_mem[0]+N, MAX_PERIOD);
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001563 if (CC==2)
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001564 OPUS_MOVE(st->syn_mem[1], st->syn_mem[1]+N, MAX_PERIOD);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001565
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001566 c=0; do
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -04001567 for (i=0;i<M*st->mode->eBands[st->start];i++)
1568 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001569 while (++c<C);
1570 c=0; do
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -04001571 for (i=M*st->mode->eBands[st->end];i<N;i++)
1572 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001573 while (++c<C);
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -04001574
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001575 if (CC==2&&C==1)
1576 {
1577 for (i=0;i<N;i++)
1578 freq[N+i] = freq[i];
1579 }
1580
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001581 out_mem[0] = st->syn_mem[0]+MAX_PERIOD;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001582 if (CC==2)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001583 out_mem[1] = st->syn_mem[1]+MAX_PERIOD;
Jean-Marc Valin0d8eaa32010-08-27 14:57:37 -04001584
Gregory Maxwella45724e2011-07-29 11:53:45 -04001585 overlap_mem[0] = prefilter_mem+CC*COMBFILTER_MAXPERIOD;
1586 if (CC==2)
1587 overlap_mem[1] = overlap_mem[0] + st->overlap;
Jean-Marc Valine0ce2cf2010-08-26 23:58:08 -04001588
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001589 compute_inv_mdcts(st->mode, shortBlocks, freq, out_mem, overlap_mem, CC, LM);
Jean-Marc Valine12017e2009-10-03 13:57:31 -04001590
Gregory Maxwell9743bf32010-11-04 20:45:09 -04001591 c=0; do {
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001592 st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);
1593 st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD);
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05001594 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 -05001595 st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset,
1596 st->mode->window, st->overlap);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001597 if (LM!=0)
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05001598 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 -05001599 st->prefilter_gain, gain1, st->prefilter_tapset, prefilter_tapset,
1600 st->mode->window, st->mode->overlap);
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001601 } while (++c<CC);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001602
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001603 deemphasis(out_mem, (opus_val16*)pcm, N, CC, st->upsample, st->mode->preemph, st->preemph_memD);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001604 st->prefilter_period_old = st->prefilter_period;
1605 st->prefilter_gain_old = st->prefilter_gain;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001606 st->prefilter_tapset_old = st->prefilter_tapset;
Jean-Marc Valind9b95652008-08-31 23:34:47 -04001607 }
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001608#endif
1609
1610 st->prefilter_period = pitch_index;
1611 st->prefilter_gain = gain1;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001612 st->prefilter_tapset = prefilter_tapset;
Jean-Marc Valina14e86d2011-02-11 16:27:27 -05001613#ifdef RESYNTH
1614 if (LM!=0)
1615 {
1616 st->prefilter_period_old = st->prefilter_period;
1617 st->prefilter_gain_old = st->prefilter_gain;
1618 st->prefilter_tapset_old = st->prefilter_tapset;
1619 }
1620#endif
Gregory Maxwell54547f12009-02-16 18:56:44 -05001621
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001622 if (CC==2&&C==1) {
1623 for (i=0;i<st->mode->nbEBands;i++)
1624 oldBandE[st->mode->nbEBands+i]=oldBandE[i];
1625 }
1626
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001627 if (!isTransient)
1628 {
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001629 for (i=0;i<CC*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001630 oldLogE2[i] = oldLogE[i];
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001631 for (i=0;i<CC*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001632 oldLogE[i] = oldBandE[i];
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05001633 } else {
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001634 for (i=0;i<CC*st->mode->nbEBands;i++)
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05001635 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05001636 }
Jean-Marc Valin8298cbb2011-11-06 23:27:16 -05001637 /* In case start or end were to change */
1638 c=0; do
1639 {
1640 for (i=0;i<st->start;i++)
1641 {
1642 oldBandE[c*st->mode->nbEBands+i]=0;
1643 oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
1644 }
1645 for (i=st->end;i<st->mode->nbEBands;i++)
1646 {
1647 oldBandE[c*st->mode->nbEBands+i]=0;
1648 oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
1649 }
1650 } while (++c<CC);
1651
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05001652 if (isTransient)
1653 st->consec_transient++;
1654 else
1655 st->consec_transient=0;
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05001656 st->rng = enc->rng;
Jean-Marc Valin5677e342011-01-13 16:15:53 -05001657
Jean-Marc Valin30d51252010-06-21 17:55:28 -04001658 /* If there's any room left (can only happen for very high rates),
Jean-Marc Valin13a7c262011-01-26 10:58:33 -05001659 it's already filled with zeros */
Jean-Marc Valin4794f2e2010-05-19 11:56:57 -04001660 ec_enc_done(enc);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001661
Gregory Maxwellfd17eab2011-10-04 03:31:45 -04001662#ifdef CUSTOM_MODES
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05001663 if (st->signalling)
1664 nbCompressedBytes++;
Gregory Maxwellfd17eab2011-10-04 03:31:45 -04001665#endif
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05001666
Jean-Marc Valin8600f692008-02-29 15:14:12 +11001667 RESTORE_STACK;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08001668 if (ec_get_error(enc))
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001669 return OPUS_INTERNAL_ERROR;
Jean-Marc Valin9d785af2010-07-18 09:42:05 -04001670 else
1671 return nbCompressedBytes;
Jean-Marc Valin8ebd3452007-11-29 20:17:32 +11001672}
1673
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001674
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001675#ifdef CUSTOM_MODES
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001676
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001677#ifdef FIXED_POINT
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001678int opus_custom_encode(CELTEncoder * restrict st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001679{
1680 return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
1681}
1682
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001683#ifndef DISABLE_FLOAT_API
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001684int opus_custom_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001685{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001686 int j, ret, C, N;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001687 VARDECL(opus_int16, in);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05001688 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001689
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001690 if (pcm==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001691 return OPUS_BAD_ARG;
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001692
Ralph Giles120800f2011-11-25 13:02:00 -08001693 C = st->channels;
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001694 N = frame_size;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001695 ALLOC(in, C*N, opus_int16);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001696
1697 for (j=0;j<C*N;j++)
1698 in[j] = FLOAT2INT16(pcm[j]);
1699
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001700 ret=celt_encode_with_ec(st,in,frame_size,compressed,nbCompressedBytes, NULL);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001701#ifdef RESYNTH
1702 for (j=0;j<C*N;j++)
1703 ((float*)pcm)[j]=in[j]*(1.f/32768.f);
1704#endif
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001705 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001706 return ret;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001707}
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001708#endif /* DISABLE_FLOAT_API */
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001709#else
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001710
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001711int opus_custom_encode(CELTEncoder * restrict st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001712{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001713 int j, ret, C, N;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001714 VARDECL(celt_sig, in);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05001715 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04001716
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001717 if (pcm==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001718 return OPUS_BAD_ARG;
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04001719
Ralph Giles120800f2011-11-25 13:02:00 -08001720 C=st->channels;
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05001721 N=frame_size;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04001722 ALLOC(in, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001723 for (j=0;j<C*N;j++) {
1724 in[j] = SCALEOUT(pcm[j]);
1725 }
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001726
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001727 ret = celt_encode_with_ec(st,in,frame_size,compressed,nbCompressedBytes, NULL);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001728#ifdef RESYNTH
1729 for (j=0;j<C*N;j++)
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001730 ((opus_int16*)pcm)[j] = FLOAT2INT16(in[j]);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001731#endif
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04001732 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04001733 return ret;
1734}
Jean-Marc Valin6e9058a2007-12-07 14:59:06 +11001735
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001736int opus_custom_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001737{
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001738 return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
Jean-Marc Valind56c6102010-05-07 20:30:22 -04001739}
1740
Jean-Marc Valin222494f2011-08-17 15:53:37 -04001741#endif
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001742
1743#endif /* CUSTOM_MODES */
1744
1745int opus_custom_encoder_ctl(CELTEncoder * restrict st, int request, ...)
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001746{
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001747 va_list ap;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001748
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001749 va_start(ap, request);
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001750 switch (request)
1751 {
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001752 case OPUS_SET_COMPLEXITY_REQUEST:
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001753 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001754 int value = va_arg(ap, opus_int32);
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001755 if (value<0 || value>10)
1756 goto bad_arg;
Jean-Marc Valin1213ba52010-08-31 17:03:13 -04001757 st->complexity = value;
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001758 }
1759 break;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001760 case CELT_SET_START_BAND_REQUEST:
1761 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001762 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001763 if (value<0 || value>=st->mode->nbEBands)
1764 goto bad_arg;
1765 st->start = value;
1766 }
1767 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001768 case CELT_SET_END_BAND_REQUEST:
1769 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001770 opus_int32 value = va_arg(ap, opus_int32);
Timothy B. Terriberry8893e532010-12-30 08:56:49 -08001771 if (value<1 || value>st->mode->nbEBands)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04001772 goto bad_arg;
1773 st->end = value;
1774 }
1775 break;
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001776 case CELT_SET_PREDICTION_REQUEST:
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001777 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001778 int value = va_arg(ap, opus_int32);
Gregory Maxwell2dd3d322009-06-05 14:05:51 -04001779 if (value<0 || value>2)
Gregory Maxwell98046ca2008-12-13 20:42:03 -05001780 goto bad_arg;
Jean-Marc Valind539c6b2011-02-03 13:36:03 -05001781 st->disable_pf = value<=1;
1782 st->force_intra = value==0;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001783 }
1784 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001785 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
Jean-Marc Valin69653882011-04-21 10:41:13 -04001786 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001787 int value = va_arg(ap, opus_int32);
Jean-Marc Valin69653882011-04-21 10:41:13 -04001788 if (value<0 || value>100)
1789 goto bad_arg;
1790 st->loss_rate = value;
1791 }
1792 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001793 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
Jean-Marc Valin79b34eb2010-12-05 17:22:06 -05001794 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001795 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin79b34eb2010-12-05 17:22:06 -05001796 st->constrained_vbr = value;
1797 }
1798 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001799 case OPUS_SET_VBR_REQUEST:
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001800 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001801 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001802 st->vbr = value;
1803 }
1804 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001805 case OPUS_SET_BITRATE_REQUEST:
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001806 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001807 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin663a7fe2011-09-06 14:05:19 -04001808 if (value<=500 && value!=OPUS_BITRATE_MAX)
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001809 goto bad_arg;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05001810 value = IMIN(value, 260000*st->channels);
Jean-Marc Valin7bb26e12011-02-01 17:04:27 -05001811 st->bitrate = value;
Gregory Maxwell888d8ce2009-05-21 04:21:53 -04001812 }
1813 break;
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001814 case CELT_SET_CHANNELS_REQUEST:
1815 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001816 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin00a98f52011-01-31 11:19:03 -05001817 if (value<1 || value>2)
1818 goto bad_arg;
1819 st->stream_channels = value;
1820 }
1821 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001822 case OPUS_RESET_STATE:
John Ridges454d1d02009-05-21 22:38:39 -04001823 {
Jean-Marc Valin8298cbb2011-11-06 23:27:16 -05001824 int i;
1825 opus_val16 *oldBandE, *oldLogE, *oldLogE2;
1826 oldBandE = (opus_val16*)(st->in_mem+st->channels*(2*st->overlap+COMBFILTER_MAXPERIOD));
1827 oldLogE = oldBandE + st->channels*st->mode->nbEBands;
1828 oldLogE2 = oldLogE + st->channels*st->mode->nbEBands;
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04001829 OPUS_CLEAR((char*)&st->ENCODER_RESET_START,
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001830 opus_custom_encoder_get_size(st->mode, st->channels)-
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001831 ((char*)&st->ENCODER_RESET_START - (char*)st));
Jean-Marc Valin8298cbb2011-11-06 23:27:16 -05001832 for (i=0;i<st->channels*st->mode->nbEBands;i++)
1833 oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT);
Jean-Marc Valin30165bb2010-12-03 14:35:59 -05001834 st->vbr_offset = 0;
John Ridges454d1d02009-05-21 22:38:39 -04001835 st->delayedIntra = 1;
Timothy B. Terriberry320cf2e2010-12-17 05:52:06 -08001836 st->spread_decision = SPREAD_NORMAL;
Gregory Maxwellec8008b2011-08-30 16:50:01 -04001837 st->tonal_average = 256;
Jean-Marc Valin8298cbb2011-11-06 23:27:16 -05001838 st->hf_average = 0;
1839 st->tapset_decision = 0;
John Ridges454d1d02009-05-21 22:38:39 -04001840 }
1841 break;
Gregory Maxwellfd17eab2011-10-04 03:31:45 -04001842#ifdef CUSTOM_MODES
Jean-Marc Valin0b405d12011-02-04 01:03:42 -05001843 case CELT_SET_INPUT_CLIPPING_REQUEST:
1844 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001845 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin0b405d12011-02-04 01:03:42 -05001846 st->clip = value;
1847 }
1848 break;
Gregory Maxwellfd17eab2011-10-04 03:31:45 -04001849#endif
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04001850 case CELT_SET_SIGNALLING_REQUEST:
1851 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001852 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04001853 st->signalling = value;
1854 }
1855 break;
1856 case CELT_GET_MODE_REQUEST:
1857 {
1858 const CELTMode ** value = va_arg(ap, const CELTMode**);
1859 if (value==0)
1860 goto bad_arg;
1861 *value=st->mode;
1862 }
1863 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001864 case OPUS_GET_FINAL_RANGE_REQUEST:
Jean-Marc Valin06cee2b2011-08-19 16:11:41 -04001865 {
1866 opus_uint32 * value = va_arg(ap, opus_uint32 *);
1867 if (value==0)
1868 goto bad_arg;
1869 *value=st->rng;
1870 }
1871 break;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001872 default:
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001873 goto bad_request;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001874 }
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001875 va_end(ap);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001876 return OPUS_OK;
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001877bad_arg:
1878 va_end(ap);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001879 return OPUS_BAD_ARG;
Jean-Marc Valinb6f90612008-10-05 22:39:13 -04001880bad_request:
1881 va_end(ap);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001882 return OPUS_UNIMPLEMENTED;
Jean-Marc Valinc18fb1d2008-09-30 07:36:54 -04001883}
1884
Jean-Marc Valin56522ad2009-06-05 17:17:25 -04001885/**********************************************************************/
1886/* */
1887/* DECODER */
1888/* */
1889/**********************************************************************/
Jean-Marc Valineafbdd52009-04-27 19:35:09 -04001890#define DECODE_BUFFER_SIZE 2048
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001891
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001892/** Decoder state
Jean-Marc Valin276de722008-02-20 17:45:51 +11001893 @brief Decoder state
1894 */
Jean-Marc Valin242da532011-09-05 20:53:33 -04001895struct OpusCustomDecoder {
1896 const OpusCustomMode *mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001897 int overlap;
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001898 int channels;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05001899 int stream_channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001900
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001901 int downsample;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001902 int start, end;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05001903 int signalling;
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001904
1905 /* Everything beyond this point gets cleared on a reset */
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05001906#define DECODER_RESET_START rng
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04001907
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04001908 opus_uint32 rng;
Jean-Marc Valinef20e392011-03-18 15:34:11 -04001909 int error;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11001910 int last_pitch_index;
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001911 int loss_count;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04001912 int postfilter_period;
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05001913 int postfilter_period_old;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001914 opus_val16 postfilter_gain;
1915 opus_val16 postfilter_gain_old;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05001916 int postfilter_tapset;
1917 int postfilter_tapset_old;
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001918
1919 celt_sig preemph_memD[2];
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04001920
Jean-Marc Valinca8b9922010-08-27 16:23:03 -04001921 celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001922 /* opus_val16 lpc[], Size = channels*LPC_ORDER */
1923 /* opus_val16 oldEBands[], Size = 2*mode->nbEBands */
1924 /* opus_val16 oldLogE[], Size = 2*mode->nbEBands */
1925 /* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */
1926 /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001927};
1928
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05001929int celt_decoder_get_size(int channels)
1930{
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001931 const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
1932 return opus_custom_decoder_get_size(mode, channels);
Jean-Marc Valin8cf29f02011-01-30 23:38:28 -05001933}
1934
Gregory Maxwellafc8d532011-09-28 15:13:26 -04001935OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_get_size(const CELTMode *mode, int channels)
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001936{
1937 int size = sizeof(struct CELTDecoder)
1938 + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig)
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04001939 + channels*LPC_ORDER*sizeof(opus_val16)
1940 + 4*2*mode->nbEBands*sizeof(opus_val16);
Jean-Marc Valin02a35272010-08-27 16:00:01 -04001941 return size;
1942}
1943
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001944#ifdef CUSTOM_MODES
1945CELTDecoder *opus_custom_decoder_create(const CELTMode *mode, int channels, int *error)
Jean-Marc Valinc97b2582011-01-28 23:07:32 -05001946{
Jean-Marc Valin875f8db2011-08-31 16:43:08 -04001947 int ret;
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001948 CELTDecoder *st = (CELTDecoder *)opus_alloc(opus_custom_decoder_get_size(mode, channels));
1949 ret = opus_custom_decoder_init(st, mode, channels);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001950 if (ret != OPUS_OK)
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -05001951 {
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001952 opus_custom_decoder_destroy(st);
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -05001953 st = NULL;
1954 }
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001955 if (error)
1956 *error = ret;
Jean-Marc Valind6c3d3c2011-01-30 10:23:40 -05001957 return st;
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -04001958}
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001959#endif /* CUSTOM_MODES */
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001960
Gregory Maxwell64a35412011-09-02 10:31:17 -04001961int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels)
Jean-Marc Valinc97b2582011-01-28 23:07:32 -05001962{
Jean-Marc Valin875f8db2011-08-31 16:43:08 -04001963 int ret;
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001964 ret = opus_custom_decoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001965 if (ret != OPUS_OK)
Jean-Marc Valin875f8db2011-08-31 16:43:08 -04001966 return ret;
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001967 st->downsample = resampling_factor(sampling_rate);
1968 if (st->downsample==0)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001969 return OPUS_BAD_ARG;
Jean-Marc Valin875f8db2011-08-31 16:43:08 -04001970 else
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001971 return OPUS_OK;
Jean-Marc Valinc97b2582011-01-28 23:07:32 -05001972}
1973
Gregory Maxwellafc8d532011-09-28 15:13:26 -04001974OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels)
Jean-Marc Valin7cfb7302010-08-27 16:54:33 -04001975{
Jean-Marc Valin80ed1472009-10-15 21:45:32 -04001976 if (channels < 0 || channels > 2)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001977 return OPUS_BAD_ARG;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11001978
Gregory Maxwell17169992009-06-04 15:15:34 -04001979 if (st==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001980 return OPUS_ALLOC_FAIL;
Jean-Marc Valinece94a02009-10-16 07:30:14 -04001981
Jean-Marc Valin06237d72011-09-01 13:20:40 -04001982 OPUS_CLEAR((char*)st, opus_custom_decoder_get_size(mode, channels));
Jean-Marc Valin6d3829f2010-08-27 17:52:38 -04001983
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001984 st->mode = mode;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001985 st->overlap = mode->overlap;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05001986 st->stream_channels = st->channels = channels;
Jean-Marc Valina5431bf2008-01-03 20:53:01 +11001987
Jean-Marc Valin913a1742011-01-29 10:00:20 -05001988 st->downsample = 1;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001989 st->start = 0;
Jean-Marc Valin8952c452010-07-16 21:48:44 -04001990 st->end = st->mode->effEBands;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05001991 st->signalling = 1;
Jean-Marc Valin5f961462010-05-19 13:38:10 -04001992
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04001993 st->loss_count = 0;
Gregory Maxwell17169992009-06-04 15:15:34 -04001994
Jean-Marc Valin8298cbb2011-11-06 23:27:16 -05001995 opus_custom_decoder_ctl(st, OPUS_RESET_STATE);
1996
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04001997 return OPUS_OK;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11001998}
1999
Jean-Marc Valin06237d72011-09-01 13:20:40 -04002000#ifdef CUSTOM_MODES
2001void opus_custom_decoder_destroy(CELTDecoder *st)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11002002{
Jean-Marc Valin07f88402011-08-29 15:08:51 -04002003 opus_free(st);
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11002004}
Jean-Marc Valin06237d72011-09-01 13:20:40 -04002005#endif /* CUSTOM_MODES */
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11002006
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002007static void celt_decode_lost(CELTDecoder * restrict st, opus_val16 * restrict pcm, int N, int LM)
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002008{
Jean-Marc Valin04752672010-05-05 07:21:21 -04002009 int c;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +11002010 int pitch_index;
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002011 int overlap = st->mode->overlap;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002012 opus_val16 fade = Q15ONE;
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10002013 int i, len;
Ralph Giles120800f2011-11-25 13:02:00 -08002014 const int C = st->channels;
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10002015 int offset;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002016 celt_sig *out_mem[2];
2017 celt_sig *decode_mem[2];
2018 celt_sig *overlap_mem[2];
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002019 opus_val16 *lpc;
2020 opus_val32 *out_syn[2];
Jean-Marc Valin37378622011-10-11 15:03:38 -04002021 opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11002022 SAVE_STACK;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002023
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002024 c=0; do {
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002025 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
2026 out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
2027 overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002028 } while (++c<C);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002029 lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C);
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002030 oldBandE = lpc+C*LPC_ORDER;
Jean-Marc Valin37378622011-10-11 15:03:38 -04002031 oldLogE = oldBandE + 2*st->mode->nbEBands;
2032 oldLogE2 = oldLogE + 2*st->mode->nbEBands;
2033 backgroundLogE = oldLogE2 + 2*st->mode->nbEBands;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002034
2035 out_syn[0] = out_mem[0]+MAX_PERIOD-N;
2036 if (C==2)
2037 out_syn[1] = out_mem[1]+MAX_PERIOD-N;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002038
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +10002039 len = N+st->mode->overlap;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002040
Jean-Marc Valin37378622011-10-11 15:03:38 -04002041 if (st->loss_count >= 5 || st->start!=0)
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002042 {
Jean-Marc Valin37378622011-10-11 15:03:38 -04002043 /* Noise-based PLC/CNG */
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002044 VARDECL(celt_sig, freq);
2045 VARDECL(celt_norm, X);
2046 VARDECL(celt_ener, bandE);
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002047 opus_uint32 seed;
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002048 int effEnd;
2049
2050 effEnd = st->end;
2051 if (effEnd > st->mode->effEBands)
2052 effEnd = st->mode->effEBands;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002053
2054 ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
2055 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
2056 ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
2057
Jean-Marc Valin37378622011-10-11 15:03:38 -04002058 if (st->loss_count >= 5)
2059 log2Amp(st->mode, st->start, st->end, bandE, backgroundLogE, C);
2060 else {
2061 /* Energy decay */
2062 opus_val16 decay = st->loss_count==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT);
2063 c=0; do
2064 {
2065 for (i=st->start;i<st->end;i++)
2066 oldBandE[c*st->mode->nbEBands+i] -= decay;
2067 } while (++c<C);
2068 log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
2069 }
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002070 seed = st->rng;
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002071 for (c=0;c<C;c++)
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002072 {
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002073 for (i=0;i<(st->mode->eBands[st->start]<<LM);i++)
2074 X[c*N+i] = 0;
Jean-Marc Valin37378622011-10-11 15:03:38 -04002075 for (i=st->start;i<st->mode->effEBands;i++)
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002076 {
2077 int j;
2078 int boffs;
2079 int blen;
2080 boffs = N*c+(st->mode->eBands[i]<<LM);
2081 blen = (st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
2082 for (j=0;j<blen;j++)
2083 {
Jean-Marc Valin7fc2fbd2011-09-01 13:40:39 -04002084 seed = celt_lcg_rand(seed);
Gregory Maxwellec8008b2011-08-30 16:50:01 -04002085 X[boffs+j] = (celt_norm)((opus_int32)seed>>20);
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002086 }
2087 renormalise_vector(X+boffs, blen, Q15ONE);
2088 }
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002089 for (i=(st->mode->eBands[st->end]<<LM);i<N;i++)
2090 X[c*N+i] = 0;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002091 }
2092 st->rng = seed;
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002093
Timothy B. Terriberry115fa352011-03-02 15:28:08 -08002094 denormalise_bands(st->mode, X, freq, bandE, st->mode->effEBands, C, 1<<LM);
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002095
Jean-Marc Valin1a8bf372011-03-16 22:03:15 -04002096 c=0; do
2097 for (i=0;i<st->mode->eBands[st->start]<<LM;i++)
2098 freq[c*N+i] = 0;
2099 while (++c<C);
2100 c=0; do {
2101 int bound = st->mode->eBands[effEnd]<<LM;
2102 if (st->downsample!=1)
2103 bound = IMIN(bound, N/st->downsample);
2104 for (i=bound;i<N;i++)
2105 freq[c*N+i] = 0;
2106 } while (++c<C);
Jean-Marc Valineafd8a72011-01-23 00:24:45 -05002107 compute_inv_mdcts(st->mode, 0, freq, out_syn, overlap_mem, C, LM);
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04002108 } else {
Jean-Marc Valin37378622011-10-11 15:03:38 -04002109 /* Pitch-based PLC */
2110 if (st->loss_count == 0)
2111 {
2112 opus_val16 pitch_buf[DECODE_BUFFER_SIZE>>1];
2113 /* Corresponds to a min pitch of 67 Hz. It's possible to save CPU in this
2114 search by using only part of the decode buffer */
2115 int poffset = 720;
2116 pitch_downsample(decode_mem, pitch_buf, DECODE_BUFFER_SIZE, C);
2117 /* Max pitch is 100 samples (480 Hz) */
2118 pitch_search(pitch_buf+((poffset)>>1), pitch_buf, DECODE_BUFFER_SIZE-poffset,
2119 poffset-100, &pitch_index);
2120 pitch_index = poffset-pitch_index;
2121 st->last_pitch_index = pitch_index;
2122 } else {
2123 pitch_index = st->last_pitch_index;
2124 fade = QCONST16(.8f,15);
2125 }
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002126
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002127 c=0; do {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002128 VARDECL(opus_val32, e);
2129 opus_val16 exc[MAX_PERIOD];
2130 opus_val32 ac[LPC_ORDER+1];
2131 opus_val16 decay = 1;
2132 opus_val32 S1=0;
Gregory Maxwell06d57b22011-08-01 22:02:25 -04002133 opus_val16 mem[LPC_ORDER]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002134
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002135 ALLOC(e, MAX_PERIOD+2*st->mode->overlap, opus_val32);
Jean-Marc Valinf54a0a32011-05-13 17:36:31 -04002136
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002137 offset = MAX_PERIOD-pitch_index;
2138 for (i=0;i<MAX_PERIOD;i++)
2139 exc[i] = ROUND16(out_mem[c][i], SIG_SHIFT);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05002140
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002141 if (st->loss_count == 0)
2142 {
2143 _celt_autocorr(exc, ac, st->mode->window, st->mode->overlap,
2144 LPC_ORDER, MAX_PERIOD);
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05002145
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002146 /* Noise floor -40 dB */
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002147#ifdef FIXED_POINT
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002148 ac[0] += SHR32(ac[0],13);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002149#else
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002150 ac[0] *= 1.0001f;
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002151#endif
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002152 /* Lag windowing */
2153 for (i=1;i<=LPC_ORDER;i++)
2154 {
2155 /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002156#ifdef FIXED_POINT
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002157 ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002158#else
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002159 ac[i] -= ac[i]*(.008f*i)*(.008f*i);
Jean-Marc Valin7b7f0712010-06-17 20:10:02 -04002160#endif
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002161 }
2162
2163 _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
2164 }
2165 for (i=0;i<LPC_ORDER;i++)
2166 mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
Jean-Marc Valin7fc2fbd2011-09-01 13:40:39 -04002167 celt_fir(exc, lpc+c*LPC_ORDER, exc, MAX_PERIOD, LPC_ORDER, mem);
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002168 /*for (i=0;i<MAX_PERIOD;i++)printf("%d ", exc[i]); printf("\n");*/
2169 /* Check if the waveform is decaying (and if so how fast) */
2170 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002171 opus_val32 E1=1, E2=1;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002172 int period;
2173 if (pitch_index <= MAX_PERIOD/2)
2174 period = pitch_index;
2175 else
2176 period = MAX_PERIOD/2;
2177 for (i=0;i<period;i++)
2178 {
2179 E1 += SHR32(MULT16_16(exc[MAX_PERIOD-period+i],exc[MAX_PERIOD-period+i]),8);
2180 E2 += SHR32(MULT16_16(exc[MAX_PERIOD-2*period+i],exc[MAX_PERIOD-2*period+i]),8);
2181 }
2182 if (E1 > E2)
2183 E1 = E2;
2184 decay = celt_sqrt(frac_div32(SHR(E1,1),E2));
Jean-Marc Valin5a0fae52009-12-14 21:19:37 -05002185 }
2186
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002187 /* Copy excitation, taking decay into account */
2188 for (i=0;i<len+st->mode->overlap;i++)
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002189 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002190 opus_val16 tmp;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002191 if (offset+i >= MAX_PERIOD)
2192 {
2193 offset -= pitch_index;
2194 decay = MULT16_16_Q15(decay, decay);
2195 }
2196 e[i] = SHL32(EXTEND32(MULT16_16_Q15(decay, exc[offset+i])), SIG_SHIFT);
2197 tmp = ROUND16(out_mem[c][offset+i],SIG_SHIFT);
2198 S1 += SHR32(MULT16_16(tmp,tmp),8);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002199 }
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002200 for (i=0;i<LPC_ORDER;i++)
2201 mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
2202 for (i=0;i<len+st->mode->overlap;i++)
2203 e[i] = MULT16_32_Q15(fade, e[i]);
Jean-Marc Valin7fc2fbd2011-09-01 13:40:39 -04002204 celt_iir(e, lpc+c*LPC_ORDER, e, len+st->mode->overlap, LPC_ORDER, mem);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002205
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002206 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002207 opus_val32 S2=0;
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05002208 for (i=0;i<len+overlap;i++)
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002209 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002210 opus_val16 tmp = ROUND16(e[i],SIG_SHIFT);
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002211 S2 += SHR32(MULT16_16(tmp,tmp),8);
2212 }
2213 /* This checks for an "explosion" in the synthesis */
2214#ifdef FIXED_POINT
2215 if (!(S1 > SHR32(S2,2)))
2216#else
2217 /* Float test is written this way to catch NaNs at the same time */
2218 if (!(S1 > 0.2f*S2))
2219#endif
2220 {
2221 for (i=0;i<len+overlap;i++)
2222 e[i] = 0;
2223 } else if (S1 < S2)
2224 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002225 opus_val16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002226 for (i=0;i<len+overlap;i++)
2227 e[i] = MULT16_32_Q15(ratio, e[i]);
2228 }
Jean-Marc Valin07fed1b2009-12-28 07:59:42 -05002229 }
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002230
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002231 /* Apply post-filter to the MDCT overlap of the previous frame */
2232 comb_filter(out_mem[c]+MAX_PERIOD, out_mem[c]+MAX_PERIOD, st->postfilter_period, st->postfilter_period, st->overlap,
2233 st->postfilter_gain, st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset,
2234 NULL, 0);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002235
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002236 for (i=0;i<MAX_PERIOD+st->mode->overlap-N;i++)
2237 out_mem[c][i] = out_mem[c][N+i];
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002238
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002239 /* Apply TDAC to the concealed audio so that it blends with the
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002240 previous and next frames */
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002241 for (i=0;i<overlap/2;i++)
2242 {
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002243 opus_val32 tmp;
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002244 tmp = MULT16_32_Q15(st->mode->window[i], e[N+overlap-1-i]) +
2245 MULT16_32_Q15(st->mode->window[overlap-i-1], e[N+i ]);
2246 out_mem[c][MAX_PERIOD+i] = MULT16_32_Q15(st->mode->window[overlap-i-1], tmp);
2247 out_mem[c][MAX_PERIOD+overlap-i-1] = MULT16_32_Q15(st->mode->window[i], tmp);
2248 }
2249 for (i=0;i<N;i++)
2250 out_mem[c][MAX_PERIOD-N+i] = e[i];
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002251
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002252 /* Apply pre-filter to the MDCT overlap for the next frame (post-filter will be applied then) */
2253 comb_filter(e, out_mem[c]+MAX_PERIOD, st->postfilter_period, st->postfilter_period, st->overlap,
2254 -st->postfilter_gain, -st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset,
2255 NULL, 0);
Jean-Marc Valin8430a752011-02-03 23:54:37 -05002256 for (i=0;i<overlap;i++)
2257 out_mem[c][MAX_PERIOD+i] = e[i];
2258 } while (++c<C);
2259 }
Jean-Marc Valin1677aa92007-12-08 01:13:34 +11002260
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002261 deemphasis(out_syn, pcm, N, C, st->downsample, st->mode->preemph, st->preemph_memD);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002262
Jean-Marc Valin0f0da992009-08-12 21:34:01 -04002263 st->loss_count++;
2264
Jean-Marc Valin8600f692008-02-29 15:14:12 +11002265 RESTORE_STACK;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002266}
2267
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002268int celt_decode_with_ec(CELTDecoder * restrict st, const unsigned char *data, int len, opus_val16 * restrict pcm, int frame_size, ec_dec *dec)
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11002269{
Jean-Marc Valin0695a5f2010-08-27 11:33:18 -04002270 int c, i, N;
Timothy B. Terriberry320cf2e2010-12-17 05:52:06 -08002271 int spread_decision;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002272 opus_int32 bits;
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002273 ec_dec _dec;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002274 VARDECL(celt_sig, freq);
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002275 VARDECL(celt_norm, X);
2276 VARDECL(celt_ener, bandE);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002277 VARDECL(int, fine_quant);
2278 VARDECL(int, pulses);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002279 VARDECL(int, cap);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002280 VARDECL(int, offsets);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04002281 VARDECL(int, fine_priority);
Jean-Marc Valin163b76e2010-05-27 23:56:53 -04002282 VARDECL(int, tf_res);
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002283 VARDECL(unsigned char, collapse_masks);
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002284 celt_sig *out_mem[2];
2285 celt_sig *decode_mem[2];
2286 celt_sig *overlap_mem[2];
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04002287 celt_sig *out_syn[2];
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002288 opus_val16 *lpc;
2289 opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
Jean-Marc Valinc890b582008-08-01 22:26:49 -04002290
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +10002291 int shortBlocks;
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04002292 int isTransient;
Jean-Marc Valin05ed03e2009-04-29 07:44:13 -04002293 int intra_ener;
Ralph Giles120800f2011-11-25 13:02:00 -08002294 const int CC = st->channels;
Jean-Marc Valin017fa852010-05-06 22:11:48 -04002295 int LM, M;
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002296 int effEnd;
Jean-Marc Valinb801da52010-09-28 14:56:20 -04002297 int codedBands;
Jean-Marc Valinf1fea662010-10-09 22:58:52 -04002298 int alloc_trim;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002299 int postfilter_pitch;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002300 opus_val16 postfilter_gain;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05002301 int intensity=0;
Jean-Marc Valine65978f2010-12-02 13:46:48 -05002302 int dual_stereo=0;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002303 opus_int32 total_bits;
2304 opus_int32 balance;
2305 opus_int32 tell;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002306 int dynalloc_logp;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002307 int postfilter_tapset;
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002308 int anti_collapse_rsv;
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002309 int anti_collapse_on=0;
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002310 int silence;
Ralph Giles120800f2011-11-25 13:02:00 -08002311 int C = st->stream_channels;
Jean-Marc Valinf62b3bb2011-03-09 11:56:29 -05002312 ALLOC_STACK;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +11002313
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002314 frame_size *= st->downsample;
Jean-Marc Valin017fa852010-05-06 22:11:48 -04002315
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002316 c=0; do {
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002317 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
2318 out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
2319 overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002320 } while (++c<CC);
Jean-Marc Valinff5f7222011-07-29 18:59:12 -04002321 lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*CC);
Jean-Marc Valin37378622011-10-11 15:03:38 -04002322 oldBandE = lpc+CC*LPC_ORDER;
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002323 oldLogE = oldBandE + 2*st->mode->nbEBands;
2324 oldLogE2 = oldLogE + 2*st->mode->nbEBands;
2325 backgroundLogE = oldLogE2 + 2*st->mode->nbEBands;
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002326
Gregory Maxwellfd17eab2011-10-04 03:31:45 -04002327#ifdef CUSTOM_MODES
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002328 if (st->signalling && data!=NULL)
2329 {
Jean-Marc Valind6bf19d2011-03-21 07:06:09 -04002330 int data0=data[0];
2331 /* Convert "standard mode" to Opus header */
2332 if (st->mode->Fs==48000 && st->mode->shortMdctSize==120)
2333 {
2334 data0 = fromOpus(data0);
2335 if (data0<0)
Jean-Marc Valin331e9fe2011-09-06 14:30:19 -04002336 return OPUS_INVALID_PACKET;
Jean-Marc Valind6bf19d2011-03-21 07:06:09 -04002337 }
2338 st->end = IMAX(1, st->mode->effEBands-2*(data0>>5));
2339 LM = (data0>>3)&0x3;
2340 C = 1 + ((data0>>2)&0x1);
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002341 data++;
2342 len--;
2343 if (LM>st->mode->maxLM)
Jean-Marc Valin331e9fe2011-09-06 14:30:19 -04002344 return OPUS_INVALID_PACKET;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002345 if (frame_size < st->mode->shortMdctSize<<LM)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002346 return OPUS_BUFFER_TOO_SMALL;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002347 else
2348 frame_size = st->mode->shortMdctSize<<LM;
2349 } else {
Gregory Maxwellfd17eab2011-10-04 03:31:45 -04002350#else
2351 {
2352#endif
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002353 for (LM=0;LM<=st->mode->maxLM;LM++)
2354 if (st->mode->shortMdctSize<<LM==frame_size)
2355 break;
2356 if (LM>st->mode->maxLM)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002357 return OPUS_BAD_ARG;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002358 }
2359 M=1<<LM;
2360
2361 if (len<0 || len>1275 || pcm==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002362 return OPUS_BAD_ARG;
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002363
Jean-Marc Valin04752672010-05-05 07:21:21 -04002364 N = M*st->mode->shortMdctSize;
Jean-Marc Valin01417232008-03-03 13:59:55 +11002365
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002366 effEnd = st->end;
2367 if (effEnd > st->mode->effEBands)
2368 effEnd = st->mode->effEBands;
2369
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002370 ALLOC(freq, IMAX(CC,C)*N, celt_sig); /**< Interleaved signal MDCTs */
2371 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
2372 ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002373 c=0; do
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002374 for (i=0;i<M*st->mode->eBands[st->start];i++)
2375 X[c*N+i] = 0;
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002376 while (++c<C);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002377 c=0; do
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002378 for (i=M*st->mode->eBands[effEnd];i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002379 X[c*N+i] = 0;
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002380 while (++c<C);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002381
Jean-Marc Valin65d35a32011-01-26 22:04:59 -05002382 if (data == NULL || len<=1)
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002383 {
Jean-Marc Valin017fa852010-05-06 22:11:48 -04002384 celt_decode_lost(st, pcm, N, LM);
Jean-Marc Valin8600f692008-02-29 15:14:12 +11002385 RESTORE_STACK;
Jean-Marc Valin37e788c2011-03-16 20:56:28 -04002386 return frame_size/st->downsample;
Jean-Marc Valinfb83fb42007-12-08 00:56:04 +11002387 }
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002388
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002389 if (dec == NULL)
2390 {
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002391 ec_dec_init(&_dec,(unsigned char*)data,len);
Jean-Marc Valinf5e2e322010-05-19 12:05:02 -04002392 dec = &_dec;
2393 }
Jean-Marc Valin6b95d8f2010-06-21 21:39:44 -04002394
Jean-Marc Valin17c59662012-02-17 16:09:21 -05002395 if (C==1)
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002396 {
2397 for (i=0;i<st->mode->nbEBands;i++)
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002398 oldBandE[i]=MAX16(oldBandE[i],oldBandE[st->mode->nbEBands+i]);
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002399 }
2400
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002401 total_bits = len*8;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002402 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002403
Jean-Marc Valina0653ed2011-07-05 13:18:59 -04002404 if (tell >= total_bits)
Ralph Gilesda025d52011-10-26 20:24:49 -07002405 silence = 1;
Jean-Marc Valina0653ed2011-07-05 13:18:59 -04002406 else if (tell==1)
Jean-Marc Valin65d35a32011-01-26 22:04:59 -05002407 silence = ec_dec_bit_logp(dec, 15);
2408 else
2409 silence = 0;
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002410 if (silence)
2411 {
Jean-Marc Valin13a7c262011-01-26 10:58:33 -05002412 /* Pretend we've read all the remaining bits */
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002413 tell = len*8;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002414 dec->nbits_total+=tell-ec_tell(dec);
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002415 }
2416
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002417 postfilter_gain = 0;
2418 postfilter_pitch = 0;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002419 postfilter_tapset = 0;
Jean-Marc Valinef986e42011-02-03 15:47:10 -05002420 if (st->start==0 && tell+16 <= total_bits)
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002421 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002422 if(ec_dec_bit_logp(dec, 1))
2423 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002424 int qg, octave;
2425 octave = ec_dec_uint(dec, 6);
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002426 postfilter_pitch = (16<<octave)+ec_dec_bits(dec, 4+octave)-1;
Jean-Marc Valinef986e42011-02-03 15:47:10 -05002427 qg = ec_dec_bits(dec, 3);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002428 if (ec_tell(dec)+2<=total_bits)
Jean-Marc Valinef986e42011-02-03 15:47:10 -05002429 postfilter_tapset = ec_dec_icdf(dec, tapset_icdf, 2);
2430 postfilter_gain = QCONST16(.09375f,15)*(qg+1);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002431 }
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002432 tell = ec_tell(dec);
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002433 }
2434
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002435 if (LM > 0 && tell+3 <= total_bits)
2436 {
Timothy B. Terriberrye86fb262010-12-17 14:50:19 -08002437 isTransient = ec_dec_bit_logp(dec, 3);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002438 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002439 }
Jean-Marc Valinf9fdbff2010-09-05 21:02:38 -04002440 else
2441 isTransient = 0;
Jean-Marc Valin017001a2010-08-05 15:42:50 -04002442
Jean-Marc Valin3b918ba2010-05-05 00:02:26 -04002443 if (isTransient)
2444 shortBlocks = M;
2445 else
2446 shortBlocks = 0;
2447
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002448 /* Decode the global flags (first symbols in the stream) */
2449 intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0;
2450 /* Get band energies */
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05002451 unquant_coarse_energy(st->mode, st->start, st->end, oldBandE,
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002452 intra_ener, dec, C, LM);
2453
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04002454 ALLOC(tf_res, st->mode->nbEBands, int);
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05002455 tf_decode(st->start, st->end, isTransient, tf_res, LM, dec);
Jean-Marc Valin0a571ef2010-06-05 23:12:19 -04002456
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002457 tell = ec_tell(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002458 spread_decision = SPREAD_NORMAL;
2459 if (tell+4 <= total_bits)
2460 spread_decision = ec_dec_icdf(dec, spread_icdf, 5);
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04002461
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002462 ALLOC(pulses, st->mode->nbEBands, int);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002463 ALLOC(cap, st->mode->nbEBands, int);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002464 ALLOC(offsets, st->mode->nbEBands, int);
Jean-Marc Valin52cb5fb2009-06-10 08:08:55 -04002465 ALLOC(fine_priority, st->mode->nbEBands, int);
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002466
Timothy B. Terriberryce6d0902011-02-01 17:41:12 -08002467 init_caps(st->mode,cap,LM,C);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002468
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002469 dynalloc_logp = 6;
2470 total_bits<<=BITRES;
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002471 tell = ec_tell_frac(dec);
Timothy B. Terriberryd6f61572010-12-30 09:04:16 -08002472 for (i=st->start;i<st->end;i++)
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002473 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002474 int width, quanta;
2475 int dynalloc_loop_logp;
2476 int boost;
2477 width = C*(st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
2478 /* quanta is 6 bits, but no more than 1 bit/sample
2479 and no less than 1/8 bit/sample */
2480 quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));
2481 dynalloc_loop_logp = dynalloc_logp;
2482 boost = 0;
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002483 while (tell+(dynalloc_loop_logp<<BITRES) < total_bits && boost < cap[i])
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002484 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002485 int flag;
2486 flag = ec_dec_bit_logp(dec, dynalloc_loop_logp);
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002487 tell = ec_tell_frac(dec);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002488 if (!flag)
2489 break;
2490 boost += quanta;
2491 total_bits -= quanta;
2492 dynalloc_loop_logp = 1;
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002493 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002494 offsets[i] = boost;
2495 /* Making dynalloc more likely */
2496 if (boost>0)
2497 dynalloc_logp = IMAX(2, dynalloc_logp-1);
Jean-Marc Valind74c8512010-09-29 17:39:54 -04002498 }
Jean-Marc Valin6775de32008-08-02 08:14:42 -04002499
Jean-Marc Valin9099bc32010-08-07 21:50:01 -04002500 ALLOC(fine_quant, st->mode->nbEBands, int);
Timothy B. Terriberry76469c62011-01-07 09:18:34 -08002501 alloc_trim = tell+(6<<BITRES) <= total_bits ?
2502 ec_dec_icdf(dec, trim_icdf, 7) : 5;
Jean-Marc Valin4f177e82010-11-26 10:32:03 -05002503
Gregory Maxwell75d27802011-08-30 14:02:41 -04002504 bits = (((opus_int32)len*8)<<BITRES) - ec_tell_frac(dec) - 1;
2505 anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0;
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002506 bits -= anti_collapse_rsv;
Timothy B. Terriberryc5643072011-01-29 12:57:18 -08002507 codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08002508 alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
2509 fine_quant, fine_priority, C, LM, dec, 0, 0);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002510
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -05002511 unquant_fine_energy(st->mode, st->start, st->end, oldBandE, fine_quant, dec, C);
Jean-Marc Valin827f9312008-05-06 23:21:55 +10002512
Jean-Marc Valin8cbea172010-08-05 15:22:57 -04002513 /* Decode fixed codebook */
Jean-Marc Valin7e983192011-02-01 18:00:29 -05002514 ALLOC(collapse_masks, C*st->mode->nbEBands, unsigned char);
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002515 quant_all_bands(0, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks,
Gregory Maxwelld830d082011-08-15 16:05:40 -04002516 NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res,
Timothy B. Terriberry948d27c2011-01-31 12:28:12 -08002517 len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng);
Jean-Marc Valin746b2a82010-05-14 22:12:33 -04002518
Timothy B. Terriberry21af73e2011-01-19 16:30:03 -08002519 if (anti_collapse_rsv > 0)
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002520 {
2521 anti_collapse_on = ec_dec_bits(dec, 1);
2522 }
2523
Jean-Marc Valine3e2c262011-01-26 13:09:53 -05002524 unquant_energy_finalise(st->mode, st->start, st->end, oldBandE,
Timothy B. Terriberrya093f4d2011-02-03 14:22:15 -08002525 fine_quant, fine_priority, len*8-ec_tell(dec), dec, C);
Jean-Marc Valin30d51252010-06-21 17:55:28 -04002526
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002527 if (anti_collapse_on)
Jean-Marc Valinfdb039b2012-03-05 17:13:59 -05002528 anti_collapse(st->mode, X, collapse_masks, LM, C, N,
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05002529 st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
Jean-Marc Valin87efe1d2011-01-18 14:44:04 -05002530
Jean-Marc Valin02a35272010-08-27 16:00:01 -04002531 log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
Jean-Marc Valinbc272de2010-08-02 09:41:31 -04002532
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002533 if (silence)
2534 {
2535 for (i=0;i<C*st->mode->nbEBands;i++)
2536 {
2537 bandE[i] = 0;
Gregory Maxwell8b631f22011-01-26 20:19:01 -05002538 oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
Jean-Marc Valinde79c372011-01-26 09:24:33 -05002539 }
2540 }
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11002541 /* Synthesis */
Jean-Marc Valin85f41b22010-07-16 18:12:45 -04002542 denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
Jean-Marc Valina4833ff2008-01-10 15:34:00 +11002543
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04002544 OPUS_MOVE(decode_mem[0], decode_mem[0]+N, DECODE_BUFFER_SIZE-N);
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002545 if (CC==2)
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04002546 OPUS_MOVE(decode_mem[1], decode_mem[1]+N, DECODE_BUFFER_SIZE-N);
Jean-Marc Valin88619552009-10-04 21:35:36 -04002547
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002548 c=0; do
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002549 for (i=0;i<M*st->mode->eBands[st->start];i++)
2550 freq[c*N+i] = 0;
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002551 while (++c<C);
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002552 c=0; do {
2553 int bound = M*st->mode->eBands[effEnd];
2554 if (st->downsample!=1)
2555 bound = IMIN(bound, N/st->downsample);
Jean-Marc Valin23340e22011-02-03 23:21:00 -05002556 for (i=bound;i<N;i++)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002557 freq[c*N+i] = 0;
Jean-Marc Valin913a1742011-01-29 10:00:20 -05002558 } while (++c<C);
Jean-Marc Valin3a0bc3d2010-02-21 15:10:22 -05002559
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002560 out_syn[0] = out_mem[0]+MAX_PERIOD-N;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002561 if (CC==2)
Jean-Marc Valin6d131082010-08-27 15:15:32 -04002562 out_syn[1] = out_mem[1]+MAX_PERIOD-N;
Jean-Marc Valinf67b4472010-08-27 01:32:40 -04002563
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002564 if (CC==2&&C==1)
2565 {
2566 for (i=0;i<N;i++)
2567 freq[N+i] = freq[i];
2568 }
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002569 if (CC==1&&C==2)
2570 {
2571 for (i=0;i<N;i++)
2572 freq[i] = HALF32(ADD32(freq[i],freq[N+i]));
2573 }
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002574
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11002575 /* Compute inverse MDCTs */
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002576 compute_inv_mdcts(st->mode, shortBlocks, freq, out_syn, overlap_mem, CC, LM);
Jean-Marc Valinffa13472007-12-10 16:54:17 +11002577
Gregory Maxwell9743bf32010-11-04 20:45:09 -04002578 c=0; do {
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05002579 st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD);
2580 st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD);
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05002581 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 -05002582 st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset,
2583 st->mode->window, st->overlap);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05002584 if (LM!=0)
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05002585 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 -05002586 st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset,
2587 st->mode->window, st->mode->overlap);
Jean-Marc Valin64805fd2011-02-12 00:50:53 -05002588
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002589 } while (++c<CC);
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -05002590 st->postfilter_period_old = st->postfilter_period;
2591 st->postfilter_gain_old = st->postfilter_gain;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002592 st->postfilter_tapset_old = st->postfilter_tapset;
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002593 st->postfilter_period = postfilter_pitch;
2594 st->postfilter_gain = postfilter_gain;
Jean-Marc Valindfa847a2011-01-17 11:37:08 -05002595 st->postfilter_tapset = postfilter_tapset;
Jean-Marc Valina14e86d2011-02-11 16:27:27 -05002596 if (LM!=0)
2597 {
2598 st->postfilter_period_old = st->postfilter_period;
2599 st->postfilter_gain_old = st->postfilter_gain;
2600 st->postfilter_tapset_old = st->postfilter_tapset;
2601 }
Jean-Marc Valin35095c62010-11-04 13:24:44 -04002602
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002603 if (C==1) {
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002604 for (i=0;i<st->mode->nbEBands;i++)
2605 oldBandE[st->mode->nbEBands+i]=oldBandE[i];
2606 }
2607
Jean-Marc Valin5677e342011-01-13 16:15:53 -05002608 /* In case start or end were to change */
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002609 if (!isTransient)
2610 {
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002611 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002612 oldLogE2[i] = oldLogE[i];
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002613 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002614 oldLogE[i] = oldBandE[i];
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002615 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002616 backgroundLogE[i] = MIN16(backgroundLogE[i] + M*QCONST16(0.001f,DB_SHIFT), oldBandE[i]);
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05002617 } else {
Jean-Marc Valin9dec74d2011-03-28 01:39:41 -04002618 for (i=0;i<2*st->mode->nbEBands;i++)
Jean-Marc Valin47e905d2011-01-27 18:05:47 -05002619 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
Jean-Marc Valin9ce95e02011-01-25 19:12:06 -05002620 }
Jean-Marc Valin8298cbb2011-11-06 23:27:16 -05002621 c=0; do
2622 {
2623 for (i=0;i<st->start;i++)
2624 {
2625 oldBandE[c*st->mode->nbEBands+i]=0;
2626 oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
2627 }
2628 for (i=st->end;i<st->mode->nbEBands;i++)
2629 {
2630 oldBandE[c*st->mode->nbEBands+i]=0;
2631 oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
2632 }
2633 } while (++c<2);
Jean-Marc Valin63fb61f2011-01-20 22:52:55 -05002634 st->rng = dec->rng;
Jean-Marc Valin5677e342011-01-13 16:15:53 -05002635
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002636 deemphasis(out_syn, pcm, N, CC, st->downsample, st->mode->preemph, st->preemph_memD);
Jean-Marc Valine14fe902009-12-11 00:07:31 -05002637 st->loss_count = 0;
Jean-Marc Valin8600f692008-02-29 15:14:12 +11002638 RESTORE_STACK;
Jean-Marc Valinef20e392011-03-18 15:34:11 -04002639 if (ec_tell(dec) > 8*len)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002640 return OPUS_INTERNAL_ERROR;
Jean-Marc Valinef20e392011-03-18 15:34:11 -04002641 if(ec_get_error(dec))
2642 st->error = 1;
2643 return frame_size/st->downsample;
Jean-Marc Valin269d40a2007-12-07 11:29:45 +11002644}
2645
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002646
Jean-Marc Valin06237d72011-09-01 13:20:40 -04002647#ifdef CUSTOM_MODES
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002648
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002649#ifdef FIXED_POINT
Jean-Marc Valin06237d72011-09-01 13:20:40 -04002650int opus_custom_decode(CELTDecoder * restrict st, const unsigned char *data, int len, opus_int16 * restrict pcm, int frame_size)
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002651{
2652 return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL);
2653}
2654
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002655#ifndef DISABLE_FLOAT_API
Jean-Marc Valin06237d72011-09-01 13:20:40 -04002656int opus_custom_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002657{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002658 int j, ret, C, N;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002659 VARDECL(opus_int16, out);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05002660 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04002661
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04002662 if (pcm==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002663 return OPUS_BAD_ARG;
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04002664
Ralph Giles120800f2011-11-25 13:02:00 -08002665 C = st->channels;
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002666 N = frame_size;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002667
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002668 ALLOC(out, C*N, opus_int16);
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002669 ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL);
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002670 if (ret>0)
2671 for (j=0;j<C*ret;j++)
Jean-Marc Valinae01e112010-08-03 21:43:41 -04002672 pcm[j]=out[j]*(1.f/32768.f);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002673
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04002674 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002675 return ret;
2676}
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002677#endif /* DISABLE_FLOAT_API */
2678
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002679#else
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002680
Jean-Marc Valin06237d72011-09-01 13:20:40 -04002681int opus_custom_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size)
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002682{
2683 return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL);
2684}
2685
Jean-Marc Valin06237d72011-09-01 13:20:40 -04002686int opus_custom_decode(CELTDecoder * restrict st, const unsigned char *data, int len, opus_int16 * restrict pcm, int frame_size)
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002687{
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002688 int j, ret, C, N;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002689 VARDECL(celt_sig, out);
Jean-Marc Valin7e983192011-02-01 18:00:29 -05002690 ALLOC_STACK;
Gregory Maxwell17169992009-06-04 15:15:34 -04002691
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04002692 if (pcm==NULL)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002693 return OPUS_BAD_ARG;
Gregory Maxwell0719f6f2009-07-09 17:07:24 -04002694
Ralph Giles120800f2011-11-25 13:02:00 -08002695 C = st->channels;
Jean-Marc Valin713d7a42011-01-31 13:41:01 -05002696 N = frame_size;
Jean-Marc Valin234969c2009-10-17 22:12:42 -04002697 ALLOC(out, C*N, celt_sig);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002698
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002699 ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL);
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002700
Jean-Marc Valine6acfe02011-03-11 16:31:24 -05002701 if (ret>0)
2702 for (j=0;j<C*ret;j++)
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -04002703 pcm[j] = FLOAT2INT16 (out[j]);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04002704
Wessel Lubberhuizen33ba6cc2008-10-03 07:09:29 -04002705 RESTORE_STACK;
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002706 return ret;
2707}
Jean-Marc Valin222494f2011-08-17 15:53:37 -04002708
Gregory Maxwell5f2a74b2008-08-11 23:50:07 -04002709#endif
Jean-Marc Valin06237d72011-09-01 13:20:40 -04002710#endif /* CUSTOM_MODES */
John Ridges454d1d02009-05-21 22:38:39 -04002711
Jean-Marc Valin06237d72011-09-01 13:20:40 -04002712int opus_custom_decoder_ctl(CELTDecoder * restrict st, int request, ...)
John Ridges454d1d02009-05-21 22:38:39 -04002713{
2714 va_list ap;
Gregory Maxwell17169992009-06-04 15:15:34 -04002715
John Ridges454d1d02009-05-21 22:38:39 -04002716 va_start(ap, request);
2717 switch (request)
2718 {
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002719 case CELT_SET_START_BAND_REQUEST:
2720 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002721 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin5f961462010-05-19 13:38:10 -04002722 if (value<0 || value>=st->mode->nbEBands)
2723 goto bad_arg;
2724 st->start = value;
2725 }
2726 break;
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002727 case CELT_SET_END_BAND_REQUEST:
2728 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002729 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwell1928f8d2011-02-08 22:32:56 -05002730 if (value<1 || value>st->mode->nbEBands)
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -04002731 goto bad_arg;
2732 st->end = value;
2733 }
2734 break;
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002735 case CELT_SET_CHANNELS_REQUEST:
2736 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002737 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valinf1916a12011-01-31 10:51:30 -05002738 if (value<1 || value>2)
2739 goto bad_arg;
2740 st->stream_channels = value;
2741 }
Jean-Marc Valindd2973d2011-03-11 17:46:02 -05002742 break;
Jean-Marc Valinef20e392011-03-18 15:34:11 -04002743 case CELT_GET_AND_CLEAR_ERROR_REQUEST:
2744 {
Jean-Marc Valin25f7f352011-09-14 09:50:06 -07002745 int *value = va_arg(ap, opus_int32*);
Jean-Marc Valinef20e392011-03-18 15:34:11 -04002746 if (value==NULL)
2747 goto bad_arg;
2748 *value=st->error;
2749 st->error = 0;
2750 }
2751 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002752 case OPUS_GET_LOOKAHEAD_REQUEST:
Jean-Marc Valinff96b162011-03-21 11:32:50 -04002753 {
Jean-Marc Valin25f7f352011-09-14 09:50:06 -07002754 int *value = va_arg(ap, opus_int32*);
Jean-Marc Valinff96b162011-03-21 11:32:50 -04002755 if (value==NULL)
2756 goto bad_arg;
2757 *value = st->overlap/st->downsample;
2758 }
2759 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002760 case OPUS_RESET_STATE:
John Ridges454d1d02009-05-21 22:38:39 -04002761 {
Jean-Marc Valin8298cbb2011-11-06 23:27:16 -05002762 int i;
2763 opus_val16 *lpc, *oldBandE, *oldLogE, *oldLogE2;
2764 lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels);
2765 oldBandE = lpc+st->channels*LPC_ORDER;
2766 oldLogE = oldBandE + 2*st->mode->nbEBands;
2767 oldLogE2 = oldLogE + 2*st->mode->nbEBands;
Jean-Marc Valinbe89c392011-08-30 12:39:51 -04002768 OPUS_CLEAR((char*)&st->DECODER_RESET_START,
Jean-Marc Valin06237d72011-09-01 13:20:40 -04002769 opus_custom_decoder_get_size(st->mode, st->channels)-
Jean-Marc Valinc09807d2010-08-27 17:17:50 -04002770 ((char*)&st->DECODER_RESET_START - (char*)st));
Jean-Marc Valin8298cbb2011-11-06 23:27:16 -05002771 for (i=0;i<2*st->mode->nbEBands;i++)
2772 oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT);
John Ridges454d1d02009-05-21 22:38:39 -04002773 }
2774 break;
Jean-Marc Valin25f7f352011-09-14 09:50:06 -07002775 case OPUS_GET_PITCH_REQUEST:
2776 {
2777 int *value = va_arg(ap, opus_int32*);
2778 if (value==NULL)
2779 goto bad_arg;
2780 *value = st->postfilter_period;
2781 }
2782 break;
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04002783#ifdef OPUS_BUILD
2784 case CELT_GET_MODE_REQUEST:
2785 {
2786 const CELTMode ** value = va_arg(ap, const CELTMode**);
2787 if (value==0)
2788 goto bad_arg;
2789 *value=st->mode;
2790 }
2791 break;
2792 case CELT_SET_SIGNALLING_REQUEST:
2793 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -04002794 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04002795 st->signalling = value;
2796 }
2797 break;
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002798 case OPUS_GET_FINAL_RANGE_REQUEST:
Jean-Marc Valin06cee2b2011-08-19 16:11:41 -04002799 {
2800 opus_uint32 * value = va_arg(ap, opus_uint32 *);
2801 if (value==0)
2802 goto bad_arg;
2803 *value=st->rng;
2804 }
2805 break;
Jean-Marc Valinc3086a92011-03-21 13:26:03 -04002806#endif
John Ridges454d1d02009-05-21 22:38:39 -04002807 default:
2808 goto bad_request;
2809 }
2810 va_end(ap);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002811 return OPUS_OK;
John Ridges454d1d02009-05-21 22:38:39 -04002812bad_arg:
2813 va_end(ap);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002814 return OPUS_BAD_ARG;
John Ridges454d1d02009-05-21 22:38:39 -04002815bad_request:
2816 va_end(ap);
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -04002817 return OPUS_UNIMPLEMENTED;
John Ridges454d1d02009-05-21 22:38:39 -04002818}
Jean-Marc Valinece94a02009-10-16 07:30:14 -04002819
Jean-Marc Valinf9265dd2011-09-01 13:46:18 -04002820
2821
2822const char *opus_strerror(int error)
2823{
2824 static const char *error_strings[8] = {
2825 "success",
2826 "invalid argument",
2827 "buffer too small",
2828 "internal error",
2829 "corrupted stream",
2830 "request not implemented",
2831 "invalid state",
2832 "memory allocation failed"
2833 };
2834 if (error > 0 || error < -7)
2835 return "unknown error";
2836 else
2837 return error_strings[-error];
2838}
2839
2840const char *opus_get_version_string(void)
2841{
2842 return "libopus " OPUS_VERSION
2843#ifdef FUZZING
2844 "-fuzzing"
2845#endif
2846 ;
2847}