blob: de3053aa3e66bc8c3cf9f8b2de3ce7677edddc8a [file] [log] [blame]
Jean-Marc Valin69062102012-11-08 09:42:27 -05001/* Copyright (c) 2007-2008 CSIRO
2 Copyright (c) 2007-2010 Xiph.Org Foundation
3 Copyright (c) 2008 Gregory Maxwell
4 Written by Jean-Marc Valin and Gregory Maxwell */
5/*
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
Jean-Marc Valin1ecb7ea2012-11-08 11:25:20 -050034#define CELT_ENCODER_C
Jean-Marc Valin69062102012-11-08 09:42:27 -050035
Aurélien Zanellicd4c8242013-05-31 15:07:00 +020036#include "cpu_support.h"
Jean-Marc Valin69062102012-11-08 09:42:27 -050037#include "os_support.h"
38#include "mdct.h"
39#include <math.h>
40#include "celt.h"
41#include "pitch.h"
42#include "bands.h"
43#include "modes.h"
44#include "entcode.h"
45#include "quant_bands.h"
46#include "rate.h"
47#include "stack_alloc.h"
48#include "mathops.h"
49#include "float_cast.h"
50#include <stdarg.h>
51#include "celt_lpc.h"
52#include "vq.h"
53
54
55/** Encoder state
56 @brief Encoder state
57 */
58struct OpusCustomEncoder {
59 const OpusCustomMode *mode; /**< Mode used by the encoder */
Jean-Marc Valin69062102012-11-08 09:42:27 -050060 int channels;
61 int stream_channels;
62
63 int force_intra;
64 int clip;
65 int disable_pf;
66 int complexity;
67 int upsample;
68 int start, end;
69
70 opus_int32 bitrate;
71 int vbr;
72 int signalling;
73 int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */
74 int loss_rate;
75 int lsb_depth;
Jean-Marc Valin3252bf22013-04-19 03:14:28 -040076 int variable_duration;
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -040077 int lfe;
Jean-Marc Valin18a380a2016-04-20 13:27:06 -040078 int disable_inv;
Aurélien Zanellicd4c8242013-05-31 15:07:00 +020079 int arch;
Jean-Marc Valin69062102012-11-08 09:42:27 -050080
81 /* Everything beyond this point gets cleared on a reset */
82#define ENCODER_RESET_START rng
83
84 opus_uint32 rng;
85 int spread_decision;
86 opus_val32 delayedIntra;
87 int tonal_average;
88 int lastCodedBands;
89 int hf_average;
90 int tapset_decision;
91
92 int prefilter_period;
93 opus_val16 prefilter_gain;
94 int prefilter_tapset;
95#ifdef RESYNTH
96 int prefilter_period_old;
97 opus_val16 prefilter_gain_old;
98 int prefilter_tapset_old;
99#endif
100 int consec_transient;
101 AnalysisInfo analysis;
Jean-Marc Valin61714e92016-04-23 00:34:53 -0400102 SILKInfo silk_info;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500103
104 opus_val32 preemph_memE[2];
105 opus_val32 preemph_memD[2];
106
107 /* VBR-related parameters */
108 opus_int32 vbr_reservoir;
109 opus_int32 vbr_drift;
110 opus_int32 vbr_offset;
111 opus_int32 vbr_count;
Jean-Marc Valinb7bd4c22013-05-18 23:33:48 -0400112 opus_val32 overlap_max;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500113 opus_val16 stereo_saving;
114 int intensity;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400115 opus_val16 *energy_mask;
Jean-Marc Valin3c0aa8f2013-06-25 14:10:27 -0400116 opus_val16 spec_avg;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500117
118#ifdef RESYNTH
119 /* +MAX_PERIOD/2 to make space for overlap */
120 celt_sig syn_mem[2][2*MAX_PERIOD+MAX_PERIOD/2];
121#endif
122
123 celt_sig in_mem[1]; /* Size = channels*mode->overlap */
124 /* celt_sig prefilter_mem[], Size = channels*COMBFILTER_MAXPERIOD */
125 /* opus_val16 oldBandE[], Size = channels*mode->nbEBands */
126 /* opus_val16 oldLogE[], Size = channels*mode->nbEBands */
127 /* opus_val16 oldLogE2[], Size = channels*mode->nbEBands */
Jean-Marc Valin6fccb4b2016-07-04 01:06:11 -0400128 /* opus_val16 energyError[], Size = channels*mode->nbEBands */
Jean-Marc Valin69062102012-11-08 09:42:27 -0500129};
130
131int celt_encoder_get_size(int channels)
132{
133 CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
134 return opus_custom_encoder_get_size(mode, channels);
135}
136
137OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_get_size(const CELTMode *mode, int channels)
138{
139 int size = sizeof(struct CELTEncoder)
140 + (channels*mode->overlap-1)*sizeof(celt_sig) /* celt_sig in_mem[channels*mode->overlap]; */
141 + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig) /* celt_sig prefilter_mem[channels*COMBFILTER_MAXPERIOD]; */
Jean-Marc Valin6fccb4b2016-07-04 01:06:11 -0400142 + 4*channels*mode->nbEBands*sizeof(opus_val16); /* opus_val16 oldBandE[channels*mode->nbEBands]; */
Jean-Marc Valin69062102012-11-08 09:42:27 -0500143 /* opus_val16 oldLogE[channels*mode->nbEBands]; */
144 /* opus_val16 oldLogE2[channels*mode->nbEBands]; */
Jean-Marc Valin6fccb4b2016-07-04 01:06:11 -0400145 /* opus_val16 energyError[channels*mode->nbEBands]; */
Jean-Marc Valin69062102012-11-08 09:42:27 -0500146 return size;
147}
148
149#ifdef CUSTOM_MODES
150CELTEncoder *opus_custom_encoder_create(const CELTMode *mode, int channels, int *error)
151{
152 int ret;
153 CELTEncoder *st = (CELTEncoder *)opus_alloc(opus_custom_encoder_get_size(mode, channels));
154 /* init will handle the NULL case */
155 ret = opus_custom_encoder_init(st, mode, channels);
156 if (ret != OPUS_OK)
157 {
158 opus_custom_encoder_destroy(st);
159 st = NULL;
160 }
161 if (error)
162 *error = ret;
163 return st;
164}
165#endif /* CUSTOM_MODES */
166
Timothy B. Terriberry39386e02013-11-18 13:30:13 -0500167static int opus_custom_encoder_init_arch(CELTEncoder *st, const CELTMode *mode,
168 int channels, int arch)
Jean-Marc Valin69062102012-11-08 09:42:27 -0500169{
170 if (channels < 0 || channels > 2)
171 return OPUS_BAD_ARG;
172
173 if (st==NULL || mode==NULL)
174 return OPUS_ALLOC_FAIL;
175
176 OPUS_CLEAR((char*)st, opus_custom_encoder_get_size(mode, channels));
177
178 st->mode = mode;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500179 st->stream_channels = st->channels = channels;
180
181 st->upsample = 1;
182 st->start = 0;
183 st->end = st->mode->effEBands;
184 st->signalling = 1;
Timothy B. Terriberry39386e02013-11-18 13:30:13 -0500185 st->arch = arch;
Aurélien Zanellicd4c8242013-05-31 15:07:00 +0200186
Jean-Marc Valin69062102012-11-08 09:42:27 -0500187 st->constrained_vbr = 1;
188 st->clip = 1;
189
190 st->bitrate = OPUS_BITRATE_MAX;
191 st->vbr = 0;
192 st->force_intra = 0;
193 st->complexity = 5;
194 st->lsb_depth=24;
195
196 opus_custom_encoder_ctl(st, OPUS_RESET_STATE);
197
198 return OPUS_OK;
199}
200
Jean-Marc Valin41e89062013-11-20 19:34:14 -0500201#ifdef CUSTOM_MODES
202int opus_custom_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels)
Timothy B. Terriberry39386e02013-11-18 13:30:13 -0500203{
204 return opus_custom_encoder_init_arch(st, mode, channels, opus_select_arch());
205}
Jean-Marc Valin41e89062013-11-20 19:34:14 -0500206#endif
Timothy B. Terriberry39386e02013-11-18 13:30:13 -0500207
208int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels,
209 int arch)
210{
211 int ret;
212 ret = opus_custom_encoder_init_arch(st,
213 opus_custom_mode_create(48000, 960, NULL), channels, arch);
214 if (ret != OPUS_OK)
215 return ret;
216 st->upsample = resampling_factor(sampling_rate);
217 return OPUS_OK;
218}
219
Jean-Marc Valin69062102012-11-08 09:42:27 -0500220#ifdef CUSTOM_MODES
221void opus_custom_encoder_destroy(CELTEncoder *st)
222{
223 opus_free(st);
224}
225#endif /* CUSTOM_MODES */
226
227
228static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int C,
Jean-Marc Valin7e122392016-10-29 17:02:36 -0400229 opus_val16 *tf_estimate, int *tf_chan, int allow_weak_transients,
Jean-Marc Valin90f20c62016-10-28 16:44:38 -0400230 int *weak_transient)
Jean-Marc Valin69062102012-11-08 09:42:27 -0500231{
232 int i;
233 VARDECL(opus_val16, tmp);
234 opus_val32 mem0,mem1;
235 int is_transient = 0;
236 opus_int32 mask_metric = 0;
237 int c;
Jean-Marc Valind683c762012-12-21 16:17:38 -0500238 opus_val16 tf_max;
Jean-Marc Valin144b6e62012-11-10 10:13:03 -0500239 int len2;
Jean-Marc Valin2af92cd2016-10-27 14:14:28 -0400240 /* Forward masking: 6.7 dB/ms. */
241#ifdef FIXED_POINT
242 int forward_shift = 4;
243#else
244 opus_val16 forward_decay = QCONST16(.0625f,15);
245#endif
Jean-Marc Valin69062102012-11-08 09:42:27 -0500246 /* Table of 6*64/x, trained on real data to minimize the average error */
247 static const unsigned char inv_table[128] = {
248 255,255,156,110, 86, 70, 59, 51, 45, 40, 37, 33, 31, 28, 26, 25,
249 23, 22, 21, 20, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
250 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8,
251 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6,
252 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5,
253 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
254 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3,
255 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2,
256 };
257 SAVE_STACK;
258 ALLOC(tmp, len, opus_val16);
259
Jean-Marc Valin90f20c62016-10-28 16:44:38 -0400260 *weak_transient = 0;
Jean-Marc Valin2af92cd2016-10-27 14:14:28 -0400261 /* For lower bitrates, let's be more conservative and have a forward masking
262 decay of 3.3 dB/ms. This avoids having to code transients at very low
263 bitrate (mostly for hybrid), which can result in unstable energy and/or
264 partial collapse. */
Jean-Marc Valin7e122392016-10-29 17:02:36 -0400265 if (allow_weak_transients)
Jean-Marc Valin2af92cd2016-10-27 14:14:28 -0400266 {
267#ifdef FIXED_POINT
268 forward_shift = 5;
269#else
270 forward_decay = QCONST16(.03125f,15);
271#endif
272 }
Jean-Marc Valin144b6e62012-11-10 10:13:03 -0500273 len2=len/2;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500274 for (c=0;c<C;c++)
275 {
276 opus_val32 mean;
277 opus_int32 unmask=0;
278 opus_val32 norm;
Jean-Marc Valin413caa02012-11-19 16:36:22 -0500279 opus_val16 maxE;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500280 mem0=0;
281 mem1=0;
282 /* High-pass filter: (1 - 2*z^-1 + z^-2) / (1 - z^-1 + .5*z^-2) */
283 for (i=0;i<len;i++)
284 {
285 opus_val32 x,y;
286 x = SHR32(in[i+c*len],SIG_SHIFT);
287 y = ADD32(mem0, x);
288#ifdef FIXED_POINT
289 mem0 = mem1 + y - SHL32(x,1);
290 mem1 = x - SHR32(y,1);
291#else
292 mem0 = mem1 + y - 2*x;
293 mem1 = x - .5f*y;
294#endif
Jean-Marc Valin84043f72016-07-24 17:54:56 -0400295 tmp[i] = SROUND16(y, 2);
Jean-Marc Valin69062102012-11-08 09:42:27 -0500296 /*printf("%f ", tmp[i]);*/
297 }
298 /*printf("\n");*/
299 /* First few samples are bad because we don't propagate the memory */
Jean-Marc Valinff072002013-12-08 23:31:30 -0500300 OPUS_CLEAR(tmp, 12);
Jean-Marc Valin69062102012-11-08 09:42:27 -0500301
302#ifdef FIXED_POINT
303 /* Normalize tmp to max range */
304 {
305 int shift=0;
Jean-Marc Valin84043f72016-07-24 17:54:56 -0400306 shift = 14-celt_ilog2(MAX16(1, celt_maxabs16(tmp, len)));
Jean-Marc Valin69062102012-11-08 09:42:27 -0500307 if (shift!=0)
308 {
309 for (i=0;i<len;i++)
310 tmp[i] = SHL16(tmp[i], shift);
311 }
312 }
313#endif
314
315 mean=0;
316 mem0=0;
Jean-Marc Valin413caa02012-11-19 16:36:22 -0500317 /* Grouping by two to reduce complexity */
Jean-Marc Valin69062102012-11-08 09:42:27 -0500318 /* Forward pass to compute the post-echo threshold*/
Jean-Marc Valin144b6e62012-11-10 10:13:03 -0500319 for (i=0;i<len2;i++)
Jean-Marc Valin69062102012-11-08 09:42:27 -0500320 {
321 opus_val16 x2 = PSHR32(MULT16_16(tmp[2*i],tmp[2*i]) + MULT16_16(tmp[2*i+1],tmp[2*i+1]),16);
322 mean += x2;
323#ifdef FIXED_POINT
324 /* FIXME: Use PSHR16() instead */
Jean-Marc Valin2af92cd2016-10-27 14:14:28 -0400325 tmp[i] = mem0 + PSHR32(x2-mem0,forward_shift);
Jean-Marc Valin69062102012-11-08 09:42:27 -0500326#else
Jean-Marc Valin2af92cd2016-10-27 14:14:28 -0400327 tmp[i] = mem0 + MULT16_16_P15(forward_decay,x2-mem0);
Jean-Marc Valin69062102012-11-08 09:42:27 -0500328#endif
329 mem0 = tmp[i];
330 }
331
332 mem0=0;
Jean-Marc Valin413caa02012-11-19 16:36:22 -0500333 maxE=0;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500334 /* Backward pass to compute the pre-echo threshold */
Jean-Marc Valin144b6e62012-11-10 10:13:03 -0500335 for (i=len2-1;i>=0;i--)
Jean-Marc Valin69062102012-11-08 09:42:27 -0500336 {
Jean-Marc Valin2af92cd2016-10-27 14:14:28 -0400337 /* Backward masking: 13.9 dB/ms. */
Jean-Marc Valin69062102012-11-08 09:42:27 -0500338#ifdef FIXED_POINT
339 /* FIXME: Use PSHR16() instead */
340 tmp[i] = mem0 + PSHR32(tmp[i]-mem0,3);
341#else
342 tmp[i] = mem0 + MULT16_16_P15(QCONST16(0.125f,15),tmp[i]-mem0);
343#endif
344 mem0 = tmp[i];
Jean-Marc Valin413caa02012-11-19 16:36:22 -0500345 maxE = MAX16(maxE, mem0);
Jean-Marc Valin69062102012-11-08 09:42:27 -0500346 }
Jean-Marc Valin413caa02012-11-19 16:36:22 -0500347 /*for (i=0;i<len2;i++)printf("%f ", tmp[i]/mean);printf("\n");*/
Jean-Marc Valin69062102012-11-08 09:42:27 -0500348
Jean-Marc Valin413caa02012-11-19 16:36:22 -0500349 /* Compute the ratio of the "frame energy" over the harmonic mean of the energy.
Jean-Marc Valin69062102012-11-08 09:42:27 -0500350 This essentially corresponds to a bitrate-normalized temporal noise-to-mask
351 ratio */
352
Jean-Marc Valin413caa02012-11-19 16:36:22 -0500353 /* As a compromise with the old transient detector, frame energy is the
354 geometric mean of the energy and half the max */
355#ifdef FIXED_POINT
356 /* Costs two sqrt() to avoid overflows */
357 mean = MULT16_16(celt_sqrt(mean), celt_sqrt(MULT16_16(maxE,len2>>1)));
358#else
Gregory Maxwell5280c712013-07-15 15:51:24 -0700359 mean = celt_sqrt(mean * maxE*.5*len2);
Jean-Marc Valin413caa02012-11-19 16:36:22 -0500360#endif
Jean-Marc Valin69062102012-11-08 09:42:27 -0500361 /* Inverse of the mean energy in Q15+6 */
Jean-Marc Valin144b6e62012-11-10 10:13:03 -0500362 norm = SHL32(EXTEND32(len2),6+14)/ADD32(EPSILON,SHR32(mean,1));
Jean-Marc Valin69062102012-11-08 09:42:27 -0500363 /* Compute harmonic mean discarding the unreliable boundaries
364 The data is smooth, so we only take 1/4th of the samples */
365 unmask=0;
Jean-Marc Valin144b6e62012-11-10 10:13:03 -0500366 for (i=12;i<len2-5;i+=4)
Jean-Marc Valin69062102012-11-08 09:42:27 -0500367 {
368 int id;
369#ifdef FIXED_POINT
Jean-Marc Valineda57aa2015-12-03 14:12:01 -0500370 id = MAX32(0,MIN32(127,MULT16_32_Q15(tmp[i]+EPSILON,norm))); /* Do not round to nearest */
Jean-Marc Valin69062102012-11-08 09:42:27 -0500371#else
Jean-Marc Valineda57aa2015-12-03 14:12:01 -0500372 id = (int)MAX32(0,MIN32(127,floor(64*norm*(tmp[i]+EPSILON)))); /* Do not round to nearest */
Jean-Marc Valin69062102012-11-08 09:42:27 -0500373#endif
374 unmask += inv_table[id];
375 }
376 /*printf("%d\n", unmask);*/
377 /* Normalize, compensate for the 1/4th of the sample and the factor of 6 in the inverse table */
Jean-Marc Valin144b6e62012-11-10 10:13:03 -0500378 unmask = 64*unmask*4/(6*(len2-17));
Jean-Marc Valin69062102012-11-08 09:42:27 -0500379 if (unmask>mask_metric)
380 {
381 *tf_chan = c;
382 mask_metric = unmask;
383 }
384 }
Jean-Marc Valin413caa02012-11-19 16:36:22 -0500385 is_transient = mask_metric>200;
Jean-Marc Valin90f20c62016-10-28 16:44:38 -0400386 /* For low bitrates, define "weak transients" that need to be
387 handled differently to avoid partial collapse. */
Jean-Marc Valin7e122392016-10-29 17:02:36 -0400388 if (allow_weak_transients && is_transient && mask_metric<600) {
Jean-Marc Valin90f20c62016-10-28 16:44:38 -0400389 is_transient = 0;
390 *weak_transient = 1;
391 }
Jean-Marc Valin69062102012-11-08 09:42:27 -0500392 /* Arbitrary metric for VBR boost */
Jean-Marc Valin413caa02012-11-19 16:36:22 -0500393 tf_max = MAX16(0,celt_sqrt(27*mask_metric)-42);
Jean-Marc Valin69062102012-11-08 09:42:27 -0500394 /* *tf_estimate = 1 + MIN16(1, sqrt(MAX16(0, tf_max-30))/20); */
Pedro Becerraa9b7def2013-12-09 16:08:29 -0500395 *tf_estimate = celt_sqrt(MAX32(0, SHL32(MULT16_16(QCONST16(0.0069,14),MIN16(163,tf_max)),14)-QCONST32(0.139,28)));
Jean-Marc Valin69062102012-11-08 09:42:27 -0500396 /*printf("%d %f\n", tf_max, mask_metric);*/
397 RESTORE_STACK;
398#ifdef FUZZING
399 is_transient = rand()&0x1;
400#endif
401 /*printf("%d %f %d\n", is_transient, (float)*tf_estimate, tf_max);*/
402 return is_transient;
403}
404
Jean-Marc Valin541a4722013-02-17 21:21:30 -0500405/* Looks for sudden increases of energy to decide whether we need to patch
406 the transient decision */
Jean-Marc Valin99618092015-12-04 16:42:19 -0500407static int patch_transient_decision(opus_val16 *newE, opus_val16 *oldE, int nbEBands,
408 int start, int end, int C)
Jean-Marc Valin541a4722013-02-17 21:21:30 -0500409{
410 int i, c;
411 opus_val32 mean_diff=0;
412 opus_val16 spread_old[26];
413 /* Apply an aggressive (-6 dB/Bark) spreading function to the old frame to
414 avoid false detection caused by irrelevant bands */
415 if (C==1)
416 {
Jean-Marc Valin99618092015-12-04 16:42:19 -0500417 spread_old[start] = oldE[start];
418 for (i=start+1;i<end;i++)
Stefan Hackera32fa312013-09-20 04:07:53 +0200419 spread_old[i] = MAX16(spread_old[i-1]-QCONST16(1.0f, DB_SHIFT), oldE[i]);
Jean-Marc Valin541a4722013-02-17 21:21:30 -0500420 } else {
Jean-Marc Valin99618092015-12-04 16:42:19 -0500421 spread_old[start] = MAX16(oldE[start],oldE[start+nbEBands]);
422 for (i=start+1;i<end;i++)
Jean-Marc Valin541a4722013-02-17 21:21:30 -0500423 spread_old[i] = MAX16(spread_old[i-1]-QCONST16(1.0f, DB_SHIFT),
Stefan Hackera32fa312013-09-20 04:07:53 +0200424 MAX16(oldE[i],oldE[i+nbEBands]));
Jean-Marc Valin541a4722013-02-17 21:21:30 -0500425 }
Jean-Marc Valin99618092015-12-04 16:42:19 -0500426 for (i=end-2;i>=start;i--)
Jean-Marc Valin541a4722013-02-17 21:21:30 -0500427 spread_old[i] = MAX16(spread_old[i], spread_old[i+1]-QCONST16(1.0f, DB_SHIFT));
428 /* Compute mean increase */
429 c=0; do {
Jean-Marc Valin99618092015-12-04 16:42:19 -0500430 for (i=IMAX(2,start);i<end-1;i++)
Jean-Marc Valin541a4722013-02-17 21:21:30 -0500431 {
432 opus_val16 x1, x2;
Jean-Marc Valin99618092015-12-04 16:42:19 -0500433 x1 = MAX16(0, newE[i + c*nbEBands]);
Jean-Marc Valin541a4722013-02-17 21:21:30 -0500434 x2 = MAX16(0, spread_old[i]);
435 mean_diff = ADD32(mean_diff, EXTEND32(MAX16(0, SUB16(x1, x2))));
436 }
437 } while (++c<C);
Jean-Marc Valin99618092015-12-04 16:42:19 -0500438 mean_diff = DIV32(mean_diff, C*(end-1-IMAX(2,start)));
Jean-Marc Valin541a4722013-02-17 21:21:30 -0500439 /*printf("%f %f %d\n", mean_diff, max_diff, count);*/
440 return mean_diff > QCONST16(1.f, DB_SHIFT);
441}
442
Jean-Marc Valin69062102012-11-08 09:42:27 -0500443/** Apply window and compute the MDCT for all sub-frames and
444 all channels in a frame */
Jean-Marc Valin851f8032013-02-18 01:43:43 -0500445static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * OPUS_RESTRICT in,
Viswanath Puttaguntaf48abe82015-05-15 12:42:19 -0500446 celt_sig * OPUS_RESTRICT out, int C, int CC, int LM, int upsample,
447 int arch)
Jean-Marc Valin69062102012-11-08 09:42:27 -0500448{
Jean-Marc Valine1f84622013-12-29 18:45:49 -0500449 const int overlap = mode->overlap;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500450 int N;
451 int B;
452 int shift;
Jean-Marc Valin851f8032013-02-18 01:43:43 -0500453 int i, b, c;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500454 if (shortBlocks)
455 {
456 B = shortBlocks;
457 N = mode->shortMdctSize;
458 shift = mode->maxLM;
459 } else {
460 B = 1;
461 N = mode->shortMdctSize<<LM;
462 shift = mode->maxLM-LM;
463 }
464 c=0; do {
465 for (b=0;b<B;b++)
466 {
467 /* Interleaving the sub-frames while doing the MDCTs */
Viswanath Puttaguntaf48abe82015-05-15 12:42:19 -0500468 clt_mdct_forward(&mode->mdct, in+c*(B*N+overlap)+b*N,
469 &out[b+c*N*B], mode->window, overlap, shift, B,
470 arch);
Jean-Marc Valin69062102012-11-08 09:42:27 -0500471 }
Jean-Marc Valin851f8032013-02-18 01:43:43 -0500472 } while (++c<CC);
473 if (CC==2&&C==1)
474 {
475 for (i=0;i<B*N;i++)
476 out[i] = ADD32(HALF32(out[i]), HALF32(out[B*N+i]));
477 }
478 if (upsample != 1)
479 {
480 c=0; do
481 {
482 int bound = B*N/upsample;
483 for (i=0;i<bound;i++)
484 out[c*B*N+i] *= upsample;
Jean-Marc Valinff072002013-12-08 23:31:30 -0500485 OPUS_CLEAR(&out[c*B*N+bound], B*N-bound);
Jean-Marc Valin851f8032013-02-18 01:43:43 -0500486 } while (++c<C);
487 }
Jean-Marc Valin69062102012-11-08 09:42:27 -0500488}
489
490
Jean-Marc Valin2dc27df2013-11-13 19:35:43 -0500491void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp,
Jean-Marc Valin69062102012-11-08 09:42:27 -0500492 int N, int CC, int upsample, const opus_val16 *coef, celt_sig *mem, int clip)
493{
494 int i;
Jean-Marc Valine368e622013-01-03 14:28:28 -0500495 opus_val16 coef0;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500496 celt_sig m;
497 int Nu;
498
499 coef0 = coef[0];
Jean-Marc Valin56269082013-12-05 16:40:59 -0500500 m = *mem;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500501
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500502 /* Fast path for the normal 48kHz case and no clipping */
503 if (coef[1] == 0 && upsample == 1 && !clip)
Jean-Marc Valin56269082013-12-05 16:40:59 -0500504 {
505 for (i=0;i<N;i++)
506 {
507 opus_val16 x;
508 x = SCALEIN(pcmp[CC*i]);
509 /* Apply pre-emphasis */
510 inp[i] = SHL32(x, SIG_SHIFT) - m;
511 m = SHR32(MULT16_16(coef0, x), 15-SIG_SHIFT);
512 }
513 *mem = m;
514 return;
515 }
Jean-Marc Valin69062102012-11-08 09:42:27 -0500516
517 Nu = N/upsample;
518 if (upsample!=1)
519 {
Jean-Marc Valinff072002013-12-08 23:31:30 -0500520 OPUS_CLEAR(inp, N);
Jean-Marc Valin69062102012-11-08 09:42:27 -0500521 }
522 for (i=0;i<Nu;i++)
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500523 inp[i*upsample] = SCALEIN(pcmp[CC*i]);
Jean-Marc Valin69062102012-11-08 09:42:27 -0500524
525#ifndef FIXED_POINT
526 if (clip)
527 {
528 /* Clip input to avoid encoding non-portable files */
529 for (i=0;i<Nu;i++)
530 inp[i*upsample] = MAX32(-65536.f, MIN32(65536.f,inp[i*upsample]));
531 }
Jean-Marc Valind6eb9c42013-11-25 22:33:43 -0500532#else
533 (void)clip; /* Avoids a warning about clip being unused. */
Jean-Marc Valin69062102012-11-08 09:42:27 -0500534#endif
Jean-Marc Valine368e622013-01-03 14:28:28 -0500535#ifdef CUSTOM_MODES
536 if (coef[1] != 0)
Jean-Marc Valin69062102012-11-08 09:42:27 -0500537 {
Jean-Marc Valine368e622013-01-03 14:28:28 -0500538 opus_val16 coef1 = coef[1];
Jean-Marc Valin69062102012-11-08 09:42:27 -0500539 opus_val16 coef2 = coef[2];
540 for (i=0;i<N;i++)
541 {
Jean-Marc Valin96408b62013-12-02 20:02:37 -0500542 celt_sig x, tmp;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500543 x = inp[i];
544 /* Apply pre-emphasis */
545 tmp = MULT16_16(coef2, x);
546 inp[i] = tmp + m;
547 m = MULT16_32_Q15(coef1, inp[i]) - MULT16_32_Q15(coef0, tmp);
548 }
Jean-Marc Valine368e622013-01-03 14:28:28 -0500549 } else
Jean-Marc Valinebdfbfb2013-01-09 11:13:00 -0500550#endif
Jean-Marc Valine368e622013-01-03 14:28:28 -0500551 {
552 for (i=0;i<N;i++)
553 {
Jean-Marc Valinaed10092013-12-05 13:36:48 -0500554 opus_val16 x;
555 x = inp[i];
Jean-Marc Valine368e622013-01-03 14:28:28 -0500556 /* Apply pre-emphasis */
Jean-Marc Valinaed10092013-12-05 13:36:48 -0500557 inp[i] = SHL32(x, SIG_SHIFT) - m;
558 m = SHR32(MULT16_16(coef0, x), 15-SIG_SHIFT);
Jean-Marc Valine368e622013-01-03 14:28:28 -0500559 }
Jean-Marc Valin69062102012-11-08 09:42:27 -0500560 }
561 *mem = m;
562}
563
564
565
566static opus_val32 l1_metric(const celt_norm *tmp, int N, int LM, opus_val16 bias)
567{
568 int i;
569 opus_val32 L1;
570 L1 = 0;
571 for (i=0;i<N;i++)
572 L1 += EXTEND32(ABS16(tmp[i]));
573 /* When in doubt, prefer good freq resolution */
574 L1 = MAC16_32_Q15(L1, LM*bias, L1);
575 return L1;
576
577}
578
Jean-Marc Valina6d663c2012-11-08 13:26:49 -0500579static int tf_analysis(const CELTMode *m, int len, int isTransient,
580 int *tf_res, int lambda, celt_norm *X, int N0, int LM,
Jean-Marc Valin2ca6df02016-06-08 02:15:21 -0400581 opus_val16 tf_estimate, int tf_chan)
Jean-Marc Valin69062102012-11-08 09:42:27 -0500582{
583 int i;
584 VARDECL(int, metric);
585 int cost0;
586 int cost1;
587 VARDECL(int, path0);
588 VARDECL(int, path1);
589 VARDECL(celt_norm, tmp);
590 VARDECL(celt_norm, tmp_1);
Jean-Marc Valin69062102012-11-08 09:42:27 -0500591 int sel;
592 int selcost[2];
593 int tf_select=0;
594 opus_val16 bias;
595
596 SAVE_STACK;
Jean-Marc Valindae16fb2012-12-13 21:40:58 -0500597 bias = MULT16_16_Q14(QCONST16(.04f,15), MAX16(-QCONST16(.25f,14), QCONST16(.5f,14)-tf_estimate));
Jean-Marc Valin69062102012-11-08 09:42:27 -0500598 /*printf("%f ", bias);*/
599
Jean-Marc Valin69062102012-11-08 09:42:27 -0500600 ALLOC(metric, len, int);
601 ALLOC(tmp, (m->eBands[len]-m->eBands[len-1])<<LM, celt_norm);
602 ALLOC(tmp_1, (m->eBands[len]-m->eBands[len-1])<<LM, celt_norm);
603 ALLOC(path0, len, int);
604 ALLOC(path1, len, int);
605
Jean-Marc Valin69062102012-11-08 09:42:27 -0500606 for (i=0;i<len;i++)
607 {
Jean-Marc Valin57cd8492013-12-09 02:33:42 -0500608 int k, N;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500609 int narrow;
610 opus_val32 L1, best_L1;
611 int best_level=0;
612 N = (m->eBands[i+1]-m->eBands[i])<<LM;
613 /* band is too narrow to be split down to LM=-1 */
614 narrow = (m->eBands[i+1]-m->eBands[i])==1;
Jean-Marc Valinff072002013-12-08 23:31:30 -0500615 OPUS_COPY(tmp, &X[tf_chan*N0 + (m->eBands[i]<<LM)], N);
Jean-Marc Valin69062102012-11-08 09:42:27 -0500616 /* Just add the right channel if we're in stereo */
617 /*if (C==2)
618 for (j=0;j<N;j++)
619 tmp[j] = ADD16(SHR16(tmp[j], 1),SHR16(X[N0+j+(m->eBands[i]<<LM)], 1));*/
620 L1 = l1_metric(tmp, N, isTransient ? LM : 0, bias);
621 best_L1 = L1;
622 /* Check the -1 case for transients */
623 if (isTransient && !narrow)
624 {
Jean-Marc Valinff072002013-12-08 23:31:30 -0500625 OPUS_COPY(tmp_1, tmp, N);
Jean-Marc Valin69062102012-11-08 09:42:27 -0500626 haar1(tmp_1, N>>LM, 1<<LM);
627 L1 = l1_metric(tmp_1, N, LM+1, bias);
628 if (L1<best_L1)
629 {
630 best_L1 = L1;
631 best_level = -1;
632 }
633 }
634 /*printf ("%f ", L1);*/
635 for (k=0;k<LM+!(isTransient||narrow);k++)
636 {
637 int B;
638
639 if (isTransient)
640 B = (LM-k-1);
641 else
642 B = k+1;
643
644 haar1(tmp, N>>k, 1<<k);
645
646 L1 = l1_metric(tmp, N, B, bias);
647
648 if (L1 < best_L1)
649 {
650 best_L1 = L1;
651 best_level = k+1;
652 }
653 }
654 /*printf ("%d ", isTransient ? LM-best_level : best_level);*/
655 /* metric is in Q1 to be able to select the mid-point (-0.5) for narrower bands */
656 if (isTransient)
657 metric[i] = 2*best_level;
658 else
659 metric[i] = -2*best_level;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500660 /* For bands that can't be split to -1, set the metric to the half-way point to avoid
661 biasing the decision */
662 if (narrow && (metric[i]==0 || metric[i]==-2*LM))
663 metric[i]-=1;
664 /*printf("%d ", metric[i]);*/
665 }
666 /*printf("\n");*/
667 /* Search for the optimal tf resolution, including tf_select */
668 tf_select = 0;
669 for (sel=0;sel<2;sel++)
670 {
671 cost0 = 0;
672 cost1 = isTransient ? 0 : lambda;
673 for (i=1;i<len;i++)
674 {
675 int curr0, curr1;
676 curr0 = IMIN(cost0, cost1 + lambda);
677 curr1 = IMIN(cost0 + lambda, cost1);
678 cost0 = curr0 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*sel+0]);
679 cost1 = curr1 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*sel+1]);
680 }
681 cost0 = IMIN(cost0, cost1);
682 selcost[sel]=cost0;
683 }
684 /* For now, we're conservative and only allow tf_select=1 for transients.
685 * If tests confirm it's useful for non-transients, we could allow it. */
686 if (selcost[1]<selcost[0] && isTransient)
687 tf_select=1;
688 cost0 = 0;
689 cost1 = isTransient ? 0 : lambda;
690 /* Viterbi forward pass */
691 for (i=1;i<len;i++)
692 {
693 int curr0, curr1;
694 int from0, from1;
695
696 from0 = cost0;
697 from1 = cost1 + lambda;
698 if (from0 < from1)
699 {
700 curr0 = from0;
701 path0[i]= 0;
702 } else {
703 curr0 = from1;
704 path0[i]= 1;
705 }
706
707 from0 = cost0 + lambda;
708 from1 = cost1;
709 if (from0 < from1)
710 {
711 curr1 = from0;
712 path1[i]= 0;
713 } else {
714 curr1 = from1;
715 path1[i]= 1;
716 }
717 cost0 = curr0 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*tf_select+0]);
718 cost1 = curr1 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*tf_select+1]);
719 }
720 tf_res[len-1] = cost0 < cost1 ? 0 : 1;
721 /* Viterbi backward pass to check the decisions */
722 for (i=len-2;i>=0;i--)
723 {
724 if (tf_res[i+1] == 1)
725 tf_res[i] = path1[i+1];
726 else
727 tf_res[i] = path0[i+1];
728 }
729 /*printf("%d %f\n", *tf_sum, tf_estimate);*/
730 RESTORE_STACK;
731#ifdef FUZZING
732 tf_select = rand()&0x1;
733 tf_res[0] = rand()&0x1;
734 for (i=1;i<len;i++)
735 tf_res[i] = tf_res[i-1] ^ ((rand()&0xF) == 0);
736#endif
737 return tf_select;
738}
739
740static void tf_encode(int start, int end, int isTransient, int *tf_res, int LM, int tf_select, ec_enc *enc)
741{
742 int curr, i;
743 int tf_select_rsv;
744 int tf_changed;
745 int logp;
746 opus_uint32 budget;
747 opus_uint32 tell;
748 budget = enc->storage*8;
749 tell = ec_tell(enc);
750 logp = isTransient ? 2 : 4;
751 /* Reserve space to code the tf_select decision. */
752 tf_select_rsv = LM>0 && tell+logp+1 <= budget;
753 budget -= tf_select_rsv;
754 curr = tf_changed = 0;
755 for (i=start;i<end;i++)
756 {
757 if (tell+logp<=budget)
758 {
759 ec_enc_bit_logp(enc, tf_res[i] ^ curr, logp);
760 tell = ec_tell(enc);
761 curr = tf_res[i];
762 tf_changed |= curr;
763 }
764 else
765 tf_res[i] = curr;
766 logp = isTransient ? 4 : 5;
767 }
768 /* Only code tf_select if it would actually make a difference. */
769 if (tf_select_rsv &&
770 tf_select_table[LM][4*isTransient+0+tf_changed]!=
771 tf_select_table[LM][4*isTransient+2+tf_changed])
772 ec_enc_bit_logp(enc, tf_select, 1);
773 else
774 tf_select = 0;
775 for (i=start;i<end;i++)
776 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
777 /*for(i=0;i<end;i++)printf("%d ", isTransient ? tf_res[i] : LM+tf_res[i]);printf("\n");*/
778}
779
780
781static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X,
782 const opus_val16 *bandLogE, int end, int LM, int C, int N0,
783 AnalysisInfo *analysis, opus_val16 *stereo_saving, opus_val16 tf_estimate,
xiangmingzhuc95c9a02014-04-30 15:48:07 +0800784 int intensity, opus_val16 surround_trim, int arch)
Jean-Marc Valin69062102012-11-08 09:42:27 -0500785{
786 int i;
787 opus_val32 diff=0;
788 int c;
Jean-Marc Valin4a168eb2013-12-11 01:34:06 -0500789 int trim_index;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500790 opus_val16 trim = QCONST16(5.f, 8);
791 opus_val16 logXC, logXC2;
792 if (C==2)
793 {
794 opus_val16 sum = 0; /* Q10 */
795 opus_val16 minXC; /* Q10 */
796 /* Compute inter-channel correlation for low frequencies */
797 for (i=0;i<8;i++)
798 {
Jean-Marc Valin57cd8492013-12-09 02:33:42 -0500799 opus_val32 partial;
xiangmingzhuc95c9a02014-04-30 15:48:07 +0800800 partial = celt_inner_prod(&X[m->eBands[i]<<LM], &X[N0+(m->eBands[i]<<LM)],
801 (m->eBands[i+1]-m->eBands[i])<<LM, arch);
Jean-Marc Valin69062102012-11-08 09:42:27 -0500802 sum = ADD16(sum, EXTRACT16(SHR32(partial, 18)));
803 }
804 sum = MULT16_16_Q15(QCONST16(1.f/8, 15), sum);
805 sum = MIN16(QCONST16(1.f, 10), ABS16(sum));
806 minXC = sum;
807 for (i=8;i<intensity;i++)
808 {
Jean-Marc Valin57cd8492013-12-09 02:33:42 -0500809 opus_val32 partial;
xiangmingzhuc95c9a02014-04-30 15:48:07 +0800810 partial = celt_inner_prod(&X[m->eBands[i]<<LM], &X[N0+(m->eBands[i]<<LM)],
811 (m->eBands[i+1]-m->eBands[i])<<LM, arch);
Jean-Marc Valin69062102012-11-08 09:42:27 -0500812 minXC = MIN16(minXC, ABS16(EXTRACT16(SHR32(partial, 18))));
813 }
814 minXC = MIN16(QCONST16(1.f, 10), ABS16(minXC));
815 /*printf ("%f\n", sum);*/
Jean-Marc Valin69062102012-11-08 09:42:27 -0500816 /* mid-side savings estimations based on the LF average*/
817 logXC = celt_log2(QCONST32(1.001f, 20)-MULT16_16(sum, sum));
818 /* mid-side savings estimations based on min correlation */
819 logXC2 = MAX16(HALF16(logXC), celt_log2(QCONST32(1.001f, 20)-MULT16_16(minXC, minXC)));
820#ifdef FIXED_POINT
821 /* Compensate for Q20 vs Q14 input and convert output to Q8 */
822 logXC = PSHR32(logXC-QCONST16(6.f, DB_SHIFT),DB_SHIFT-8);
823 logXC2 = PSHR32(logXC2-QCONST16(6.f, DB_SHIFT),DB_SHIFT-8);
824#endif
825
826 trim += MAX16(-QCONST16(4.f, 8), MULT16_16_Q15(QCONST16(.75f,15),logXC));
827 *stereo_saving = MIN16(*stereo_saving + QCONST16(0.25f, 8), -HALF16(logXC2));
828 }
829
830 /* Estimate spectral tilt */
831 c=0; do {
832 for (i=0;i<end-1;i++)
833 {
834 diff += bandLogE[i+c*m->nbEBands]*(opus_int32)(2+2*i-end);
835 }
836 } while (++c<C);
837 diff /= C*(end-1);
838 /*printf("%f\n", diff);*/
Jean-Marc Valin69062102012-11-08 09:42:27 -0500839 trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8), SHR16(diff+QCONST16(1.f, DB_SHIFT),DB_SHIFT-8)/6 ));
Jean-Marc Valin0f686962013-09-05 12:49:55 -0400840 trim -= SHR16(surround_trim, DB_SHIFT-8);
Jean-Marc Valindae16fb2012-12-13 21:40:58 -0500841 trim -= 2*SHR16(tf_estimate, 14-8);
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -0400842#ifndef DISABLE_FLOAT_API
Jean-Marc Valin69062102012-11-08 09:42:27 -0500843 if (analysis->valid)
844 {
Jean-Marc Valina71c9ad2013-11-13 12:07:01 -0500845 trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8),
846 (opus_val16)(QCONST16(2.f, 8)*(analysis->tonality_slope+.05f))));
Jean-Marc Valin69062102012-11-08 09:42:27 -0500847 }
Timothy B. Terriberry23f503a2014-12-26 08:31:39 -0800848#else
849 (void)analysis;
Jean-Marc Valin69062102012-11-08 09:42:27 -0500850#endif
851
852#ifdef FIXED_POINT
853 trim_index = PSHR32(trim, 8);
854#else
Jean-Marc Valind683c762012-12-21 16:17:38 -0500855 trim_index = (int)floor(.5f+trim);
Jean-Marc Valin69062102012-11-08 09:42:27 -0500856#endif
Jean-Marc Valin4a168eb2013-12-11 01:34:06 -0500857 trim_index = IMAX(0, IMIN(10, trim_index));
Jean-Marc Valin69062102012-11-08 09:42:27 -0500858 /*printf("%d\n", trim_index);*/
859#ifdef FUZZING
860 trim_index = rand()%11;
861#endif
862 return trim_index;
863}
864
865static int stereo_analysis(const CELTMode *m, const celt_norm *X,
866 int LM, int N0)
867{
868 int i;
869 int thetas;
870 opus_val32 sumLR = EPSILON, sumMS = EPSILON;
871
872 /* Use the L1 norm to model the entropy of the L/R signal vs the M/S signal */
873 for (i=0;i<13;i++)
874 {
875 int j;
876 for (j=m->eBands[i]<<LM;j<m->eBands[i+1]<<LM;j++)
877 {
878 opus_val32 L, R, M, S;
879 /* We cast to 32-bit first because of the -32768 case */
880 L = EXTEND32(X[j]);
881 R = EXTEND32(X[N0+j]);
882 M = ADD32(L, R);
883 S = SUB32(L, R);
884 sumLR = ADD32(sumLR, ADD32(ABS32(L), ABS32(R)));
885 sumMS = ADD32(sumMS, ADD32(ABS32(M), ABS32(S)));
886 }
887 }
888 sumMS = MULT16_32_Q15(QCONST16(0.707107f, 15), sumMS);
889 thetas = 13;
890 /* We don't need thetas for lower bands with LM<=1 */
891 if (LM<=1)
892 thetas -= 8;
893 return MULT16_32_Q15((m->eBands[13]<<(LM+1))+thetas, sumMS)
894 > MULT16_32_Q15(m->eBands[13]<<(LM+1), sumLR);
895}
896
Jean-Marc Valin05548fa2014-01-19 01:31:00 -0500897#define MSWAP(a,b) do {opus_val16 tmp = a;a=b;b=tmp;} while(0)
898static opus_val16 median_of_5(const opus_val16 *x)
899{
900 opus_val16 t0, t1, t2, t3, t4;
901 t2 = x[2];
902 if (x[0] > x[1])
903 {
904 t0 = x[1];
905 t1 = x[0];
906 } else {
907 t0 = x[0];
908 t1 = x[1];
909 }
910 if (x[3] > x[4])
911 {
912 t3 = x[4];
913 t4 = x[3];
914 } else {
915 t3 = x[3];
916 t4 = x[4];
917 }
918 if (t0 > t3)
919 {
920 MSWAP(t0, t3);
921 MSWAP(t1, t4);
922 }
923 if (t2 > t1)
924 {
925 if (t1 < t3)
926 return MIN16(t2, t3);
927 else
928 return MIN16(t4, t1);
929 } else {
930 if (t2 < t3)
931 return MIN16(t1, t3);
932 else
933 return MIN16(t2, t4);
934 }
935}
936
937static opus_val16 median_of_3(const opus_val16 *x)
938{
939 opus_val16 t0, t1, t2;
940 if (x[0] > x[1])
941 {
942 t0 = x[1];
943 t1 = x[0];
944 } else {
945 t0 = x[0];
946 t1 = x[1];
947 }
948 t2 = x[2];
949 if (t1 < t2)
950 return t1;
951 else if (t0 < t2)
952 return t2;
953 else
954 return t0;
955}
956
Jean-Marc Valind683c762012-12-21 16:17:38 -0500957static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16 *bandLogE2,
Jean-Marc Valin10b30e72012-11-10 00:44:03 -0500958 int nbEBands, int start, int end, int C, int *offsets, int lsb_depth, const opus_int16 *logN,
959 int isTransient, int vbr, int constrained_vbr, const opus_int16 *eBands, int LM,
Jean-Marc Valin0f686962013-09-05 12:49:55 -0400960 int effectiveBytes, opus_int32 *tot_boost_, int lfe, opus_val16 *surround_dynalloc)
Jean-Marc Valin10b30e72012-11-10 00:44:03 -0500961{
962 int i, c;
963 opus_int32 tot_boost=0;
964 opus_val16 maxDepth;
965 VARDECL(opus_val16, follower);
966 VARDECL(opus_val16, noise_floor);
967 SAVE_STACK;
968 ALLOC(follower, C*nbEBands, opus_val16);
969 ALLOC(noise_floor, C*nbEBands, opus_val16);
Jean-Marc Valinff072002013-12-08 23:31:30 -0500970 OPUS_CLEAR(offsets, nbEBands);
Jean-Marc Valin10b30e72012-11-10 00:44:03 -0500971 /* Dynamic allocation code */
Jean-Marc Valin82594922013-07-25 13:52:42 -0400972 maxDepth=-QCONST16(31.9f, DB_SHIFT);
Jean-Marc Valin10b30e72012-11-10 00:44:03 -0500973 for (i=0;i<end;i++)
974 {
975 /* Noise floor must take into account eMeans, the depth, the width of the bands
976 and the preemphasis filter (approx. square of bark band ID) */
977 noise_floor[i] = MULT16_16(QCONST16(0.0625f, DB_SHIFT),logN[i])
978 +QCONST16(.5f,DB_SHIFT)+SHL16(9-lsb_depth,DB_SHIFT)-SHL16(eMeans[i],6)
979 +MULT16_16(QCONST16(.0062,DB_SHIFT),(i+5)*(i+5));
980 }
981 c=0;do
982 {
983 for (i=0;i<end;i++)
984 maxDepth = MAX16(maxDepth, bandLogE[c*nbEBands+i]-noise_floor[i]);
985 } while (++c<C);
986 /* Make sure that dynamic allocation can't make us bust the budget */
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -0400987 if (effectiveBytes > 50 && LM>=1 && !lfe)
Jean-Marc Valin10b30e72012-11-10 00:44:03 -0500988 {
989 int last=0;
990 c=0;do
991 {
Jean-Marc Valin05548fa2014-01-19 01:31:00 -0500992 opus_val16 offset;
993 opus_val16 tmp;
Jean-Marc Valin379af352014-01-19 01:42:04 -0500994 opus_val16 *f;
995 f = &follower[c*nbEBands];
996 f[0] = bandLogE2[c*nbEBands];
Jean-Marc Valin10b30e72012-11-10 00:44:03 -0500997 for (i=1;i<end;i++)
998 {
999 /* The last band to be at least 3 dB higher than the previous one
1000 is the last we'll consider. Otherwise, we run into problems on
1001 bandlimited signals. */
1002 if (bandLogE2[c*nbEBands+i] > bandLogE2[c*nbEBands+i-1]+QCONST16(.5f,DB_SHIFT))
1003 last=i;
Jean-Marc Valin379af352014-01-19 01:42:04 -05001004 f[i] = MIN16(f[i-1]+QCONST16(1.5f,DB_SHIFT), bandLogE2[c*nbEBands+i]);
Jean-Marc Valin10b30e72012-11-10 00:44:03 -05001005 }
1006 for (i=last-1;i>=0;i--)
Jean-Marc Valin379af352014-01-19 01:42:04 -05001007 f[i] = MIN16(f[i], MIN16(f[i+1]+QCONST16(2.f,DB_SHIFT), bandLogE2[c*nbEBands+i]));
Jean-Marc Valin05548fa2014-01-19 01:31:00 -05001008
1009 /* Combine with a median filter to avoid dynalloc triggering unnecessarily.
1010 The "offset" value controls how conservative we are -- a higher offset
1011 reduces the impact of the median filter and makes dynalloc use more bits. */
1012 offset = QCONST16(1.f, DB_SHIFT);
1013 for (i=2;i<end-2;i++)
Jean-Marc Valin379af352014-01-19 01:42:04 -05001014 f[i] = MAX16(f[i], median_of_5(&bandLogE2[c*nbEBands+i-2])-offset);
Jean-Marc Valin05548fa2014-01-19 01:31:00 -05001015 tmp = median_of_3(&bandLogE2[c*nbEBands])-offset;
Jean-Marc Valin379af352014-01-19 01:42:04 -05001016 f[0] = MAX16(f[0], tmp);
1017 f[1] = MAX16(f[1], tmp);
Jean-Marc Valince1173c2014-01-20 18:45:57 -05001018 tmp = median_of_3(&bandLogE2[c*nbEBands+end-3])-offset;
1019 f[end-2] = MAX16(f[end-2], tmp);
1020 f[end-1] = MAX16(f[end-1], tmp);
Jean-Marc Valin05548fa2014-01-19 01:31:00 -05001021
Jean-Marc Valin10b30e72012-11-10 00:44:03 -05001022 for (i=0;i<end;i++)
Jean-Marc Valin379af352014-01-19 01:42:04 -05001023 f[i] = MAX16(f[i], noise_floor[i]);
Jean-Marc Valin10b30e72012-11-10 00:44:03 -05001024 } while (++c<C);
1025 if (C==2)
1026 {
1027 for (i=start;i<end;i++)
1028 {
1029 /* Consider 24 dB "cross-talk" */
1030 follower[nbEBands+i] = MAX16(follower[nbEBands+i], follower[ i]-QCONST16(4.f,DB_SHIFT));
1031 follower[ i] = MAX16(follower[ i], follower[nbEBands+i]-QCONST16(4.f,DB_SHIFT));
1032 follower[i] = HALF16(MAX16(0, bandLogE[i]-follower[i]) + MAX16(0, bandLogE[nbEBands+i]-follower[nbEBands+i]));
1033 }
1034 } else {
1035 for (i=start;i<end;i++)
1036 {
1037 follower[i] = MAX16(0, bandLogE[i]-follower[i]);
1038 }
1039 }
Jean-Marc Valin0f686962013-09-05 12:49:55 -04001040 for (i=start;i<end;i++)
1041 follower[i] = MAX16(follower[i], surround_dynalloc[i]);
Jean-Marc Valin10b30e72012-11-10 00:44:03 -05001042 /* For non-transient CBR/CVBR frames, halve the dynalloc contribution */
1043 if ((!vbr || constrained_vbr)&&!isTransient)
1044 {
1045 for (i=start;i<end;i++)
1046 follower[i] = HALF16(follower[i]);
1047 }
1048 for (i=start;i<end;i++)
1049 {
1050 int width;
1051 int boost;
1052 int boost_bits;
1053
1054 if (i<8)
1055 follower[i] *= 2;
1056 if (i>=12)
1057 follower[i] = HALF16(follower[i]);
1058 follower[i] = MIN16(follower[i], QCONST16(4, DB_SHIFT));
1059
1060 width = C*(eBands[i+1]-eBands[i])<<LM;
1061 if (width<6)
1062 {
Jean-Marc Valind683c762012-12-21 16:17:38 -05001063 boost = (int)SHR32(EXTEND32(follower[i]),DB_SHIFT);
Jean-Marc Valin10b30e72012-11-10 00:44:03 -05001064 boost_bits = boost*width<<BITRES;
1065 } else if (width > 48) {
Jean-Marc Valind683c762012-12-21 16:17:38 -05001066 boost = (int)SHR32(EXTEND32(follower[i])*8,DB_SHIFT);
Jean-Marc Valin10b30e72012-11-10 00:44:03 -05001067 boost_bits = (boost*width<<BITRES)/8;
1068 } else {
Jean-Marc Valind683c762012-12-21 16:17:38 -05001069 boost = (int)SHR32(EXTEND32(follower[i])*width/6,DB_SHIFT);
Jean-Marc Valin10b30e72012-11-10 00:44:03 -05001070 boost_bits = boost*6<<BITRES;
1071 }
1072 /* For CBR and non-transient CVBR frames, limit dynalloc to 1/4 of the bits */
1073 if ((!vbr || (constrained_vbr&&!isTransient))
1074 && (tot_boost+boost_bits)>>BITRES>>3 > effectiveBytes/4)
1075 {
Jean-Marc Valine4550922013-07-30 05:12:46 -04001076 opus_int32 cap = ((effectiveBytes/4)<<BITRES<<3);
1077 offsets[i] = cap-tot_boost;
1078 tot_boost = cap;
Jean-Marc Valin10b30e72012-11-10 00:44:03 -05001079 break;
1080 } else {
1081 offsets[i] = boost;
1082 tot_boost += boost_bits;
1083 }
1084 }
1085 }
1086 *tot_boost_ = tot_boost;
1087 RESTORE_STACK;
1088 return maxDepth;
1089}
1090
1091
Jean-Marc Valin69062102012-11-08 09:42:27 -05001092static int run_prefilter(CELTEncoder *st, celt_sig *in, celt_sig *prefilter_mem, int CC, int N,
1093 int prefilter_tapset, int *pitch, opus_val16 *gain, int *qgain, int enabled, int nbAvailableBytes)
1094{
1095 int c;
1096 VARDECL(celt_sig, _pre);
1097 celt_sig *pre[2];
1098 const CELTMode *mode;
1099 int pitch_index;
1100 opus_val16 gain1;
1101 opus_val16 pf_threshold;
1102 int pf_on;
1103 int qg;
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001104 int overlap;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001105 SAVE_STACK;
1106
1107 mode = st->mode;
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001108 overlap = mode->overlap;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001109 ALLOC(_pre, CC*(N+COMBFILTER_MAXPERIOD), celt_sig);
1110
1111 pre[0] = _pre;
1112 pre[1] = _pre + (N+COMBFILTER_MAXPERIOD);
1113
1114
1115 c=0; do {
1116 OPUS_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD);
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001117 OPUS_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+overlap)+overlap, N);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001118 } while (++c<CC);
1119
1120 if (enabled)
1121 {
1122 VARDECL(opus_val16, pitch_buf);
1123 ALLOC(pitch_buf, (COMBFILTER_MAXPERIOD+N)>>1, opus_val16);
1124
Timothy B. Terriberry39386e02013-11-18 13:30:13 -05001125 pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC, st->arch);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001126 /* Don't search for the fir last 1.5 octave of the range because
1127 there's too many false-positives due to short-term correlation */
1128 pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N,
Timothy B. Terriberry39386e02013-11-18 13:30:13 -05001129 COMBFILTER_MAXPERIOD-3*COMBFILTER_MINPERIOD, &pitch_index,
1130 st->arch);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001131 pitch_index = COMBFILTER_MAXPERIOD-pitch_index;
1132
1133 gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD,
xiangmingzhuc95c9a02014-04-30 15:48:07 +08001134 N, &pitch_index, st->prefilter_period, st->prefilter_gain, st->arch);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001135 if (pitch_index > COMBFILTER_MAXPERIOD-2)
1136 pitch_index = COMBFILTER_MAXPERIOD-2;
1137 gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1);
1138 /*printf("%d %d %f %f\n", pitch_change, pitch_index, gain1, st->analysis.tonality);*/
1139 if (st->loss_rate>2)
1140 gain1 = HALF32(gain1);
1141 if (st->loss_rate>4)
1142 gain1 = HALF32(gain1);
1143 if (st->loss_rate>8)
1144 gain1 = 0;
1145 } else {
1146 gain1 = 0;
1147 pitch_index = COMBFILTER_MINPERIOD;
1148 }
1149
1150 /* Gain threshold for enabling the prefilter/postfilter */
1151 pf_threshold = QCONST16(.2f,15);
1152
1153 /* Adjusting the threshold based on rate and continuity */
1154 if (abs(pitch_index-st->prefilter_period)*10>pitch_index)
1155 pf_threshold += QCONST16(.2f,15);
1156 if (nbAvailableBytes<25)
1157 pf_threshold += QCONST16(.1f,15);
1158 if (nbAvailableBytes<35)
1159 pf_threshold += QCONST16(.1f,15);
1160 if (st->prefilter_gain > QCONST16(.4f,15))
1161 pf_threshold -= QCONST16(.1f,15);
1162 if (st->prefilter_gain > QCONST16(.55f,15))
1163 pf_threshold -= QCONST16(.1f,15);
1164
1165 /* Hard threshold at 0.2 */
1166 pf_threshold = MAX16(pf_threshold, QCONST16(.2f,15));
1167 if (gain1<pf_threshold)
1168 {
1169 gain1 = 0;
1170 pf_on = 0;
1171 qg = 0;
1172 } else {
1173 /*This block is not gated by a total bits check only because
1174 of the nbAvailableBytes check above.*/
1175 if (ABS16(gain1-st->prefilter_gain)<QCONST16(.1f,15))
1176 gain1=st->prefilter_gain;
1177
1178#ifdef FIXED_POINT
1179 qg = ((gain1+1536)>>10)/3-1;
1180#else
1181 qg = (int)floor(.5f+gain1*32/3)-1;
1182#endif
1183 qg = IMAX(0, IMIN(7, qg));
1184 gain1 = QCONST16(0.09375f,15)*(qg+1);
1185 pf_on = 1;
1186 }
1187 /*printf("%d %f\n", pitch_index, gain1);*/
1188
1189 c=0; do {
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001190 int offset = mode->shortMdctSize-overlap;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001191 st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001192 OPUS_COPY(in+c*(N+overlap), st->in_mem+c*(overlap), overlap);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001193 if (offset)
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001194 comb_filter(in+c*(N+overlap)+overlap, pre[c]+COMBFILTER_MAXPERIOD,
Jean-Marc Valin69062102012-11-08 09:42:27 -05001195 st->prefilter_period, st->prefilter_period, offset, -st->prefilter_gain, -st->prefilter_gain,
Jonathan Lennox43120f02015-08-03 17:04:27 -04001196 st->prefilter_tapset, st->prefilter_tapset, NULL, 0, st->arch);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001197
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001198 comb_filter(in+c*(N+overlap)+overlap+offset, pre[c]+COMBFILTER_MAXPERIOD+offset,
Jean-Marc Valin69062102012-11-08 09:42:27 -05001199 st->prefilter_period, pitch_index, N-offset, -st->prefilter_gain, -gain1,
Jonathan Lennox43120f02015-08-03 17:04:27 -04001200 st->prefilter_tapset, prefilter_tapset, mode->window, overlap, st->arch);
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001201 OPUS_COPY(st->in_mem+c*(overlap), in+c*(N+overlap)+N, overlap);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001202
1203 if (N>COMBFILTER_MAXPERIOD)
1204 {
Jean-Marc Valinb66080a2016-06-20 12:11:05 -04001205 OPUS_COPY(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001206 } else {
1207 OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, prefilter_mem+c*COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD-N);
Jean-Marc Valinb66080a2016-06-20 12:11:05 -04001208 OPUS_COPY(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001209 }
1210 } while (++c<CC);
1211
1212 RESTORE_STACK;
1213 *gain = gain1;
1214 *pitch = pitch_index;
1215 *qgain = qg;
1216 return pf_on;
1217}
1218
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001219static int compute_vbr(const CELTMode *mode, AnalysisInfo *analysis, opus_int32 base_target,
1220 int LM, opus_int32 bitrate, int lastCodedBands, int C, int intensity,
1221 int constrained_vbr, opus_val16 stereo_saving, int tot_boost,
1222 opus_val16 tf_estimate, int pitch_change, opus_val16 maxDepth,
Jean-Marc Valin3c0aa8f2013-06-25 14:10:27 -04001223 int variable_duration, int lfe, int has_surround_mask, opus_val16 surround_masking,
1224 opus_val16 temporal_vbr)
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001225{
1226 /* The target rate in 8th bits per frame */
1227 opus_int32 target;
1228 int coded_bins;
1229 int coded_bands;
Jean-Marc Valin39cbc452013-06-13 15:28:53 -04001230 opus_val16 tf_calibration;
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001231 int nbEBands;
1232 const opus_int16 *eBands;
1233
1234 nbEBands = mode->nbEBands;
1235 eBands = mode->eBands;
1236
1237 coded_bands = lastCodedBands ? lastCodedBands : nbEBands;
1238 coded_bins = eBands[coded_bands]<<LM;
1239 if (C==2)
1240 coded_bins += eBands[IMIN(intensity, coded_bands)]<<LM;
1241
1242 target = base_target;
1243
1244 /*printf("%f %f %f %f %d %d ", st->analysis.activity, st->analysis.tonality, tf_estimate, st->stereo_saving, tot_boost, coded_bands);*/
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -04001245#ifndef DISABLE_FLOAT_API
Gregory Maxwell5280c712013-07-15 15:51:24 -07001246 if (analysis->valid && analysis->activity<.4)
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001247 target -= (opus_int32)((coded_bins<<BITRES)*(.4f-analysis->activity));
1248#endif
1249 /* Stereo savings */
1250 if (C==2)
1251 {
1252 int coded_stereo_bands;
1253 int coded_stereo_dof;
1254 opus_val16 max_frac;
1255 coded_stereo_bands = IMIN(intensity, coded_bands);
1256 coded_stereo_dof = (eBands[coded_stereo_bands]<<LM)-coded_stereo_bands;
1257 /* Maximum fraction of the bits we can save if the signal is mono. */
1258 max_frac = DIV32_16(MULT16_16(QCONST16(0.8f, 15), coded_stereo_dof), coded_bins);
Jean-Marc Valin9c23f5c2013-10-28 14:15:18 -04001259 stereo_saving = MIN16(stereo_saving, QCONST16(1.f, 8));
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001260 /*printf("%d %d %d ", coded_stereo_dof, coded_bins, tot_boost);*/
1261 target -= (opus_int32)MIN32(MULT16_32_Q15(max_frac,target),
1262 SHR32(MULT16_16(stereo_saving-QCONST16(0.1f,8),(coded_stereo_dof<<BITRES)),8));
1263 }
1264 /* Boost the rate according to dynalloc (minus the dynalloc average for calibration). */
1265 target += tot_boost-(16<<LM);
1266 /* Apply transient boost, compensating for average boost. */
Jean-Marc Valin39cbc452013-06-13 15:28:53 -04001267 tf_calibration = variable_duration==OPUS_FRAMESIZE_VARIABLE ?
1268 QCONST16(0.02f,14) : QCONST16(0.04f,14);
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001269 target += (opus_int32)SHL32(MULT16_32_Q15(tf_estimate-tf_calibration, target),1);
1270
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -04001271#ifndef DISABLE_FLOAT_API
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001272 /* Apply tonality boost */
Jean-Marc Valincd373b52013-07-07 02:51:07 -04001273 if (analysis->valid && !lfe)
1274 {
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001275 opus_int32 tonal_target;
1276 float tonal;
1277
1278 /* Tonality boost (compensating for the average). */
1279 tonal = MAX16(0.f,analysis->tonality-.15f)-0.09f;
1280 tonal_target = target + (opus_int32)((coded_bins<<BITRES)*1.2f*tonal);
1281 if (pitch_change)
1282 tonal_target += (opus_int32)((coded_bins<<BITRES)*.8f);
Jean-Marc Valin942fc812013-10-01 19:27:30 -04001283 /*printf("%f %f ", analysis->tonality, tonal);*/
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001284 target = tonal_target;
1285 }
Timothy B. Terriberry23f503a2014-12-26 08:31:39 -08001286#else
1287 (void)analysis;
1288 (void)pitch_change;
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001289#endif
1290
1291 if (has_surround_mask&&!lfe)
1292 {
Jean-Marc Valin16ba19a2013-06-27 03:40:44 -04001293 opus_int32 surround_target = target + (opus_int32)SHR32(MULT16_16(surround_masking,coded_bins<<BITRES), DB_SHIFT);
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001294 /*printf("%f %d %d %d %d %d %d ", surround_masking, coded_bins, st->end, st->intensity, surround_target, target, st->bitrate);*/
1295 target = IMAX(target/4, surround_target);
1296 }
1297
1298 {
1299 opus_int32 floor_depth;
1300 int bins;
1301 bins = eBands[nbEBands-2]<<LM;
1302 /*floor_depth = SHR32(MULT16_16((C*bins<<BITRES),celt_log2(SHL32(MAX16(1,sample_max),13))), DB_SHIFT);*/
1303 floor_depth = (opus_int32)SHR32(MULT16_16((C*bins<<BITRES),maxDepth), DB_SHIFT);
1304 floor_depth = IMAX(floor_depth, target>>2);
1305 target = IMIN(target, floor_depth);
1306 /*printf("%f %d\n", maxDepth, floor_depth);*/
1307 }
1308
Jean-Marc Valin59618a52015-11-16 23:03:17 -05001309 /* Make VBR less aggressive for constrained VBR because we can't keep a higher bitrate
1310 for long. Needs tuning. */
1311 if ((!has_surround_mask||lfe) && constrained_vbr)
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001312 {
Jean-Marc Valin59618a52015-11-16 23:03:17 -05001313 target = base_target + (opus_int32)MULT16_32_Q15(QCONST16(0.67f, 15), target-base_target);
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001314 }
Jean-Marc Valin3c0aa8f2013-06-25 14:10:27 -04001315
Jean-Marc Valincd373b52013-07-07 02:51:07 -04001316 if (!has_surround_mask && tf_estimate < QCONST16(.2f, 14))
Jean-Marc Valin3c0aa8f2013-06-25 14:10:27 -04001317 {
1318 opus_val16 amount;
1319 opus_val16 tvbr_factor;
Jean-Marc Valin8e3a1cb2013-07-01 16:12:27 -04001320 amount = MULT16_16_Q15(QCONST16(.0000031f, 30), IMAX(0, IMIN(32000, 96000-bitrate)));
Jean-Marc Valin3c0aa8f2013-06-25 14:10:27 -04001321 tvbr_factor = SHR32(MULT16_16(temporal_vbr, amount), DB_SHIFT);
1322 target += (opus_int32)MULT16_32_Q15(tvbr_factor, target);
1323 }
1324
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001325 /* Don't allow more than doubling the rate */
1326 target = IMIN(2*base_target, target);
1327
1328 return target;
1329}
1330
Jean-Marc Valin69062102012-11-08 09:42:27 -05001331int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
1332{
1333 int i, c, N;
1334 opus_int32 bits;
1335 ec_enc _enc;
1336 VARDECL(celt_sig, in);
1337 VARDECL(celt_sig, freq);
1338 VARDECL(celt_norm, X);
1339 VARDECL(celt_ener, bandE);
1340 VARDECL(opus_val16, bandLogE);
1341 VARDECL(opus_val16, bandLogE2);
1342 VARDECL(int, fine_quant);
1343 VARDECL(opus_val16, error);
1344 VARDECL(int, pulses);
1345 VARDECL(int, cap);
1346 VARDECL(int, offsets);
1347 VARDECL(int, fine_priority);
1348 VARDECL(int, tf_res);
1349 VARDECL(unsigned char, collapse_masks);
1350 celt_sig *prefilter_mem;
Jean-Marc Valin6fccb4b2016-07-04 01:06:11 -04001351 opus_val16 *oldBandE, *oldLogE, *oldLogE2, *energyError;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001352 int shortBlocks=0;
1353 int isTransient=0;
1354 const int CC = st->channels;
1355 const int C = st->stream_channels;
1356 int LM, M;
1357 int tf_select;
1358 int nbFilledBytes, nbAvailableBytes;
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001359 int start;
1360 int end;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001361 int effEnd;
1362 int codedBands;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001363 int alloc_trim;
1364 int pitch_index=COMBFILTER_MINPERIOD;
1365 opus_val16 gain1 = 0;
1366 int dual_stereo=0;
1367 int effectiveBytes;
1368 int dynalloc_logp;
1369 opus_int32 vbr_rate;
1370 opus_int32 total_bits;
1371 opus_int32 total_boost;
1372 opus_int32 balance;
1373 opus_int32 tell;
Jean-Marc Valinbcd6aba2015-12-06 10:50:15 -05001374 opus_int32 tell0_frac;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001375 int prefilter_tapset=0;
1376 int pf_on;
1377 int anti_collapse_rsv;
1378 int anti_collapse_on=0;
1379 int silence=0;
1380 int tf_chan = 0;
1381 opus_val16 tf_estimate;
1382 int pitch_change=0;
Jean-Marc Valin10b30e72012-11-10 00:44:03 -05001383 opus_int32 tot_boost;
Jean-Marc Valinb7bd4c22013-05-18 23:33:48 -04001384 opus_val32 sample_max;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001385 opus_val16 maxDepth;
1386 const OpusCustomMode *mode;
1387 int nbEBands;
1388 int overlap;
1389 const opus_int16 *eBands;
1390 int secondMdct;
Jean-Marc Valin5fb50ad2012-12-21 01:23:26 -05001391 int signalBandwidth;
Jean-Marc Valinf77410d2013-04-19 22:44:03 -04001392 int transient_got_disabled=0;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -04001393 opus_val16 surround_masking=0;
Jean-Marc Valin3c0aa8f2013-06-25 14:10:27 -04001394 opus_val16 temporal_vbr=0;
Jean-Marc Valin0f686962013-09-05 12:49:55 -04001395 opus_val16 surround_trim = 0;
Jean-Marc Valin14845912016-06-08 02:33:56 -04001396 opus_int32 equiv_rate;
Jean-Marc Valinbcd6aba2015-12-06 10:50:15 -05001397 int hybrid;
Jean-Marc Valin90f20c62016-10-28 16:44:38 -04001398 int weak_transient = 0;
Jean-Marc Valin0f686962013-09-05 12:49:55 -04001399 VARDECL(opus_val16, surround_dynalloc);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001400 ALLOC_STACK;
1401
1402 mode = st->mode;
1403 nbEBands = mode->nbEBands;
1404 overlap = mode->overlap;
1405 eBands = mode->eBands;
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001406 start = st->start;
1407 end = st->end;
Jean-Marc Valinbcd6aba2015-12-06 10:50:15 -05001408 hybrid = start != 0;
Jean-Marc Valindae16fb2012-12-13 21:40:58 -05001409 tf_estimate = 0;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001410 if (nbCompressedBytes<2 || pcm==NULL)
Jean-Marc Valine83d2aa2013-11-15 01:52:28 -05001411 {
Jean-Marc Valin1b28e0c2013-11-15 01:57:25 -05001412 RESTORE_STACK;
Jean-Marc Valine83d2aa2013-11-15 01:52:28 -05001413 return OPUS_BAD_ARG;
1414 }
Jean-Marc Valin69062102012-11-08 09:42:27 -05001415
1416 frame_size *= st->upsample;
1417 for (LM=0;LM<=mode->maxLM;LM++)
1418 if (mode->shortMdctSize<<LM==frame_size)
1419 break;
1420 if (LM>mode->maxLM)
Jean-Marc Valine83d2aa2013-11-15 01:52:28 -05001421 {
Jean-Marc Valin1b28e0c2013-11-15 01:57:25 -05001422 RESTORE_STACK;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001423 return OPUS_BAD_ARG;
Jean-Marc Valine83d2aa2013-11-15 01:52:28 -05001424 }
Jean-Marc Valin69062102012-11-08 09:42:27 -05001425 M=1<<LM;
1426 N = M*mode->shortMdctSize;
1427
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001428 prefilter_mem = st->in_mem+CC*(overlap);
1429 oldBandE = (opus_val16*)(st->in_mem+CC*(overlap+COMBFILTER_MAXPERIOD));
Jean-Marc Valin69062102012-11-08 09:42:27 -05001430 oldLogE = oldBandE + CC*nbEBands;
1431 oldLogE2 = oldLogE + CC*nbEBands;
Jean-Marc Valin6fccb4b2016-07-04 01:06:11 -04001432 energyError = oldLogE2 + CC*nbEBands;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001433
1434 if (enc==NULL)
1435 {
Jean-Marc Valinbcd6aba2015-12-06 10:50:15 -05001436 tell0_frac=tell=1;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001437 nbFilledBytes=0;
1438 } else {
Jean-Marc Valinbcd6aba2015-12-06 10:50:15 -05001439 tell0_frac=tell=ec_tell_frac(enc);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001440 tell=ec_tell(enc);
1441 nbFilledBytes=(tell+4)>>3;
1442 }
1443
1444#ifdef CUSTOM_MODES
1445 if (st->signalling && enc==NULL)
1446 {
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001447 int tmp = (mode->effEBands-end)>>1;
1448 end = st->end = IMAX(1, mode->effEBands-tmp);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001449 compressed[0] = tmp<<5;
1450 compressed[0] |= LM<<3;
1451 compressed[0] |= (C==2)<<2;
1452 /* Convert "standard mode" to Opus header */
1453 if (mode->Fs==48000 && mode->shortMdctSize==120)
1454 {
1455 int c0 = toOpus(compressed[0]);
1456 if (c0<0)
Jean-Marc Valine83d2aa2013-11-15 01:52:28 -05001457 {
Jean-Marc Valin1b28e0c2013-11-15 01:57:25 -05001458 RESTORE_STACK;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001459 return OPUS_BAD_ARG;
Jean-Marc Valine83d2aa2013-11-15 01:52:28 -05001460 }
Jean-Marc Valin69062102012-11-08 09:42:27 -05001461 compressed[0] = c0;
1462 }
1463 compressed++;
1464 nbCompressedBytes--;
1465 }
1466#else
1467 celt_assert(st->signalling==0);
1468#endif
1469
1470 /* Can't produce more than 1275 output bytes */
1471 nbCompressedBytes = IMIN(nbCompressedBytes,1275);
1472 nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
1473
1474 if (st->vbr && st->bitrate!=OPUS_BITRATE_MAX)
1475 {
1476 opus_int32 den=mode->Fs>>BITRES;
1477 vbr_rate=(st->bitrate*frame_size+(den>>1))/den;
1478#ifdef CUSTOM_MODES
1479 if (st->signalling)
1480 vbr_rate -= 8<<BITRES;
1481#endif
1482 effectiveBytes = vbr_rate>>(3+BITRES);
1483 } else {
1484 opus_int32 tmp;
1485 vbr_rate = 0;
1486 tmp = st->bitrate*frame_size;
1487 if (tell>1)
1488 tmp += tell;
1489 if (st->bitrate!=OPUS_BITRATE_MAX)
1490 nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes,
1491 (tmp+4*mode->Fs)/(8*mode->Fs)-!!st->signalling));
Jean-Marc Valinbcd6aba2015-12-06 10:50:15 -05001492 effectiveBytes = nbCompressedBytes - nbFilledBytes;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001493 }
Jean-Marc Valin14845912016-06-08 02:33:56 -04001494 equiv_rate = ((opus_int32)nbCompressedBytes*8*50 >> (3-LM)) - (40*C+20)*((400>>LM) - 50);
Jean-Marc Valinc1959e72013-11-08 19:24:10 -05001495 if (st->bitrate != OPUS_BITRATE_MAX)
Jean-Marc Valin14845912016-06-08 02:33:56 -04001496 equiv_rate = IMIN(equiv_rate, st->bitrate - (40*C+20)*((400>>LM) - 50));
Jean-Marc Valin69062102012-11-08 09:42:27 -05001497
1498 if (enc==NULL)
1499 {
1500 ec_enc_init(&_enc, compressed, nbCompressedBytes);
1501 enc = &_enc;
1502 }
1503
1504 if (vbr_rate>0)
1505 {
1506 /* Computes the max bit-rate allowed in VBR mode to avoid violating the
1507 target rate and buffering.
1508 We must do this up front so that bust-prevention logic triggers
1509 correctly if we don't have enough bits. */
1510 if (st->constrained_vbr)
1511 {
1512 opus_int32 vbr_bound;
1513 opus_int32 max_allowed;
1514 /* We could use any multiple of vbr_rate as bound (depending on the
1515 delay).
1516 This is clamped to ensure we use at least two bytes if the encoder
1517 was entirely empty, but to allow 0 in hybrid mode. */
1518 vbr_bound = vbr_rate;
1519 max_allowed = IMIN(IMAX(tell==1?2:0,
1520 (vbr_rate+vbr_bound-st->vbr_reservoir)>>(BITRES+3)),
1521 nbAvailableBytes);
1522 if(max_allowed < nbAvailableBytes)
1523 {
1524 nbCompressedBytes = nbFilledBytes+max_allowed;
1525 nbAvailableBytes = max_allowed;
1526 ec_enc_shrink(enc, nbCompressedBytes);
1527 }
1528 }
1529 }
1530 total_bits = nbCompressedBytes*8;
1531
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001532 effEnd = end;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001533 if (effEnd > mode->effEBands)
1534 effEnd = mode->effEBands;
1535
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001536 ALLOC(in, CC*(N+overlap), celt_sig);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001537
Jean-Marc Valinb7bd4c22013-05-18 23:33:48 -04001538 sample_max=MAX32(st->overlap_max, celt_maxabs16(pcm, C*(N-overlap)/st->upsample));
Jean-Marc Valin69062102012-11-08 09:42:27 -05001539 st->overlap_max=celt_maxabs16(pcm+C*(N-overlap)/st->upsample, C*overlap/st->upsample);
Jean-Marc Valinb7bd4c22013-05-18 23:33:48 -04001540 sample_max=MAX32(sample_max, st->overlap_max);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001541#ifdef FIXED_POINT
1542 silence = (sample_max==0);
1543#else
1544 silence = (sample_max <= (opus_val16)1/(1<<st->lsb_depth));
1545#endif
1546#ifdef FUZZING
1547 if ((rand()&0x3F)==0)
1548 silence = 1;
1549#endif
1550 if (tell==1)
1551 ec_enc_bit_logp(enc, silence, 15);
1552 else
1553 silence=0;
1554 if (silence)
1555 {
1556 /*In VBR mode there is no need to send more than the minimum. */
1557 if (vbr_rate>0)
1558 {
1559 effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2);
1560 total_bits=nbCompressedBytes*8;
1561 nbAvailableBytes=2;
1562 ec_enc_shrink(enc, nbCompressedBytes);
1563 }
1564 /* Pretend we've filled all the remaining bits with zeros
1565 (that's what the initialiser did anyway) */
1566 tell = nbCompressedBytes*8;
1567 enc->nbits_total+=tell-ec_tell(enc);
1568 }
1569 c=0; do {
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -05001570 int need_clip=0;
1571#ifndef FIXED_POINT
1572 need_clip = st->clip && sample_max>65536.f;
1573#endif
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001574 celt_preemphasis(pcm+c, in+c*(N+overlap)+overlap, N, CC, st->upsample,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -05001575 mode->preemph, st->preemph_memE+c, need_clip);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001576 } while (++c<CC);
1577
1578
1579
1580 /* Find pitch period and gain */
1581 {
1582 int enabled;
1583 int qg;
Jean-Marc Valin7e0ca432015-12-25 13:12:58 -05001584 enabled = ((st->lfe&&nbAvailableBytes>3) || nbAvailableBytes>12*C) && !hybrid && !silence && !st->disable_pf
Jean-Marc Valin39cbc452013-06-13 15:28:53 -04001585 && st->complexity >= 5 && !(st->consec_transient && LM!=3 && st->variable_duration==OPUS_FRAMESIZE_VARIABLE);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001586
1587 prefilter_tapset = st->tapset_decision;
1588 pf_on = run_prefilter(st, in, prefilter_mem, CC, N, prefilter_tapset, &pitch_index, &gain1, &qg, enabled, nbAvailableBytes);
Gregory Maxwell5280c712013-07-15 15:51:24 -07001589 if ((gain1 > QCONST16(.4f,15) || st->prefilter_gain > QCONST16(.4f,15)) && (!st->analysis.valid || st->analysis.tonality > .3)
1590 && (pitch_index > 1.26*st->prefilter_period || pitch_index < .79*st->prefilter_period))
Jean-Marc Valin69062102012-11-08 09:42:27 -05001591 pitch_change = 1;
1592 if (pf_on==0)
1593 {
Jean-Marc Valin7e0ca432015-12-25 13:12:58 -05001594 if(!hybrid && tell+16<=total_bits)
Jean-Marc Valin69062102012-11-08 09:42:27 -05001595 ec_enc_bit_logp(enc, 0, 1);
1596 } else {
1597 /*This block is not gated by a total bits check only because
1598 of the nbAvailableBytes check above.*/
1599 int octave;
1600 ec_enc_bit_logp(enc, 1, 1);
1601 pitch_index += 1;
1602 octave = EC_ILOG(pitch_index)-5;
1603 ec_enc_uint(enc, octave, 6);
1604 ec_enc_bits(enc, pitch_index-(16<<octave), 4+octave);
1605 pitch_index -= 1;
1606 ec_enc_bits(enc, qg, 3);
1607 ec_enc_icdf(enc, prefilter_tapset, tapset_icdf, 2);
1608 }
1609 }
1610
1611 isTransient = 0;
1612 shortBlocks = 0;
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -04001613 if (st->complexity >= 1 && !st->lfe)
Jean-Marc Valin2a5f0562012-11-19 23:17:06 -05001614 {
Jean-Marc Valin7e122392016-10-29 17:02:36 -04001615 /* Reduces the likelihood of energy instability on fricatives at low bitrate
1616 in hybrid mode. It seems like we still want to have real transients on vowels
1617 though (small SILK quantization offset value). */
1618 int allow_weak_transients = hybrid && effectiveBytes<15 && st->silk_info.offset >= 100;
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001619 isTransient = transient_analysis(in, N+overlap, CC,
Jean-Marc Valin7e122392016-10-29 17:02:36 -04001620 &tf_estimate, &tf_chan, allow_weak_transients, &weak_transient);
Jean-Marc Valin2a5f0562012-11-19 23:17:06 -05001621 }
Jean-Marc Valin69062102012-11-08 09:42:27 -05001622 if (LM>0 && ec_tell(enc)+3<=total_bits)
1623 {
Jean-Marc Valin2a5f0562012-11-19 23:17:06 -05001624 if (isTransient)
1625 shortBlocks = M;
Jean-Marc Valin2a5f0562012-11-19 23:17:06 -05001626 } else {
1627 isTransient = 0;
Jean-Marc Valin3252bf22013-04-19 03:14:28 -04001628 transient_got_disabled=1;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001629 }
1630
1631 ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */
1632 ALLOC(bandE,nbEBands*CC, celt_ener);
1633 ALLOC(bandLogE,nbEBands*CC, opus_val16);
1634
1635 secondMdct = shortBlocks && st->complexity>=8;
1636 ALLOC(bandLogE2, C*nbEBands, opus_val16);
1637 if (secondMdct)
1638 {
Viswanath Puttaguntaf48abe82015-05-15 12:42:19 -05001639 compute_mdcts(mode, 0, in, freq, C, CC, LM, st->upsample, st->arch);
Jean-Marc Valin306d7f52013-12-16 01:08:21 -05001640 compute_band_energies(mode, freq, bandE, effEnd, C, LM);
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001641 amp2Log2(mode, effEnd, end, bandE, bandLogE2, C);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001642 for (i=0;i<C*nbEBands;i++)
1643 bandLogE2[i] += HALF16(SHL16(LM, DB_SHIFT));
1644 }
1645
Viswanath Puttaguntaf48abe82015-05-15 12:42:19 -05001646 compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample, st->arch);
Jean-Marc Valin69c3dcd2013-02-19 03:42:18 -05001647 if (CC==2&&C==1)
1648 tf_chan = 0;
Jean-Marc Valin306d7f52013-12-16 01:08:21 -05001649 compute_band_energies(mode, freq, bandE, effEnd, C, LM);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001650
Jean-Marc Valin172f66a2013-04-27 02:29:52 -04001651 if (st->lfe)
1652 {
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001653 for (i=2;i<end;i++)
Jean-Marc Valin43654982013-07-07 00:39:35 -04001654 {
Jean-Marc Valin172f66a2013-04-27 02:29:52 -04001655 bandE[i] = IMIN(bandE[i], MULT16_32_Q15(QCONST16(1e-4f,15),bandE[0]));
Jean-Marc Valin43654982013-07-07 00:39:35 -04001656 bandE[i] = MAX32(bandE[i], EPSILON);
1657 }
Jean-Marc Valin172f66a2013-04-27 02:29:52 -04001658 }
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001659 amp2Log2(mode, effEnd, end, bandE, bandLogE, C);
Jean-Marc Valin0f686962013-09-05 12:49:55 -04001660
1661 ALLOC(surround_dynalloc, C*nbEBands, opus_val16);
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001662 OPUS_CLEAR(surround_dynalloc, end);
Jean-Marc Valind2c484b2013-05-06 16:02:31 -04001663 /* This computes how much masking takes place between surround channels */
Jean-Marc Valin7e0ca432015-12-25 13:12:58 -05001664 if (!hybrid&&st->energy_mask&&!st->lfe)
Jean-Marc Valina4dccd32013-05-04 23:54:20 -04001665 {
Jean-Marc Valin039e9ab2013-09-12 03:05:43 -04001666 int mask_end;
Jean-Marc Valinae7dc8a2013-09-13 15:05:50 -04001667 int midband;
1668 int count_dynalloc;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -04001669 opus_val32 mask_avg=0;
Jean-Marc Valin0f686962013-09-05 12:49:55 -04001670 opus_val32 diff=0;
Jean-Marc Valin039e9ab2013-09-12 03:05:43 -04001671 int count=0;
Jean-Marc Valin942fc812013-10-01 19:27:30 -04001672 mask_end = IMAX(2,st->lastCodedBands);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -04001673 for (c=0;c<C;c++)
Jean-Marc Valind2c484b2013-05-06 16:02:31 -04001674 {
Jean-Marc Valin039e9ab2013-09-12 03:05:43 -04001675 for(i=0;i<mask_end;i++)
Jean-Marc Valind2c484b2013-05-06 16:02:31 -04001676 {
Jean-Marc Valinae7dc8a2013-09-13 15:05:50 -04001677 opus_val16 mask;
1678 mask = MAX16(MIN16(st->energy_mask[nbEBands*c+i],
1679 QCONST16(.25f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT));
1680 if (mask > 0)
1681 mask = HALF16(mask);
1682 mask_avg += MULT16_16(mask, eBands[i+1]-eBands[i]);
1683 count += eBands[i+1]-eBands[i];
1684 diff += MULT16_16(mask, 1+2*i-mask_end);
Jean-Marc Valind2c484b2013-05-06 16:02:31 -04001685 }
1686 }
Gregory Maxwell6d2d5c42014-04-16 18:29:26 -07001687 celt_assert(count>0);
Jean-Marc Valin039e9ab2013-09-12 03:05:43 -04001688 mask_avg = DIV32_16(mask_avg,count);
Jean-Marc Valin36a21ed2013-09-14 15:46:09 -04001689 mask_avg += QCONST16(.2f, DB_SHIFT);
Jean-Marc Valin039e9ab2013-09-12 03:05:43 -04001690 diff = diff*6/(C*(mask_end-1)*(mask_end+1)*mask_end);
1691 /* Again, being conservative */
1692 diff = HALF32(diff);
1693 diff = MAX32(MIN32(diff, QCONST32(.031f, DB_SHIFT)), -QCONST32(.031f, DB_SHIFT));
Jean-Marc Valinae7dc8a2013-09-13 15:05:50 -04001694 /* Find the band that's in the middle of the coded spectrum */
1695 for (midband=0;eBands[midband+1] < eBands[mask_end]/2;midband++);
1696 count_dynalloc=0;
Jean-Marc Valin039e9ab2013-09-12 03:05:43 -04001697 for(i=0;i<mask_end;i++)
Jean-Marc Valin0f686962013-09-05 12:49:55 -04001698 {
1699 opus_val32 lin;
1700 opus_val16 unmask;
Jean-Marc Valinae7dc8a2013-09-13 15:05:50 -04001701 lin = mask_avg + diff*(i-midband);
Jean-Marc Valin0f686962013-09-05 12:49:55 -04001702 if (C==2)
Jean-Marc Valinae7dc8a2013-09-13 15:05:50 -04001703 unmask = MAX16(st->energy_mask[i], st->energy_mask[nbEBands+i]);
Jean-Marc Valin0f686962013-09-05 12:49:55 -04001704 else
Jean-Marc Valinae7dc8a2013-09-13 15:05:50 -04001705 unmask = st->energy_mask[i];
1706 unmask = MIN16(unmask, QCONST16(.0f, DB_SHIFT));
1707 unmask -= lin;
Jean-Marc Valin0f686962013-09-05 12:49:55 -04001708 if (unmask > QCONST16(.25f, DB_SHIFT))
1709 {
1710 surround_dynalloc[i] = unmask - QCONST16(.25f, DB_SHIFT);
Jean-Marc Valinae7dc8a2013-09-13 15:05:50 -04001711 count_dynalloc++;
1712 }
1713 }
1714 if (count_dynalloc>=3)
1715 {
1716 /* If we need dynalloc in many bands, it's probably because our
1717 initial masking rate was too low. */
1718 mask_avg += QCONST16(.25f, DB_SHIFT);
1719 if (mask_avg>0)
1720 {
1721 /* Something went really wrong in the original calculations,
1722 disabling masking. */
1723 mask_avg = 0;
1724 diff = 0;
Jean-Marc Valinff072002013-12-08 23:31:30 -05001725 OPUS_CLEAR(surround_dynalloc, mask_end);
Jean-Marc Valinae7dc8a2013-09-13 15:05:50 -04001726 } else {
1727 for(i=0;i<mask_end;i++)
1728 surround_dynalloc[i] = MAX16(0, surround_dynalloc[i]-QCONST16(.25f, DB_SHIFT));
Jean-Marc Valin0f686962013-09-05 12:49:55 -04001729 }
1730 }
Jean-Marc Valin36a21ed2013-09-14 15:46:09 -04001731 mask_avg += QCONST16(.2f, DB_SHIFT);
Jean-Marc Valin0f686962013-09-05 12:49:55 -04001732 /* Convert to 1/64th units used for the trim */
1733 surround_trim = 64*diff;
1734 /*printf("%d %d ", mask_avg, surround_trim);*/
1735 surround_masking = mask_avg;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -04001736 }
Jean-Marc Valin92a06f52013-07-01 16:27:07 -04001737 /* Temporal VBR (but not for LFE) */
1738 if (!st->lfe)
Jean-Marc Valin3c0aa8f2013-06-25 14:10:27 -04001739 {
1740 opus_val16 follow=-QCONST16(10.0f,DB_SHIFT);
Jean-Marc Valin8f466272013-10-28 21:50:10 -04001741 opus_val32 frame_avg=0;
Jean-Marc Valin3c0aa8f2013-06-25 14:10:27 -04001742 opus_val16 offset = shortBlocks?HALF16(SHL16(LM, DB_SHIFT)):0;
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001743 for(i=start;i<end;i++)
Jean-Marc Valin3c0aa8f2013-06-25 14:10:27 -04001744 {
1745 follow = MAX16(follow-QCONST16(1.f, DB_SHIFT), bandLogE[i]-offset);
1746 if (C==2)
1747 follow = MAX16(follow, bandLogE[i+nbEBands]-offset);
1748 frame_avg += follow;
1749 }
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001750 frame_avg /= (end-start);
Jean-Marc Valin3c0aa8f2013-06-25 14:10:27 -04001751 temporal_vbr = SUB16(frame_avg,st->spec_avg);
1752 temporal_vbr = MIN16(QCONST16(3.f, DB_SHIFT), MAX16(-QCONST16(1.5f, DB_SHIFT), temporal_vbr));
1753 st->spec_avg += MULT16_16_Q15(QCONST16(.02f, 15), temporal_vbr);
1754 }
Jean-Marc Valin69062102012-11-08 09:42:27 -05001755 /*for (i=0;i<21;i++)
1756 printf("%f ", bandLogE[i]);
1757 printf("\n");*/
1758
1759 if (!secondMdct)
1760 {
Jean-Marc Valinff072002013-12-08 23:31:30 -05001761 OPUS_COPY(bandLogE2, bandLogE, C*nbEBands);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001762 }
1763
Jean-Marc Valin541a4722013-02-17 21:21:30 -05001764 /* Last chance to catch any transient we might have missed in the
1765 time-domain analysis */
Jean-Marc Valin92d24922016-06-06 16:52:50 -04001766 if (LM>0 && ec_tell(enc)+3<=total_bits && !isTransient && st->complexity>=5 && !st->lfe && !hybrid)
Jean-Marc Valin541a4722013-02-17 21:21:30 -05001767 {
Jean-Marc Valin99618092015-12-04 16:42:19 -05001768 if (patch_transient_decision(bandLogE, oldBandE, nbEBands, start, end, C))
Jean-Marc Valin541a4722013-02-17 21:21:30 -05001769 {
1770 isTransient = 1;
1771 shortBlocks = M;
Viswanath Puttaguntaf48abe82015-05-15 12:42:19 -05001772 compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample, st->arch);
Jean-Marc Valin306d7f52013-12-16 01:08:21 -05001773 compute_band_energies(mode, freq, bandE, effEnd, C, LM);
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001774 amp2Log2(mode, effEnd, end, bandE, bandLogE, C);
Jean-Marc Valin541a4722013-02-17 21:21:30 -05001775 /* Compensate for the scaling of short vs long mdcts */
1776 for (i=0;i<C*nbEBands;i++)
1777 bandLogE2[i] += HALF16(SHL16(LM, DB_SHIFT));
Jean-Marc Valin16ba19a2013-06-27 03:40:44 -04001778 tf_estimate = QCONST16(.2f,14);
Jean-Marc Valin541a4722013-02-17 21:21:30 -05001779 }
1780 }
1781
1782 if (LM>0 && ec_tell(enc)+3<=total_bits)
1783 ec_enc_bit_logp(enc, isTransient, 3);
1784
Jean-Marc Valin69062102012-11-08 09:42:27 -05001785 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
1786
1787 /* Band normalisation */
1788 normalise_bands(mode, freq, X, bandE, effEnd, C, M);
1789
1790 ALLOC(tf_res, nbEBands, int);
Jean-Marc Valina6d663c2012-11-08 13:26:49 -05001791 /* Disable variable tf resolution for hybrid and at very low bitrate */
Jean-Marc Valin7e0ca432015-12-25 13:12:58 -05001792 if (effectiveBytes>=15*C && !hybrid && st->complexity>=2 && !st->lfe)
Jean-Marc Valina6d663c2012-11-08 13:26:49 -05001793 {
1794 int lambda;
Jean-Marc Valin7780d4a2016-06-08 15:19:03 -04001795 lambda = IMAX(5, 1280/effectiveBytes + 2);
Jean-Marc Valin2ca6df02016-06-08 02:15:21 -04001796 tf_select = tf_analysis(mode, effEnd, isTransient, tf_res, lambda, X, N, LM, tf_estimate, tf_chan);
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001797 for (i=effEnd;i<end;i++)
Jean-Marc Valina6d663c2012-11-08 13:26:49 -05001798 tf_res[i] = tf_res[effEnd-1];
Jean-Marc Valin90f20c62016-10-28 16:44:38 -04001799 } else if (hybrid && weak_transient)
1800 {
1801 /* For weak transients, we rely on the fact that improving time resolution using
1802 TF on a long window is imperfect and will not result in an energy collapse at
1803 low bitrate. */
1804 for (i=0;i<end;i++)
1805 tf_res[i] = 1;
1806 tf_select=0;
Jean-Marc Valin8229f072016-06-06 16:54:29 -04001807 } else if (hybrid && effectiveBytes<15)
1808 {
1809 /* For low bitrate hybrid, we force temporal resolution to 5 ms rather than 2.5 ms. */
Jean-Marc Valin8229f072016-06-06 16:54:29 -04001810 for (i=0;i<end;i++)
1811 tf_res[i] = 0;
1812 tf_select=isTransient;
Jean-Marc Valina6d663c2012-11-08 13:26:49 -05001813 } else {
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001814 for (i=0;i<end;i++)
Jean-Marc Valina6d663c2012-11-08 13:26:49 -05001815 tf_res[i] = isTransient;
1816 tf_select=0;
1817 }
Jean-Marc Valin69062102012-11-08 09:42:27 -05001818
1819 ALLOC(error, C*nbEBands, opus_val16);
Jean-Marc Valin6fccb4b2016-07-04 01:06:11 -04001820 c=0;
1821 do {
1822 for (i=start;i<end;i++)
1823 {
1824 /* When the energy is stable, slightly bias energy quantization towards
1825 the previous error to make the gain more stable (a constant offset is
1826 better than fluctuations). */
1827 if (ABS32(SUB32(bandLogE[i+c*nbEBands], oldBandE[i+c*nbEBands])) < QCONST16(2.f, DB_SHIFT))
1828 {
1829 bandLogE[i+c*nbEBands] -= MULT16_16_Q15(energyError[i+c*nbEBands], QCONST16(0.25f, 15));
1830 }
1831 }
1832 } while (++c < C);
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001833 quant_coarse_energy(mode, start, end, effEnd, bandLogE,
Jean-Marc Valin69062102012-11-08 09:42:27 -05001834 oldBandE, total_bits, error, enc,
1835 C, LM, nbAvailableBytes, st->force_intra,
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -04001836 &st->delayedIntra, st->complexity >= 4, st->loss_rate, st->lfe);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001837
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001838 tf_encode(start, end, isTransient, tf_res, LM, tf_select, enc);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001839
1840 if (ec_tell(enc)+4<=total_bits)
1841 {
Jean-Marc Valin172f66a2013-04-27 02:29:52 -04001842 if (st->lfe)
1843 {
1844 st->tapset_decision = 0;
1845 st->spread_decision = SPREAD_NORMAL;
Jean-Marc Valinf705e9b2016-06-06 13:43:13 -04001846 } else if (hybrid)
1847 {
1848 if (st->complexity == 0)
1849 st->spread_decision = SPREAD_NONE;
1850 else if (isTransient)
1851 st->spread_decision = SPREAD_NORMAL;
1852 else
1853 st->spread_decision = SPREAD_AGGRESSIVE;
1854 } else if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C)
Jean-Marc Valin69062102012-11-08 09:42:27 -05001855 {
1856 if (st->complexity == 0)
1857 st->spread_decision = SPREAD_NONE;
Jean-Marc Valin1fd1d7d2012-11-08 17:22:07 -05001858 else
1859 st->spread_decision = SPREAD_NORMAL;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001860 } else {
Jean-Marc Valin41fd7a12012-12-12 14:41:29 -05001861 /* Disable new spreading+tapset estimator until we can show it works
1862 better than the old one. So far it seems like spreading_decision()
1863 works best. */
Jean-Marc Valinab86a9c2013-11-13 23:06:25 -05001864#if 0
1865 if (st->analysis.valid)
Jean-Marc Valin69062102012-11-08 09:42:27 -05001866 {
1867 static const opus_val16 spread_thresholds[3] = {-QCONST16(.6f, 15), -QCONST16(.2f, 15), -QCONST16(.07f, 15)};
1868 static const opus_val16 spread_histeresis[3] = {QCONST16(.15f, 15), QCONST16(.07f, 15), QCONST16(.02f, 15)};
1869 static const opus_val16 tapset_thresholds[2] = {QCONST16(.0f, 15), QCONST16(.15f, 15)};
1870 static const opus_val16 tapset_histeresis[2] = {QCONST16(.1f, 15), QCONST16(.05f, 15)};
1871 st->spread_decision = hysteresis_decision(-st->analysis.tonality, spread_thresholds, spread_histeresis, 3, st->spread_decision);
1872 st->tapset_decision = hysteresis_decision(st->analysis.tonality_slope, tapset_thresholds, tapset_histeresis, 2, st->tapset_decision);
Jean-Marc Valinab86a9c2013-11-13 23:06:25 -05001873 } else
1874#endif
1875 {
Jean-Marc Valin69062102012-11-08 09:42:27 -05001876 st->spread_decision = spreading_decision(mode, X,
1877 &st->tonal_average, st->spread_decision, &st->hf_average,
1878 &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M);
1879 }
1880 /*printf("%d %d\n", st->tapset_decision, st->spread_decision);*/
1881 /*printf("%f %d %f %d\n\n", st->analysis.tonality, st->spread_decision, st->analysis.tonality_slope, st->tapset_decision);*/
1882 }
1883 ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5);
1884 }
1885
Jean-Marc Valin69062102012-11-08 09:42:27 -05001886 ALLOC(offsets, nbEBands, int);
1887
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001888 maxDepth = dynalloc_analysis(bandLogE, bandLogE2, nbEBands, start, end, C, offsets,
Jean-Marc Valin10b30e72012-11-10 00:44:03 -05001889 st->lsb_depth, mode->logN, isTransient, st->vbr, st->constrained_vbr,
Jean-Marc Valin0f686962013-09-05 12:49:55 -04001890 eBands, LM, effectiveBytes, &tot_boost, st->lfe, surround_dynalloc);
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -04001891 /* For LFE, everything interesting is in the first band */
1892 if (st->lfe)
1893 offsets[0] = IMIN(8, effectiveBytes/3);
Jean-Marc Valin10b30e72012-11-10 00:44:03 -05001894 ALLOC(cap, nbEBands, int);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001895 init_caps(mode,cap,LM,C);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001896
Jean-Marc Valin69062102012-11-08 09:42:27 -05001897 dynalloc_logp = 6;
1898 total_bits<<=BITRES;
1899 total_boost = 0;
1900 tell = ec_tell_frac(enc);
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001901 for (i=start;i<end;i++)
Jean-Marc Valin69062102012-11-08 09:42:27 -05001902 {
1903 int width, quanta;
1904 int dynalloc_loop_logp;
1905 int boost;
1906 int j;
1907 width = C*(eBands[i+1]-eBands[i])<<LM;
1908 /* quanta is 6 bits, but no more than 1 bit/sample
1909 and no less than 1/8 bit/sample */
1910 quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));
1911 dynalloc_loop_logp = dynalloc_logp;
1912 boost = 0;
1913 for (j = 0; tell+(dynalloc_loop_logp<<BITRES) < total_bits-total_boost
1914 && boost < cap[i]; j++)
1915 {
1916 int flag;
1917 flag = j<offsets[i];
1918 ec_enc_bit_logp(enc, flag, dynalloc_loop_logp);
1919 tell = ec_tell_frac(enc);
1920 if (!flag)
1921 break;
1922 boost += quanta;
1923 total_boost += quanta;
1924 dynalloc_loop_logp = 1;
1925 }
1926 /* Making dynalloc more likely */
1927 if (j)
1928 dynalloc_logp = IMAX(2, dynalloc_logp-1);
1929 offsets[i] = boost;
1930 }
1931
1932 if (C==2)
1933 {
Jean-Marc Valin2924af42013-11-25 21:24:30 -05001934 static const opus_val16 intensity_thresholds[21]=
Jean-Marc Valin69062102012-11-08 09:42:27 -05001935 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 off*/
Jean-Marc Valin2924af42013-11-25 21:24:30 -05001936 { 1, 2, 3, 4, 5, 6, 7, 8,16,24,36,44,50,56,62,67,72,79,88,106,134};
Jean-Marc Valin69062102012-11-08 09:42:27 -05001937 static const opus_val16 intensity_histeresis[21]=
Jean-Marc Valina47d6f32013-11-24 23:59:09 -05001938 { 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 5, 6, 8, 8};
Jean-Marc Valin69062102012-11-08 09:42:27 -05001939
1940 /* Always use MS for 2.5 ms frames until we can do a better analysis */
1941 if (LM!=0)
1942 dual_stereo = stereo_analysis(mode, X, LM, N);
1943
Jean-Marc Valin086ea7c2013-11-29 16:47:52 -05001944 st->intensity = hysteresis_decision((opus_val16)(equiv_rate/1000),
Jean-Marc Valin2924af42013-11-25 21:24:30 -05001945 intensity_thresholds, intensity_histeresis, 21, st->intensity);
Jean-Marc Valin91f80102013-12-10 18:38:44 -05001946 st->intensity = IMIN(end,IMAX(start, st->intensity));
Jean-Marc Valin69062102012-11-08 09:42:27 -05001947 }
1948
1949 alloc_trim = 5;
1950 if (tell+(6<<BITRES) <= total_bits - total_boost)
1951 {
Jean-Marc Valin0247d342015-12-05 14:31:54 -05001952 if (start > 0 || st->lfe)
1953 {
1954 st->stereo_saving = 0;
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -04001955 alloc_trim = 5;
Jean-Marc Valin0247d342015-12-05 14:31:54 -05001956 } else {
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -04001957 alloc_trim = alloc_trim_analysis(mode, X, bandLogE,
xiangmingzhuc95c9a02014-04-30 15:48:07 +08001958 end, LM, C, N, &st->analysis, &st->stereo_saving, tf_estimate,
1959 st->intensity, surround_trim, st->arch);
Jean-Marc Valin0247d342015-12-05 14:31:54 -05001960 }
Jean-Marc Valin69062102012-11-08 09:42:27 -05001961 ec_enc_icdf(enc, alloc_trim, trim_icdf, 7);
1962 tell = ec_tell_frac(enc);
1963 }
1964
1965 /* Variable bitrate */
1966 if (vbr_rate>0)
1967 {
1968 opus_val16 alpha;
1969 opus_int32 delta;
1970 /* The target rate in 8th bits per frame */
1971 opus_int32 target, base_target;
1972 opus_int32 min_allowed;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001973 int lm_diff = mode->maxLM - LM;
Jean-Marc Valin69062102012-11-08 09:42:27 -05001974
1975 /* Don't attempt to use more than 510 kb/s, even for frames smaller than 20 ms.
1976 The CELT allocator will just not be able to use more than that anyway. */
1977 nbCompressedBytes = IMIN(nbCompressedBytes,1275>>(3-LM));
Jean-Marc Valinbcd6aba2015-12-06 10:50:15 -05001978 if (!hybrid)
1979 {
1980 base_target = vbr_rate - ((40*C+20)<<BITRES);
1981 } else {
1982 base_target = IMAX(0, vbr_rate - ((9*C+4)<<BITRES));
1983 }
Jean-Marc Valin69062102012-11-08 09:42:27 -05001984
1985 if (st->constrained_vbr)
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001986 base_target += (st->vbr_offset>>lm_diff);
Jean-Marc Valin69062102012-11-08 09:42:27 -05001987
Jean-Marc Valinbcd6aba2015-12-06 10:50:15 -05001988 if (!hybrid)
1989 {
1990 target = compute_vbr(mode, &st->analysis, base_target, LM, equiv_rate,
Jean-Marc Valin28733d12013-06-10 03:30:01 -04001991 st->lastCodedBands, C, st->intensity, st->constrained_vbr,
1992 st->stereo_saving, tot_boost, tf_estimate, pitch_change, maxDepth,
Jean-Marc Valin3c0aa8f2013-06-25 14:10:27 -04001993 st->variable_duration, st->lfe, st->energy_mask!=NULL, surround_masking,
1994 temporal_vbr);
Jean-Marc Valinbcd6aba2015-12-06 10:50:15 -05001995 } else {
1996 target = base_target;
Jean-Marc Valin61714e92016-04-23 00:34:53 -04001997 /* Tonal frames (offset<100) need more bits than noisy (offset>100) ones. */
1998 if (st->silk_info.offset < 100) target += 12 << BITRES >> (3-LM);
1999 if (st->silk_info.offset > 100) target -= 18 << BITRES >> (3-LM);
Jean-Marc Valin78fc6642016-05-31 17:54:20 -04002000 /* Boosting bitrate on transients and vowels with significant temporal
2001 spikes. */
2002 target += MULT16_16_Q14(tf_estimate-QCONST16(.25f,14), (50<<BITRES));
Jean-Marc Valinbcd6aba2015-12-06 10:50:15 -05002003 /* If we have a strong transient, let's make sure it has enough bits to code
2004 the first two bands, so that it can use folding rather than noise. */
2005 if (tf_estimate > QCONST16(.7f,14))
Jean-Marc Valin78fc6642016-05-31 17:54:20 -04002006 target = IMAX(target, 50<<BITRES);
Jean-Marc Valinbcd6aba2015-12-06 10:50:15 -05002007 }
Jean-Marc Valin69062102012-11-08 09:42:27 -05002008 /* The current offset is removed from the target and the space used
2009 so far is added*/
2010 target=target+tell;
2011 /* In VBR mode the frame size must not be reduced so much that it would
2012 result in the encoder running out of bits.
2013 The margin of 2 bytes ensures that none of the bust-prevention logic
2014 in the decoder will have triggered so far. */
Jean-Marc Valinbcd6aba2015-12-06 10:50:15 -05002015 min_allowed = ((tell+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3)) + 2;
2016 /* Take into account the 37 bits we need to have left in the packet to
2017 signal a redundant frame in hybrid mode. Creating a shorter packet would
2018 create an entropy coder desync. */
2019 if (hybrid)
2020 min_allowed = IMAX(min_allowed, (tell0_frac+(37<<BITRES)+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3));
Jean-Marc Valin69062102012-11-08 09:42:27 -05002021
2022 nbAvailableBytes = (target+(1<<(BITRES+2)))>>(BITRES+3);
2023 nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes);
Jean-Marc Valinbcd6aba2015-12-06 10:50:15 -05002024 nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes);
Jean-Marc Valin69062102012-11-08 09:42:27 -05002025
2026 /* By how much did we "miss" the target on that frame */
2027 delta = target - vbr_rate;
2028
2029 target=nbAvailableBytes<<(BITRES+3);
2030
2031 /*If the frame is silent we don't adjust our drift, otherwise
2032 the encoder will shoot to very high rates after hitting a
2033 span of silence, but we do allow the bitres to refill.
2034 This means that we'll undershoot our target in CVBR/VBR modes
2035 on files with lots of silence. */
2036 if(silence)
2037 {
2038 nbAvailableBytes = 2;
2039 target = 2*8<<BITRES;
2040 delta = 0;
2041 }
2042
2043 if (st->vbr_count < 970)
2044 {
2045 st->vbr_count++;
2046 alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+20),16));
2047 } else
2048 alpha = QCONST16(.001f,15);
2049 /* How many bits have we used in excess of what we're allowed */
2050 if (st->constrained_vbr)
2051 st->vbr_reservoir += target - vbr_rate;
2052 /*printf ("%d\n", st->vbr_reservoir);*/
2053
2054 /* Compute the offset we need to apply in order to reach the target */
2055 if (st->constrained_vbr)
2056 {
2057 st->vbr_drift += (opus_int32)MULT16_32_Q15(alpha,(delta*(1<<lm_diff))-st->vbr_offset-st->vbr_drift);
2058 st->vbr_offset = -st->vbr_drift;
2059 }
2060 /*printf ("%d\n", st->vbr_drift);*/
2061
2062 if (st->constrained_vbr && st->vbr_reservoir < 0)
2063 {
2064 /* We're under the min value -- increase rate */
2065 int adjust = (-st->vbr_reservoir)/(8<<BITRES);
2066 /* Unless we're just coding silence */
2067 nbAvailableBytes += silence?0:adjust;
2068 st->vbr_reservoir = 0;
2069 /*printf ("+%d\n", adjust);*/
2070 }
Jean-Marc Valinbcd6aba2015-12-06 10:50:15 -05002071 nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes);
Jean-Marc Valin69062102012-11-08 09:42:27 -05002072 /*printf("%d\n", nbCompressedBytes*50*8);*/
2073 /* This moves the raw bits to take into account the new compressed size */
2074 ec_enc_shrink(enc, nbCompressedBytes);
2075 }
2076
2077 /* Bit allocation */
2078 ALLOC(fine_quant, nbEBands, int);
2079 ALLOC(pulses, nbEBands, int);
2080 ALLOC(fine_priority, nbEBands, int);
2081
2082 /* bits = packet size - where we are - safety*/
2083 bits = (((opus_int32)nbCompressedBytes*8)<<BITRES) - ec_tell_frac(enc) - 1;
2084 anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0;
2085 bits -= anti_collapse_rsv;
Jean-Marc Valin91f80102013-12-10 18:38:44 -05002086 signalBandwidth = end-1;
Jean-Marc Valin3ab03e02013-09-06 16:00:39 -04002087#ifndef DISABLE_FLOAT_API
Jean-Marc Valin5fb50ad2012-12-21 01:23:26 -05002088 if (st->analysis.valid)
Jean-Marc Valin6e277c62013-05-17 14:15:31 -04002089 {
2090 int min_bandwidth;
Jean-Marc Valinc1959e72013-11-08 19:24:10 -05002091 if (equiv_rate < (opus_int32)32000*C)
Jean-Marc Valin6e277c62013-05-17 14:15:31 -04002092 min_bandwidth = 13;
Jean-Marc Valinc1959e72013-11-08 19:24:10 -05002093 else if (equiv_rate < (opus_int32)48000*C)
Jean-Marc Valin6e277c62013-05-17 14:15:31 -04002094 min_bandwidth = 16;
Jean-Marc Valinc1959e72013-11-08 19:24:10 -05002095 else if (equiv_rate < (opus_int32)60000*C)
Jean-Marc Valin6e277c62013-05-17 14:15:31 -04002096 min_bandwidth = 18;
Jean-Marc Valinc1959e72013-11-08 19:24:10 -05002097 else if (equiv_rate < (opus_int32)80000*C)
Jean-Marc Valin6e277c62013-05-17 14:15:31 -04002098 min_bandwidth = 19;
2099 else
2100 min_bandwidth = 20;
2101 signalBandwidth = IMAX(st->analysis.bandwidth, min_bandwidth);
2102 }
Jean-Marc Valin5fb50ad2012-12-21 01:23:26 -05002103#endif
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -04002104 if (st->lfe)
2105 signalBandwidth = 1;
Jean-Marc Valin91f80102013-12-10 18:38:44 -05002106 codedBands = compute_allocation(mode, start, end, offsets, cap,
Jean-Marc Valin69062102012-11-08 09:42:27 -05002107 alloc_trim, &st->intensity, &dual_stereo, bits, &balance, pulses,
Jean-Marc Valin5fb50ad2012-12-21 01:23:26 -05002108 fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands, signalBandwidth);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -04002109 if (st->lastCodedBands)
2110 st->lastCodedBands = IMIN(st->lastCodedBands+1,IMAX(st->lastCodedBands-1,codedBands));
2111 else
2112 st->lastCodedBands = codedBands;
Jean-Marc Valin69062102012-11-08 09:42:27 -05002113
Jean-Marc Valin91f80102013-12-10 18:38:44 -05002114 quant_fine_energy(mode, start, end, oldBandE, error, fine_quant, enc, C);
Jean-Marc Valin69062102012-11-08 09:42:27 -05002115
Jean-Marc Valin69062102012-11-08 09:42:27 -05002116 /* Residual quantisation */
2117 ALLOC(collapse_masks, C*nbEBands, unsigned char);
Jean-Marc Valin91f80102013-12-10 18:38:44 -05002118 quant_all_bands(1, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks,
xiangmingzhuc95c9a02014-04-30 15:48:07 +08002119 bandE, pulses, shortBlocks, st->spread_decision,
2120 dual_stereo, st->intensity, tf_res, nbCompressedBytes*(8<<BITRES)-anti_collapse_rsv,
Jean-Marc Valin18a380a2016-04-20 13:27:06 -04002121 balance, enc, LM, codedBands, &st->rng, st->complexity, st->arch, st->disable_inv);
Jean-Marc Valin69062102012-11-08 09:42:27 -05002122
2123 if (anti_collapse_rsv > 0)
2124 {
2125 anti_collapse_on = st->consec_transient<2;
2126#ifdef FUZZING
2127 anti_collapse_on = rand()&0x1;
2128#endif
2129 ec_enc_bits(enc, anti_collapse_on, 1);
2130 }
Jean-Marc Valin91f80102013-12-10 18:38:44 -05002131 quant_energy_finalise(mode, start, end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C);
Jean-Marc Valin6fccb4b2016-07-04 01:06:11 -04002132 OPUS_CLEAR(energyError, nbEBands*CC);
2133 c=0;
2134 do {
2135 for (i=start;i<end;i++)
2136 {
2137 energyError[i+c*nbEBands] = MAX16(-QCONST16(0.5f, 15), MIN16(QCONST16(0.5f, 15), error[i+c*nbEBands]));
2138 }
2139 } while (++c < C);
Jean-Marc Valin69062102012-11-08 09:42:27 -05002140
2141 if (silence)
2142 {
2143 for (i=0;i<C*nbEBands;i++)
2144 oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
2145 }
2146
2147#ifdef RESYNTH
2148 /* Re-synthesis of the coded audio if required */
2149 {
2150 celt_sig *out_mem[2];
2151
Jean-Marc Valin69062102012-11-08 09:42:27 -05002152 if (anti_collapse_on)
2153 {
2154 anti_collapse(mode, X, collapse_masks, LM, C, N,
Jean-Marc Valin91f80102013-12-10 18:38:44 -05002155 start, end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
Jean-Marc Valin69062102012-11-08 09:42:27 -05002156 }
2157
Jean-Marc Valin69062102012-11-08 09:42:27 -05002158 c=0; do {
Nils Wallméniuse0884fe2012-12-01 21:11:50 +01002159 OPUS_MOVE(st->syn_mem[c], st->syn_mem[c]+N, 2*MAX_PERIOD-N+overlap/2);
Jean-Marc Valin69062102012-11-08 09:42:27 -05002160 } while (++c<CC);
2161
Jean-Marc Valin69062102012-11-08 09:42:27 -05002162 c=0; do {
2163 out_mem[c] = st->syn_mem[c]+2*MAX_PERIOD-N;
2164 } while (++c<CC);
2165
Viswanath Puttagunta19c54062015-05-15 12:42:20 -05002166 celt_synthesis(mode, X, out_mem, oldBandE, start, effEnd,
2167 C, CC, isTransient, LM, st->upsample, silence, st->arch);
Jean-Marc Valin69062102012-11-08 09:42:27 -05002168
2169 c=0; do {
2170 st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);
2171 st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD);
2172 comb_filter(out_mem[c], out_mem[c], st->prefilter_period_old, st->prefilter_period, mode->shortMdctSize,
2173 st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset,
Jean-Marc Valin91f80102013-12-10 18:38:44 -05002174 mode->window, overlap);
Jean-Marc Valin69062102012-11-08 09:42:27 -05002175 if (LM!=0)
2176 comb_filter(out_mem[c]+mode->shortMdctSize, out_mem[c]+mode->shortMdctSize, st->prefilter_period, pitch_index, N-mode->shortMdctSize,
2177 st->prefilter_gain, gain1, st->prefilter_tapset, prefilter_tapset,
2178 mode->window, overlap);
2179 } while (++c<CC);
2180
2181 /* We reuse freq[] as scratch space for the de-emphasis */
Jean-Marc Valinbdc7b932014-01-06 08:58:38 -05002182 deemphasis(out_mem, (opus_val16*)pcm, N, CC, st->upsample, mode->preemph, st->preemph_memD);
Jean-Marc Valin69062102012-11-08 09:42:27 -05002183 st->prefilter_period_old = st->prefilter_period;
2184 st->prefilter_gain_old = st->prefilter_gain;
2185 st->prefilter_tapset_old = st->prefilter_tapset;
2186 }
2187#endif
2188
2189 st->prefilter_period = pitch_index;
2190 st->prefilter_gain = gain1;
2191 st->prefilter_tapset = prefilter_tapset;
2192#ifdef RESYNTH
2193 if (LM!=0)
2194 {
2195 st->prefilter_period_old = st->prefilter_period;
2196 st->prefilter_gain_old = st->prefilter_gain;
2197 st->prefilter_tapset_old = st->prefilter_tapset;
2198 }
2199#endif
2200
2201 if (CC==2&&C==1) {
Jean-Marc Valinff072002013-12-08 23:31:30 -05002202 OPUS_COPY(&oldBandE[nbEBands], oldBandE, nbEBands);
Jean-Marc Valin69062102012-11-08 09:42:27 -05002203 }
2204
2205 if (!isTransient)
2206 {
Jean-Marc Valinff072002013-12-08 23:31:30 -05002207 OPUS_COPY(oldLogE2, oldLogE, CC*nbEBands);
2208 OPUS_COPY(oldLogE, oldBandE, CC*nbEBands);
Jean-Marc Valin69062102012-11-08 09:42:27 -05002209 } else {
2210 for (i=0;i<CC*nbEBands;i++)
2211 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
2212 }
2213 /* In case start or end were to change */
2214 c=0; do
2215 {
Jean-Marc Valin91f80102013-12-10 18:38:44 -05002216 for (i=0;i<start;i++)
Jean-Marc Valin69062102012-11-08 09:42:27 -05002217 {
2218 oldBandE[c*nbEBands+i]=0;
2219 oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
2220 }
Jean-Marc Valin91f80102013-12-10 18:38:44 -05002221 for (i=end;i<nbEBands;i++)
Jean-Marc Valin69062102012-11-08 09:42:27 -05002222 {
2223 oldBandE[c*nbEBands+i]=0;
2224 oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
2225 }
2226 } while (++c<CC);
2227
Jean-Marc Valin3252bf22013-04-19 03:14:28 -04002228 if (isTransient || transient_got_disabled)
Jean-Marc Valin69062102012-11-08 09:42:27 -05002229 st->consec_transient++;
2230 else
2231 st->consec_transient=0;
2232 st->rng = enc->rng;
2233
2234 /* If there's any room left (can only happen for very high rates),
2235 it's already filled with zeros */
2236 ec_enc_done(enc);
2237
2238#ifdef CUSTOM_MODES
2239 if (st->signalling)
2240 nbCompressedBytes++;
2241#endif
2242
2243 RESTORE_STACK;
2244 if (ec_get_error(enc))
2245 return OPUS_INTERNAL_ERROR;
2246 else
2247 return nbCompressedBytes;
2248}
2249
2250
2251#ifdef CUSTOM_MODES
2252
2253#ifdef FIXED_POINT
2254int opus_custom_encode(CELTEncoder * OPUS_RESTRICT st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
2255{
2256 return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
2257}
2258
2259#ifndef DISABLE_FLOAT_API
2260int opus_custom_encode_float(CELTEncoder * OPUS_RESTRICT st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
2261{
2262 int j, ret, C, N;
2263 VARDECL(opus_int16, in);
2264 ALLOC_STACK;
2265
2266 if (pcm==NULL)
2267 return OPUS_BAD_ARG;
2268
2269 C = st->channels;
2270 N = frame_size;
2271 ALLOC(in, C*N, opus_int16);
2272
2273 for (j=0;j<C*N;j++)
2274 in[j] = FLOAT2INT16(pcm[j]);
2275
2276 ret=celt_encode_with_ec(st,in,frame_size,compressed,nbCompressedBytes, NULL);
2277#ifdef RESYNTH
2278 for (j=0;j<C*N;j++)
2279 ((float*)pcm)[j]=in[j]*(1.f/32768.f);
2280#endif
2281 RESTORE_STACK;
2282 return ret;
2283}
2284#endif /* DISABLE_FLOAT_API */
2285#else
2286
2287int opus_custom_encode(CELTEncoder * OPUS_RESTRICT st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
2288{
2289 int j, ret, C, N;
2290 VARDECL(celt_sig, in);
2291 ALLOC_STACK;
2292
2293 if (pcm==NULL)
2294 return OPUS_BAD_ARG;
2295
2296 C=st->channels;
2297 N=frame_size;
2298 ALLOC(in, C*N, celt_sig);
2299 for (j=0;j<C*N;j++) {
2300 in[j] = SCALEOUT(pcm[j]);
2301 }
2302
2303 ret = celt_encode_with_ec(st,in,frame_size,compressed,nbCompressedBytes, NULL);
2304#ifdef RESYNTH
2305 for (j=0;j<C*N;j++)
2306 ((opus_int16*)pcm)[j] = FLOAT2INT16(in[j]);
2307#endif
2308 RESTORE_STACK;
2309 return ret;
2310}
2311
2312int opus_custom_encode_float(CELTEncoder * OPUS_RESTRICT st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
2313{
2314 return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
2315}
2316
2317#endif
2318
2319#endif /* CUSTOM_MODES */
2320
2321int opus_custom_encoder_ctl(CELTEncoder * OPUS_RESTRICT st, int request, ...)
2322{
2323 va_list ap;
2324
2325 va_start(ap, request);
2326 switch (request)
2327 {
2328 case OPUS_SET_COMPLEXITY_REQUEST:
2329 {
2330 int value = va_arg(ap, opus_int32);
2331 if (value<0 || value>10)
2332 goto bad_arg;
2333 st->complexity = value;
2334 }
2335 break;
2336 case CELT_SET_START_BAND_REQUEST:
2337 {
2338 opus_int32 value = va_arg(ap, opus_int32);
2339 if (value<0 || value>=st->mode->nbEBands)
2340 goto bad_arg;
2341 st->start = value;
2342 }
2343 break;
2344 case CELT_SET_END_BAND_REQUEST:
2345 {
2346 opus_int32 value = va_arg(ap, opus_int32);
2347 if (value<1 || value>st->mode->nbEBands)
2348 goto bad_arg;
2349 st->end = value;
2350 }
2351 break;
2352 case CELT_SET_PREDICTION_REQUEST:
2353 {
2354 int value = va_arg(ap, opus_int32);
2355 if (value<0 || value>2)
2356 goto bad_arg;
2357 st->disable_pf = value<=1;
2358 st->force_intra = value==0;
2359 }
2360 break;
2361 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
2362 {
2363 int value = va_arg(ap, opus_int32);
2364 if (value<0 || value>100)
2365 goto bad_arg;
2366 st->loss_rate = value;
2367 }
2368 break;
2369 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
2370 {
2371 opus_int32 value = va_arg(ap, opus_int32);
2372 st->constrained_vbr = value;
2373 }
2374 break;
2375 case OPUS_SET_VBR_REQUEST:
2376 {
2377 opus_int32 value = va_arg(ap, opus_int32);
2378 st->vbr = value;
2379 }
2380 break;
2381 case OPUS_SET_BITRATE_REQUEST:
2382 {
2383 opus_int32 value = va_arg(ap, opus_int32);
2384 if (value<=500 && value!=OPUS_BITRATE_MAX)
2385 goto bad_arg;
2386 value = IMIN(value, 260000*st->channels);
2387 st->bitrate = value;
2388 }
2389 break;
2390 case CELT_SET_CHANNELS_REQUEST:
2391 {
2392 opus_int32 value = va_arg(ap, opus_int32);
2393 if (value<1 || value>2)
2394 goto bad_arg;
2395 st->stream_channels = value;
2396 }
2397 break;
2398 case OPUS_SET_LSB_DEPTH_REQUEST:
2399 {
2400 opus_int32 value = va_arg(ap, opus_int32);
2401 if (value<8 || value>24)
2402 goto bad_arg;
2403 st->lsb_depth=value;
2404 }
2405 break;
2406 case OPUS_GET_LSB_DEPTH_REQUEST:
2407 {
2408 opus_int32 *value = va_arg(ap, opus_int32*);
2409 *value=st->lsb_depth;
2410 }
2411 break;
Jean-Marc Valin3252bf22013-04-19 03:14:28 -04002412 case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
2413 {
2414 opus_int32 value = va_arg(ap, opus_int32);
2415 st->variable_duration = value;
2416 }
2417 break;
Jean-Marc Valin18a380a2016-04-20 13:27:06 -04002418 case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
2419 {
2420 opus_int32 value = va_arg(ap, opus_int32);
2421 if(value<0 || value>1)
2422 {
2423 goto bad_arg;
2424 }
2425 st->disable_inv = value;
2426 }
2427 break;
2428 case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
2429 {
2430 opus_int32 *value = va_arg(ap, opus_int32*);
2431 if (!value)
2432 {
2433 goto bad_arg;
2434 }
2435 *value = st->disable_inv;
2436 }
2437 break;
Jean-Marc Valin69062102012-11-08 09:42:27 -05002438 case OPUS_RESET_STATE:
2439 {
2440 int i;
2441 opus_val16 *oldBandE, *oldLogE, *oldLogE2;
Jean-Marc Valin91f80102013-12-10 18:38:44 -05002442 oldBandE = (opus_val16*)(st->in_mem+st->channels*(st->mode->overlap+COMBFILTER_MAXPERIOD));
Jean-Marc Valin69062102012-11-08 09:42:27 -05002443 oldLogE = oldBandE + st->channels*st->mode->nbEBands;
2444 oldLogE2 = oldLogE + st->channels*st->mode->nbEBands;
2445 OPUS_CLEAR((char*)&st->ENCODER_RESET_START,
2446 opus_custom_encoder_get_size(st->mode, st->channels)-
2447 ((char*)&st->ENCODER_RESET_START - (char*)st));
2448 for (i=0;i<st->channels*st->mode->nbEBands;i++)
2449 oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT);
2450 st->vbr_offset = 0;
2451 st->delayedIntra = 1;
2452 st->spread_decision = SPREAD_NORMAL;
2453 st->tonal_average = 256;
2454 st->hf_average = 0;
2455 st->tapset_decision = 0;
2456 }
2457 break;
2458#ifdef CUSTOM_MODES
2459 case CELT_SET_INPUT_CLIPPING_REQUEST:
2460 {
2461 opus_int32 value = va_arg(ap, opus_int32);
2462 st->clip = value;
2463 }
2464 break;
2465#endif
2466 case CELT_SET_SIGNALLING_REQUEST:
2467 {
2468 opus_int32 value = va_arg(ap, opus_int32);
2469 st->signalling = value;
2470 }
2471 break;
2472 case CELT_SET_ANALYSIS_REQUEST:
2473 {
2474 AnalysisInfo *info = va_arg(ap, AnalysisInfo *);
2475 if (info)
2476 OPUS_COPY(&st->analysis, info, 1);
2477 }
2478 break;
Jean-Marc Valin61714e92016-04-23 00:34:53 -04002479 case CELT_SET_SILK_INFO_REQUEST:
2480 {
2481 SILKInfo *info = va_arg(ap, SILKInfo *);
2482 if (info)
2483 OPUS_COPY(&st->silk_info, info, 1);
2484 }
2485 break;
Jean-Marc Valin69062102012-11-08 09:42:27 -05002486 case CELT_GET_MODE_REQUEST:
2487 {
2488 const CELTMode ** value = va_arg(ap, const CELTMode**);
2489 if (value==0)
2490 goto bad_arg;
2491 *value=st->mode;
2492 }
2493 break;
2494 case OPUS_GET_FINAL_RANGE_REQUEST:
2495 {
2496 opus_uint32 * value = va_arg(ap, opus_uint32 *);
2497 if (value==0)
2498 goto bad_arg;
2499 *value=st->rng;
2500 }
2501 break;
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -04002502 case OPUS_SET_LFE_REQUEST:
2503 {
2504 opus_int32 value = va_arg(ap, opus_int32);
2505 st->lfe = value;
2506 }
2507 break;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -04002508 case OPUS_SET_ENERGY_MASK_REQUEST:
2509 {
2510 opus_val16 *value = va_arg(ap, opus_val16*);
2511 st->energy_mask = value;
2512 }
2513 break;
Jean-Marc Valin69062102012-11-08 09:42:27 -05002514 default:
2515 goto bad_request;
2516 }
2517 va_end(ap);
2518 return OPUS_OK;
2519bad_arg:
2520 va_end(ap);
2521 return OPUS_BAD_ARG;
2522bad_request:
2523 va_end(ap);
2524 return OPUS_UNIMPLEMENTED;
2525}