Chris@69
|
1 /* Copyright (c) 2007-2008 CSIRO
|
Chris@69
|
2 Copyright (c) 2007-2010 Xiph.Org Foundation
|
Chris@69
|
3 Copyright (c) 2008 Gregory Maxwell
|
Chris@69
|
4 Written by Jean-Marc Valin and Gregory Maxwell */
|
Chris@69
|
5 /*
|
Chris@69
|
6 Redistribution and use in source and binary forms, with or without
|
Chris@69
|
7 modification, are permitted provided that the following conditions
|
Chris@69
|
8 are met:
|
Chris@69
|
9
|
Chris@69
|
10 - Redistributions of source code must retain the above copyright
|
Chris@69
|
11 notice, this list of conditions and the following disclaimer.
|
Chris@69
|
12
|
Chris@69
|
13 - Redistributions in binary form must reproduce the above copyright
|
Chris@69
|
14 notice, this list of conditions and the following disclaimer in the
|
Chris@69
|
15 documentation and/or other materials provided with the distribution.
|
Chris@69
|
16
|
Chris@69
|
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
Chris@69
|
18 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
Chris@69
|
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
Chris@69
|
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
Chris@69
|
21 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
Chris@69
|
22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
Chris@69
|
23 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
Chris@69
|
24 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
Chris@69
|
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
Chris@69
|
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
Chris@69
|
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
Chris@69
|
28 */
|
Chris@69
|
29
|
Chris@69
|
30 #ifdef HAVE_CONFIG_H
|
Chris@69
|
31 #include "config.h"
|
Chris@69
|
32 #endif
|
Chris@69
|
33
|
Chris@69
|
34 #define CELT_DECODER_C
|
Chris@69
|
35
|
Chris@69
|
36 #include "cpu_support.h"
|
Chris@69
|
37 #include "os_support.h"
|
Chris@69
|
38 #include "mdct.h"
|
Chris@69
|
39 #include <math.h>
|
Chris@69
|
40 #include "celt.h"
|
Chris@69
|
41 #include "pitch.h"
|
Chris@69
|
42 #include "bands.h"
|
Chris@69
|
43 #include "modes.h"
|
Chris@69
|
44 #include "entcode.h"
|
Chris@69
|
45 #include "quant_bands.h"
|
Chris@69
|
46 #include "rate.h"
|
Chris@69
|
47 #include "stack_alloc.h"
|
Chris@69
|
48 #include "mathops.h"
|
Chris@69
|
49 #include "float_cast.h"
|
Chris@69
|
50 #include <stdarg.h>
|
Chris@69
|
51 #include "celt_lpc.h"
|
Chris@69
|
52 #include "vq.h"
|
Chris@69
|
53
|
Chris@69
|
54 /* The maximum pitch lag to allow in the pitch-based PLC. It's possible to save
|
Chris@69
|
55 CPU time in the PLC pitch search by making this smaller than MAX_PERIOD. The
|
Chris@69
|
56 current value corresponds to a pitch of 66.67 Hz. */
|
Chris@69
|
57 #define PLC_PITCH_LAG_MAX (720)
|
Chris@69
|
58 /* The minimum pitch lag to allow in the pitch-based PLC. This corresponds to a
|
Chris@69
|
59 pitch of 480 Hz. */
|
Chris@69
|
60 #define PLC_PITCH_LAG_MIN (100)
|
Chris@69
|
61
|
Chris@69
|
62 #if defined(SMALL_FOOTPRINT) && defined(FIXED_POINT)
|
Chris@69
|
63 #define NORM_ALIASING_HACK
|
Chris@69
|
64 #endif
|
Chris@69
|
65 /**********************************************************************/
|
Chris@69
|
66 /* */
|
Chris@69
|
67 /* DECODER */
|
Chris@69
|
68 /* */
|
Chris@69
|
69 /**********************************************************************/
|
Chris@69
|
70 #define DECODE_BUFFER_SIZE 2048
|
Chris@69
|
71
|
Chris@69
|
72 /** Decoder state
|
Chris@69
|
73 @brief Decoder state
|
Chris@69
|
74 */
|
Chris@69
|
75 struct OpusCustomDecoder {
|
Chris@69
|
76 const OpusCustomMode *mode;
|
Chris@69
|
77 int overlap;
|
Chris@69
|
78 int channels;
|
Chris@69
|
79 int stream_channels;
|
Chris@69
|
80
|
Chris@69
|
81 int downsample;
|
Chris@69
|
82 int start, end;
|
Chris@69
|
83 int signalling;
|
Chris@69
|
84 int disable_inv;
|
Chris@69
|
85 int arch;
|
Chris@69
|
86
|
Chris@69
|
87 /* Everything beyond this point gets cleared on a reset */
|
Chris@69
|
88 #define DECODER_RESET_START rng
|
Chris@69
|
89
|
Chris@69
|
90 opus_uint32 rng;
|
Chris@69
|
91 int error;
|
Chris@69
|
92 int last_pitch_index;
|
Chris@69
|
93 int loss_count;
|
Chris@69
|
94 int skip_plc;
|
Chris@69
|
95 int postfilter_period;
|
Chris@69
|
96 int postfilter_period_old;
|
Chris@69
|
97 opus_val16 postfilter_gain;
|
Chris@69
|
98 opus_val16 postfilter_gain_old;
|
Chris@69
|
99 int postfilter_tapset;
|
Chris@69
|
100 int postfilter_tapset_old;
|
Chris@69
|
101
|
Chris@69
|
102 celt_sig preemph_memD[2];
|
Chris@69
|
103
|
Chris@69
|
104 celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */
|
Chris@69
|
105 /* opus_val16 lpc[], Size = channels*LPC_ORDER */
|
Chris@69
|
106 /* opus_val16 oldEBands[], Size = 2*mode->nbEBands */
|
Chris@69
|
107 /* opus_val16 oldLogE[], Size = 2*mode->nbEBands */
|
Chris@69
|
108 /* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */
|
Chris@69
|
109 /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */
|
Chris@69
|
110 };
|
Chris@69
|
111
|
Chris@69
|
112 #if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
|
Chris@69
|
113 /* Make basic checks on the CELT state to ensure we don't end
|
Chris@69
|
114 up writing all over memory. */
|
Chris@69
|
115 void validate_celt_decoder(CELTDecoder *st)
|
Chris@69
|
116 {
|
Chris@69
|
117 #ifndef CUSTOM_MODES
|
Chris@69
|
118 celt_assert(st->mode == opus_custom_mode_create(48000, 960, NULL));
|
Chris@69
|
119 celt_assert(st->overlap == 120);
|
Chris@69
|
120 #endif
|
Chris@69
|
121 celt_assert(st->channels == 1 || st->channels == 2);
|
Chris@69
|
122 celt_assert(st->stream_channels == 1 || st->stream_channels == 2);
|
Chris@69
|
123 celt_assert(st->downsample > 0);
|
Chris@69
|
124 celt_assert(st->start == 0 || st->start == 17);
|
Chris@69
|
125 celt_assert(st->start < st->end);
|
Chris@69
|
126 celt_assert(st->end <= 21);
|
Chris@69
|
127 #ifdef OPUS_ARCHMASK
|
Chris@69
|
128 celt_assert(st->arch >= 0);
|
Chris@69
|
129 celt_assert(st->arch <= OPUS_ARCHMASK);
|
Chris@69
|
130 #endif
|
Chris@69
|
131 celt_assert(st->last_pitch_index <= PLC_PITCH_LAG_MAX);
|
Chris@69
|
132 celt_assert(st->last_pitch_index >= PLC_PITCH_LAG_MIN || st->last_pitch_index == 0);
|
Chris@69
|
133 celt_assert(st->postfilter_period < MAX_PERIOD);
|
Chris@69
|
134 celt_assert(st->postfilter_period >= COMBFILTER_MINPERIOD || st->postfilter_period == 0);
|
Chris@69
|
135 celt_assert(st->postfilter_period_old < MAX_PERIOD);
|
Chris@69
|
136 celt_assert(st->postfilter_period_old >= COMBFILTER_MINPERIOD || st->postfilter_period_old == 0);
|
Chris@69
|
137 celt_assert(st->postfilter_tapset <= 2);
|
Chris@69
|
138 celt_assert(st->postfilter_tapset >= 0);
|
Chris@69
|
139 celt_assert(st->postfilter_tapset_old <= 2);
|
Chris@69
|
140 celt_assert(st->postfilter_tapset_old >= 0);
|
Chris@69
|
141 }
|
Chris@69
|
142 #endif
|
Chris@69
|
143
|
Chris@69
|
144 int celt_decoder_get_size(int channels)
|
Chris@69
|
145 {
|
Chris@69
|
146 const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
|
Chris@69
|
147 return opus_custom_decoder_get_size(mode, channels);
|
Chris@69
|
148 }
|
Chris@69
|
149
|
Chris@69
|
150 OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_get_size(const CELTMode *mode, int channels)
|
Chris@69
|
151 {
|
Chris@69
|
152 int size = sizeof(struct CELTDecoder)
|
Chris@69
|
153 + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig)
|
Chris@69
|
154 + channels*LPC_ORDER*sizeof(opus_val16)
|
Chris@69
|
155 + 4*2*mode->nbEBands*sizeof(opus_val16);
|
Chris@69
|
156 return size;
|
Chris@69
|
157 }
|
Chris@69
|
158
|
Chris@69
|
159 #ifdef CUSTOM_MODES
|
Chris@69
|
160 CELTDecoder *opus_custom_decoder_create(const CELTMode *mode, int channels, int *error)
|
Chris@69
|
161 {
|
Chris@69
|
162 int ret;
|
Chris@69
|
163 CELTDecoder *st = (CELTDecoder *)opus_alloc(opus_custom_decoder_get_size(mode, channels));
|
Chris@69
|
164 ret = opus_custom_decoder_init(st, mode, channels);
|
Chris@69
|
165 if (ret != OPUS_OK)
|
Chris@69
|
166 {
|
Chris@69
|
167 opus_custom_decoder_destroy(st);
|
Chris@69
|
168 st = NULL;
|
Chris@69
|
169 }
|
Chris@69
|
170 if (error)
|
Chris@69
|
171 *error = ret;
|
Chris@69
|
172 return st;
|
Chris@69
|
173 }
|
Chris@69
|
174 #endif /* CUSTOM_MODES */
|
Chris@69
|
175
|
Chris@69
|
176 int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels)
|
Chris@69
|
177 {
|
Chris@69
|
178 int ret;
|
Chris@69
|
179 ret = opus_custom_decoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels);
|
Chris@69
|
180 if (ret != OPUS_OK)
|
Chris@69
|
181 return ret;
|
Chris@69
|
182 st->downsample = resampling_factor(sampling_rate);
|
Chris@69
|
183 if (st->downsample==0)
|
Chris@69
|
184 return OPUS_BAD_ARG;
|
Chris@69
|
185 else
|
Chris@69
|
186 return OPUS_OK;
|
Chris@69
|
187 }
|
Chris@69
|
188
|
Chris@69
|
189 OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels)
|
Chris@69
|
190 {
|
Chris@69
|
191 if (channels < 0 || channels > 2)
|
Chris@69
|
192 return OPUS_BAD_ARG;
|
Chris@69
|
193
|
Chris@69
|
194 if (st==NULL)
|
Chris@69
|
195 return OPUS_ALLOC_FAIL;
|
Chris@69
|
196
|
Chris@69
|
197 OPUS_CLEAR((char*)st, opus_custom_decoder_get_size(mode, channels));
|
Chris@69
|
198
|
Chris@69
|
199 st->mode = mode;
|
Chris@69
|
200 st->overlap = mode->overlap;
|
Chris@69
|
201 st->stream_channels = st->channels = channels;
|
Chris@69
|
202
|
Chris@69
|
203 st->downsample = 1;
|
Chris@69
|
204 st->start = 0;
|
Chris@69
|
205 st->end = st->mode->effEBands;
|
Chris@69
|
206 st->signalling = 1;
|
Chris@69
|
207 #ifndef DISABLE_UPDATE_DRAFT
|
Chris@69
|
208 st->disable_inv = channels == 1;
|
Chris@69
|
209 #else
|
Chris@69
|
210 st->disable_inv = 0;
|
Chris@69
|
211 #endif
|
Chris@69
|
212 st->arch = opus_select_arch();
|
Chris@69
|
213
|
Chris@69
|
214 opus_custom_decoder_ctl(st, OPUS_RESET_STATE);
|
Chris@69
|
215
|
Chris@69
|
216 return OPUS_OK;
|
Chris@69
|
217 }
|
Chris@69
|
218
|
Chris@69
|
219 #ifdef CUSTOM_MODES
|
Chris@69
|
220 void opus_custom_decoder_destroy(CELTDecoder *st)
|
Chris@69
|
221 {
|
Chris@69
|
222 opus_free(st);
|
Chris@69
|
223 }
|
Chris@69
|
224 #endif /* CUSTOM_MODES */
|
Chris@69
|
225
|
Chris@69
|
226 #ifndef CUSTOM_MODES
|
Chris@69
|
227 /* Special case for stereo with no downsampling and no accumulation. This is
|
Chris@69
|
228 quite common and we can make it faster by processing both channels in the
|
Chris@69
|
229 same loop, reducing overhead due to the dependency loop in the IIR filter. */
|
Chris@69
|
230 static void deemphasis_stereo_simple(celt_sig *in[], opus_val16 *pcm, int N, const opus_val16 coef0,
|
Chris@69
|
231 celt_sig *mem)
|
Chris@69
|
232 {
|
Chris@69
|
233 celt_sig * OPUS_RESTRICT x0;
|
Chris@69
|
234 celt_sig * OPUS_RESTRICT x1;
|
Chris@69
|
235 celt_sig m0, m1;
|
Chris@69
|
236 int j;
|
Chris@69
|
237 x0=in[0];
|
Chris@69
|
238 x1=in[1];
|
Chris@69
|
239 m0 = mem[0];
|
Chris@69
|
240 m1 = mem[1];
|
Chris@69
|
241 for (j=0;j<N;j++)
|
Chris@69
|
242 {
|
Chris@69
|
243 celt_sig tmp0, tmp1;
|
Chris@69
|
244 /* Add VERY_SMALL to x[] first to reduce dependency chain. */
|
Chris@69
|
245 tmp0 = x0[j] + VERY_SMALL + m0;
|
Chris@69
|
246 tmp1 = x1[j] + VERY_SMALL + m1;
|
Chris@69
|
247 m0 = MULT16_32_Q15(coef0, tmp0);
|
Chris@69
|
248 m1 = MULT16_32_Q15(coef0, tmp1);
|
Chris@69
|
249 pcm[2*j ] = SCALEOUT(SIG2WORD16(tmp0));
|
Chris@69
|
250 pcm[2*j+1] = SCALEOUT(SIG2WORD16(tmp1));
|
Chris@69
|
251 }
|
Chris@69
|
252 mem[0] = m0;
|
Chris@69
|
253 mem[1] = m1;
|
Chris@69
|
254 }
|
Chris@69
|
255 #endif
|
Chris@69
|
256
|
Chris@69
|
257 #ifndef RESYNTH
|
Chris@69
|
258 static
|
Chris@69
|
259 #endif
|
Chris@69
|
260 void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef,
|
Chris@69
|
261 celt_sig *mem, int accum)
|
Chris@69
|
262 {
|
Chris@69
|
263 int c;
|
Chris@69
|
264 int Nd;
|
Chris@69
|
265 int apply_downsampling=0;
|
Chris@69
|
266 opus_val16 coef0;
|
Chris@69
|
267 VARDECL(celt_sig, scratch);
|
Chris@69
|
268 SAVE_STACK;
|
Chris@69
|
269 #ifndef CUSTOM_MODES
|
Chris@69
|
270 /* Short version for common case. */
|
Chris@69
|
271 if (downsample == 1 && C == 2 && !accum)
|
Chris@69
|
272 {
|
Chris@69
|
273 deemphasis_stereo_simple(in, pcm, N, coef[0], mem);
|
Chris@69
|
274 return;
|
Chris@69
|
275 }
|
Chris@69
|
276 #endif
|
Chris@69
|
277 #ifndef FIXED_POINT
|
Chris@69
|
278 (void)accum;
|
Chris@69
|
279 celt_assert(accum==0);
|
Chris@69
|
280 #endif
|
Chris@69
|
281 ALLOC(scratch, N, celt_sig);
|
Chris@69
|
282 coef0 = coef[0];
|
Chris@69
|
283 Nd = N/downsample;
|
Chris@69
|
284 c=0; do {
|
Chris@69
|
285 int j;
|
Chris@69
|
286 celt_sig * OPUS_RESTRICT x;
|
Chris@69
|
287 opus_val16 * OPUS_RESTRICT y;
|
Chris@69
|
288 celt_sig m = mem[c];
|
Chris@69
|
289 x =in[c];
|
Chris@69
|
290 y = pcm+c;
|
Chris@69
|
291 #ifdef CUSTOM_MODES
|
Chris@69
|
292 if (coef[1] != 0)
|
Chris@69
|
293 {
|
Chris@69
|
294 opus_val16 coef1 = coef[1];
|
Chris@69
|
295 opus_val16 coef3 = coef[3];
|
Chris@69
|
296 for (j=0;j<N;j++)
|
Chris@69
|
297 {
|
Chris@69
|
298 celt_sig tmp = x[j] + m + VERY_SMALL;
|
Chris@69
|
299 m = MULT16_32_Q15(coef0, tmp)
|
Chris@69
|
300 - MULT16_32_Q15(coef1, x[j]);
|
Chris@69
|
301 tmp = SHL32(MULT16_32_Q15(coef3, tmp), 2);
|
Chris@69
|
302 scratch[j] = tmp;
|
Chris@69
|
303 }
|
Chris@69
|
304 apply_downsampling=1;
|
Chris@69
|
305 } else
|
Chris@69
|
306 #endif
|
Chris@69
|
307 if (downsample>1)
|
Chris@69
|
308 {
|
Chris@69
|
309 /* Shortcut for the standard (non-custom modes) case */
|
Chris@69
|
310 for (j=0;j<N;j++)
|
Chris@69
|
311 {
|
Chris@69
|
312 celt_sig tmp = x[j] + VERY_SMALL + m;
|
Chris@69
|
313 m = MULT16_32_Q15(coef0, tmp);
|
Chris@69
|
314 scratch[j] = tmp;
|
Chris@69
|
315 }
|
Chris@69
|
316 apply_downsampling=1;
|
Chris@69
|
317 } else {
|
Chris@69
|
318 /* Shortcut for the standard (non-custom modes) case */
|
Chris@69
|
319 #ifdef FIXED_POINT
|
Chris@69
|
320 if (accum)
|
Chris@69
|
321 {
|
Chris@69
|
322 for (j=0;j<N;j++)
|
Chris@69
|
323 {
|
Chris@69
|
324 celt_sig tmp = x[j] + m + VERY_SMALL;
|
Chris@69
|
325 m = MULT16_32_Q15(coef0, tmp);
|
Chris@69
|
326 y[j*C] = SAT16(ADD32(y[j*C], SCALEOUT(SIG2WORD16(tmp))));
|
Chris@69
|
327 }
|
Chris@69
|
328 } else
|
Chris@69
|
329 #endif
|
Chris@69
|
330 {
|
Chris@69
|
331 for (j=0;j<N;j++)
|
Chris@69
|
332 {
|
Chris@69
|
333 celt_sig tmp = x[j] + VERY_SMALL + m;
|
Chris@69
|
334 m = MULT16_32_Q15(coef0, tmp);
|
Chris@69
|
335 y[j*C] = SCALEOUT(SIG2WORD16(tmp));
|
Chris@69
|
336 }
|
Chris@69
|
337 }
|
Chris@69
|
338 }
|
Chris@69
|
339 mem[c] = m;
|
Chris@69
|
340
|
Chris@69
|
341 if (apply_downsampling)
|
Chris@69
|
342 {
|
Chris@69
|
343 /* Perform down-sampling */
|
Chris@69
|
344 #ifdef FIXED_POINT
|
Chris@69
|
345 if (accum)
|
Chris@69
|
346 {
|
Chris@69
|
347 for (j=0;j<Nd;j++)
|
Chris@69
|
348 y[j*C] = SAT16(ADD32(y[j*C], SCALEOUT(SIG2WORD16(scratch[j*downsample]))));
|
Chris@69
|
349 } else
|
Chris@69
|
350 #endif
|
Chris@69
|
351 {
|
Chris@69
|
352 for (j=0;j<Nd;j++)
|
Chris@69
|
353 y[j*C] = SCALEOUT(SIG2WORD16(scratch[j*downsample]));
|
Chris@69
|
354 }
|
Chris@69
|
355 }
|
Chris@69
|
356 } while (++c<C);
|
Chris@69
|
357 RESTORE_STACK;
|
Chris@69
|
358 }
|
Chris@69
|
359
|
Chris@69
|
360 #ifndef RESYNTH
|
Chris@69
|
361 static
|
Chris@69
|
362 #endif
|
Chris@69
|
363 void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
|
Chris@69
|
364 opus_val16 *oldBandE, int start, int effEnd, int C, int CC,
|
Chris@69
|
365 int isTransient, int LM, int downsample,
|
Chris@69
|
366 int silence, int arch)
|
Chris@69
|
367 {
|
Chris@69
|
368 int c, i;
|
Chris@69
|
369 int M;
|
Chris@69
|
370 int b;
|
Chris@69
|
371 int B;
|
Chris@69
|
372 int N, NB;
|
Chris@69
|
373 int shift;
|
Chris@69
|
374 int nbEBands;
|
Chris@69
|
375 int overlap;
|
Chris@69
|
376 VARDECL(celt_sig, freq);
|
Chris@69
|
377 SAVE_STACK;
|
Chris@69
|
378
|
Chris@69
|
379 overlap = mode->overlap;
|
Chris@69
|
380 nbEBands = mode->nbEBands;
|
Chris@69
|
381 N = mode->shortMdctSize<<LM;
|
Chris@69
|
382 ALLOC(freq, N, celt_sig); /**< Interleaved signal MDCTs */
|
Chris@69
|
383 M = 1<<LM;
|
Chris@69
|
384
|
Chris@69
|
385 if (isTransient)
|
Chris@69
|
386 {
|
Chris@69
|
387 B = M;
|
Chris@69
|
388 NB = mode->shortMdctSize;
|
Chris@69
|
389 shift = mode->maxLM;
|
Chris@69
|
390 } else {
|
Chris@69
|
391 B = 1;
|
Chris@69
|
392 NB = mode->shortMdctSize<<LM;
|
Chris@69
|
393 shift = mode->maxLM-LM;
|
Chris@69
|
394 }
|
Chris@69
|
395
|
Chris@69
|
396 if (CC==2&&C==1)
|
Chris@69
|
397 {
|
Chris@69
|
398 /* Copying a mono streams to two channels */
|
Chris@69
|
399 celt_sig *freq2;
|
Chris@69
|
400 denormalise_bands(mode, X, freq, oldBandE, start, effEnd, M,
|
Chris@69
|
401 downsample, silence);
|
Chris@69
|
402 /* Store a temporary copy in the output buffer because the IMDCT destroys its input. */
|
Chris@69
|
403 freq2 = out_syn[1]+overlap/2;
|
Chris@69
|
404 OPUS_COPY(freq2, freq, N);
|
Chris@69
|
405 for (b=0;b<B;b++)
|
Chris@69
|
406 clt_mdct_backward(&mode->mdct, &freq2[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch);
|
Chris@69
|
407 for (b=0;b<B;b++)
|
Chris@69
|
408 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[1]+NB*b, mode->window, overlap, shift, B, arch);
|
Chris@69
|
409 } else if (CC==1&&C==2)
|
Chris@69
|
410 {
|
Chris@69
|
411 /* Downmixing a stereo stream to mono */
|
Chris@69
|
412 celt_sig *freq2;
|
Chris@69
|
413 freq2 = out_syn[0]+overlap/2;
|
Chris@69
|
414 denormalise_bands(mode, X, freq, oldBandE, start, effEnd, M,
|
Chris@69
|
415 downsample, silence);
|
Chris@69
|
416 /* Use the output buffer as temp array before downmixing. */
|
Chris@69
|
417 denormalise_bands(mode, X+N, freq2, oldBandE+nbEBands, start, effEnd, M,
|
Chris@69
|
418 downsample, silence);
|
Chris@69
|
419 for (i=0;i<N;i++)
|
Chris@69
|
420 freq[i] = ADD32(HALF32(freq[i]), HALF32(freq2[i]));
|
Chris@69
|
421 for (b=0;b<B;b++)
|
Chris@69
|
422 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch);
|
Chris@69
|
423 } else {
|
Chris@69
|
424 /* Normal case (mono or stereo) */
|
Chris@69
|
425 c=0; do {
|
Chris@69
|
426 denormalise_bands(mode, X+c*N, freq, oldBandE+c*nbEBands, start, effEnd, M,
|
Chris@69
|
427 downsample, silence);
|
Chris@69
|
428 for (b=0;b<B;b++)
|
Chris@69
|
429 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B, arch);
|
Chris@69
|
430 } while (++c<CC);
|
Chris@69
|
431 }
|
Chris@69
|
432 /* Saturate IMDCT output so that we can't overflow in the pitch postfilter
|
Chris@69
|
433 or in the */
|
Chris@69
|
434 c=0; do {
|
Chris@69
|
435 for (i=0;i<N;i++)
|
Chris@69
|
436 out_syn[c][i] = SATURATE(out_syn[c][i], SIG_SAT);
|
Chris@69
|
437 } while (++c<CC);
|
Chris@69
|
438 RESTORE_STACK;
|
Chris@69
|
439 }
|
Chris@69
|
440
|
Chris@69
|
441 static void tf_decode(int start, int end, int isTransient, int *tf_res, int LM, ec_dec *dec)
|
Chris@69
|
442 {
|
Chris@69
|
443 int i, curr, tf_select;
|
Chris@69
|
444 int tf_select_rsv;
|
Chris@69
|
445 int tf_changed;
|
Chris@69
|
446 int logp;
|
Chris@69
|
447 opus_uint32 budget;
|
Chris@69
|
448 opus_uint32 tell;
|
Chris@69
|
449
|
Chris@69
|
450 budget = dec->storage*8;
|
Chris@69
|
451 tell = ec_tell(dec);
|
Chris@69
|
452 logp = isTransient ? 2 : 4;
|
Chris@69
|
453 tf_select_rsv = LM>0 && tell+logp+1<=budget;
|
Chris@69
|
454 budget -= tf_select_rsv;
|
Chris@69
|
455 tf_changed = curr = 0;
|
Chris@69
|
456 for (i=start;i<end;i++)
|
Chris@69
|
457 {
|
Chris@69
|
458 if (tell+logp<=budget)
|
Chris@69
|
459 {
|
Chris@69
|
460 curr ^= ec_dec_bit_logp(dec, logp);
|
Chris@69
|
461 tell = ec_tell(dec);
|
Chris@69
|
462 tf_changed |= curr;
|
Chris@69
|
463 }
|
Chris@69
|
464 tf_res[i] = curr;
|
Chris@69
|
465 logp = isTransient ? 4 : 5;
|
Chris@69
|
466 }
|
Chris@69
|
467 tf_select = 0;
|
Chris@69
|
468 if (tf_select_rsv &&
|
Chris@69
|
469 tf_select_table[LM][4*isTransient+0+tf_changed] !=
|
Chris@69
|
470 tf_select_table[LM][4*isTransient+2+tf_changed])
|
Chris@69
|
471 {
|
Chris@69
|
472 tf_select = ec_dec_bit_logp(dec, 1);
|
Chris@69
|
473 }
|
Chris@69
|
474 for (i=start;i<end;i++)
|
Chris@69
|
475 {
|
Chris@69
|
476 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
|
Chris@69
|
477 }
|
Chris@69
|
478 }
|
Chris@69
|
479
|
Chris@69
|
480 static int celt_plc_pitch_search(celt_sig *decode_mem[2], int C, int arch)
|
Chris@69
|
481 {
|
Chris@69
|
482 int pitch_index;
|
Chris@69
|
483 VARDECL( opus_val16, lp_pitch_buf );
|
Chris@69
|
484 SAVE_STACK;
|
Chris@69
|
485 ALLOC( lp_pitch_buf, DECODE_BUFFER_SIZE>>1, opus_val16 );
|
Chris@69
|
486 pitch_downsample(decode_mem, lp_pitch_buf,
|
Chris@69
|
487 DECODE_BUFFER_SIZE, C, arch);
|
Chris@69
|
488 pitch_search(lp_pitch_buf+(PLC_PITCH_LAG_MAX>>1), lp_pitch_buf,
|
Chris@69
|
489 DECODE_BUFFER_SIZE-PLC_PITCH_LAG_MAX,
|
Chris@69
|
490 PLC_PITCH_LAG_MAX-PLC_PITCH_LAG_MIN, &pitch_index, arch);
|
Chris@69
|
491 pitch_index = PLC_PITCH_LAG_MAX-pitch_index;
|
Chris@69
|
492 RESTORE_STACK;
|
Chris@69
|
493 return pitch_index;
|
Chris@69
|
494 }
|
Chris@69
|
495
|
Chris@69
|
496 static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
|
Chris@69
|
497 {
|
Chris@69
|
498 int c;
|
Chris@69
|
499 int i;
|
Chris@69
|
500 const int C = st->channels;
|
Chris@69
|
501 celt_sig *decode_mem[2];
|
Chris@69
|
502 celt_sig *out_syn[2];
|
Chris@69
|
503 opus_val16 *lpc;
|
Chris@69
|
504 opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
|
Chris@69
|
505 const OpusCustomMode *mode;
|
Chris@69
|
506 int nbEBands;
|
Chris@69
|
507 int overlap;
|
Chris@69
|
508 int start;
|
Chris@69
|
509 int loss_count;
|
Chris@69
|
510 int noise_based;
|
Chris@69
|
511 const opus_int16 *eBands;
|
Chris@69
|
512 SAVE_STACK;
|
Chris@69
|
513
|
Chris@69
|
514 mode = st->mode;
|
Chris@69
|
515 nbEBands = mode->nbEBands;
|
Chris@69
|
516 overlap = mode->overlap;
|
Chris@69
|
517 eBands = mode->eBands;
|
Chris@69
|
518
|
Chris@69
|
519 c=0; do {
|
Chris@69
|
520 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap);
|
Chris@69
|
521 out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N;
|
Chris@69
|
522 } while (++c<C);
|
Chris@69
|
523 lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+overlap)*C);
|
Chris@69
|
524 oldBandE = lpc+C*LPC_ORDER;
|
Chris@69
|
525 oldLogE = oldBandE + 2*nbEBands;
|
Chris@69
|
526 oldLogE2 = oldLogE + 2*nbEBands;
|
Chris@69
|
527 backgroundLogE = oldLogE2 + 2*nbEBands;
|
Chris@69
|
528
|
Chris@69
|
529 loss_count = st->loss_count;
|
Chris@69
|
530 start = st->start;
|
Chris@69
|
531 noise_based = loss_count >= 5 || start != 0 || st->skip_plc;
|
Chris@69
|
532 if (noise_based)
|
Chris@69
|
533 {
|
Chris@69
|
534 /* Noise-based PLC/CNG */
|
Chris@69
|
535 #ifdef NORM_ALIASING_HACK
|
Chris@69
|
536 celt_norm *X;
|
Chris@69
|
537 #else
|
Chris@69
|
538 VARDECL(celt_norm, X);
|
Chris@69
|
539 #endif
|
Chris@69
|
540 opus_uint32 seed;
|
Chris@69
|
541 int end;
|
Chris@69
|
542 int effEnd;
|
Chris@69
|
543 opus_val16 decay;
|
Chris@69
|
544 end = st->end;
|
Chris@69
|
545 effEnd = IMAX(start, IMIN(end, mode->effEBands));
|
Chris@69
|
546
|
Chris@69
|
547 #ifdef NORM_ALIASING_HACK
|
Chris@69
|
548 /* This is an ugly hack that breaks aliasing rules and would be easily broken,
|
Chris@69
|
549 but it saves almost 4kB of stack. */
|
Chris@69
|
550 X = (celt_norm*)(out_syn[C-1]+overlap/2);
|
Chris@69
|
551 #else
|
Chris@69
|
552 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
|
Chris@69
|
553 #endif
|
Chris@69
|
554
|
Chris@69
|
555 /* Energy decay */
|
Chris@69
|
556 decay = loss_count==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT);
|
Chris@69
|
557 c=0; do
|
Chris@69
|
558 {
|
Chris@69
|
559 for (i=start;i<end;i++)
|
Chris@69
|
560 oldBandE[c*nbEBands+i] = MAX16(backgroundLogE[c*nbEBands+i], oldBandE[c*nbEBands+i] - decay);
|
Chris@69
|
561 } while (++c<C);
|
Chris@69
|
562 seed = st->rng;
|
Chris@69
|
563 for (c=0;c<C;c++)
|
Chris@69
|
564 {
|
Chris@69
|
565 for (i=start;i<effEnd;i++)
|
Chris@69
|
566 {
|
Chris@69
|
567 int j;
|
Chris@69
|
568 int boffs;
|
Chris@69
|
569 int blen;
|
Chris@69
|
570 boffs = N*c+(eBands[i]<<LM);
|
Chris@69
|
571 blen = (eBands[i+1]-eBands[i])<<LM;
|
Chris@69
|
572 for (j=0;j<blen;j++)
|
Chris@69
|
573 {
|
Chris@69
|
574 seed = celt_lcg_rand(seed);
|
Chris@69
|
575 X[boffs+j] = (celt_norm)((opus_int32)seed>>20);
|
Chris@69
|
576 }
|
Chris@69
|
577 renormalise_vector(X+boffs, blen, Q15ONE, st->arch);
|
Chris@69
|
578 }
|
Chris@69
|
579 }
|
Chris@69
|
580 st->rng = seed;
|
Chris@69
|
581
|
Chris@69
|
582 c=0; do {
|
Chris@69
|
583 OPUS_MOVE(decode_mem[c], decode_mem[c]+N,
|
Chris@69
|
584 DECODE_BUFFER_SIZE-N+(overlap>>1));
|
Chris@69
|
585 } while (++c<C);
|
Chris@69
|
586
|
Chris@69
|
587 celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, C, C, 0, LM, st->downsample, 0, st->arch);
|
Chris@69
|
588 } else {
|
Chris@69
|
589 int exc_length;
|
Chris@69
|
590 /* Pitch-based PLC */
|
Chris@69
|
591 const opus_val16 *window;
|
Chris@69
|
592 opus_val16 *exc;
|
Chris@69
|
593 opus_val16 fade = Q15ONE;
|
Chris@69
|
594 int pitch_index;
|
Chris@69
|
595 VARDECL(opus_val32, etmp);
|
Chris@69
|
596 VARDECL(opus_val16, _exc);
|
Chris@69
|
597 VARDECL(opus_val16, fir_tmp);
|
Chris@69
|
598
|
Chris@69
|
599 if (loss_count == 0)
|
Chris@69
|
600 {
|
Chris@69
|
601 st->last_pitch_index = pitch_index = celt_plc_pitch_search(decode_mem, C, st->arch);
|
Chris@69
|
602 } else {
|
Chris@69
|
603 pitch_index = st->last_pitch_index;
|
Chris@69
|
604 fade = QCONST16(.8f,15);
|
Chris@69
|
605 }
|
Chris@69
|
606
|
Chris@69
|
607 /* We want the excitation for 2 pitch periods in order to look for a
|
Chris@69
|
608 decaying signal, but we can't get more than MAX_PERIOD. */
|
Chris@69
|
609 exc_length = IMIN(2*pitch_index, MAX_PERIOD);
|
Chris@69
|
610
|
Chris@69
|
611 ALLOC(etmp, overlap, opus_val32);
|
Chris@69
|
612 ALLOC(_exc, MAX_PERIOD+LPC_ORDER, opus_val16);
|
Chris@69
|
613 ALLOC(fir_tmp, exc_length, opus_val16);
|
Chris@69
|
614 exc = _exc+LPC_ORDER;
|
Chris@69
|
615 window = mode->window;
|
Chris@69
|
616 c=0; do {
|
Chris@69
|
617 opus_val16 decay;
|
Chris@69
|
618 opus_val16 attenuation;
|
Chris@69
|
619 opus_val32 S1=0;
|
Chris@69
|
620 celt_sig *buf;
|
Chris@69
|
621 int extrapolation_offset;
|
Chris@69
|
622 int extrapolation_len;
|
Chris@69
|
623 int j;
|
Chris@69
|
624
|
Chris@69
|
625 buf = decode_mem[c];
|
Chris@69
|
626 for (i=0;i<MAX_PERIOD+LPC_ORDER;i++)
|
Chris@69
|
627 exc[i-LPC_ORDER] = ROUND16(buf[DECODE_BUFFER_SIZE-MAX_PERIOD-LPC_ORDER+i], SIG_SHIFT);
|
Chris@69
|
628
|
Chris@69
|
629 if (loss_count == 0)
|
Chris@69
|
630 {
|
Chris@69
|
631 opus_val32 ac[LPC_ORDER+1];
|
Chris@69
|
632 /* Compute LPC coefficients for the last MAX_PERIOD samples before
|
Chris@69
|
633 the first loss so we can work in the excitation-filter domain. */
|
Chris@69
|
634 _celt_autocorr(exc, ac, window, overlap,
|
Chris@69
|
635 LPC_ORDER, MAX_PERIOD, st->arch);
|
Chris@69
|
636 /* Add a noise floor of -40 dB. */
|
Chris@69
|
637 #ifdef FIXED_POINT
|
Chris@69
|
638 ac[0] += SHR32(ac[0],13);
|
Chris@69
|
639 #else
|
Chris@69
|
640 ac[0] *= 1.0001f;
|
Chris@69
|
641 #endif
|
Chris@69
|
642 /* Use lag windowing to stabilize the Levinson-Durbin recursion. */
|
Chris@69
|
643 for (i=1;i<=LPC_ORDER;i++)
|
Chris@69
|
644 {
|
Chris@69
|
645 /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
|
Chris@69
|
646 #ifdef FIXED_POINT
|
Chris@69
|
647 ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);
|
Chris@69
|
648 #else
|
Chris@69
|
649 ac[i] -= ac[i]*(0.008f*0.008f)*i*i;
|
Chris@69
|
650 #endif
|
Chris@69
|
651 }
|
Chris@69
|
652 _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
|
Chris@69
|
653 #ifdef FIXED_POINT
|
Chris@69
|
654 /* For fixed-point, apply bandwidth expansion until we can guarantee that
|
Chris@69
|
655 no overflow can happen in the IIR filter. This means:
|
Chris@69
|
656 32768*sum(abs(filter)) < 2^31 */
|
Chris@69
|
657 while (1) {
|
Chris@69
|
658 opus_val16 tmp=Q15ONE;
|
Chris@69
|
659 opus_val32 sum=QCONST16(1., SIG_SHIFT);
|
Chris@69
|
660 for (i=0;i<LPC_ORDER;i++)
|
Chris@69
|
661 sum += ABS16(lpc[c*LPC_ORDER+i]);
|
Chris@69
|
662 if (sum < 65535) break;
|
Chris@69
|
663 for (i=0;i<LPC_ORDER;i++)
|
Chris@69
|
664 {
|
Chris@69
|
665 tmp = MULT16_16_Q15(QCONST16(.99f,15), tmp);
|
Chris@69
|
666 lpc[c*LPC_ORDER+i] = MULT16_16_Q15(lpc[c*LPC_ORDER+i], tmp);
|
Chris@69
|
667 }
|
Chris@69
|
668 }
|
Chris@69
|
669 #endif
|
Chris@69
|
670 }
|
Chris@69
|
671 /* Initialize the LPC history with the samples just before the start
|
Chris@69
|
672 of the region for which we're computing the excitation. */
|
Chris@69
|
673 {
|
Chris@69
|
674 /* Compute the excitation for exc_length samples before the loss. We need the copy
|
Chris@69
|
675 because celt_fir() cannot filter in-place. */
|
Chris@69
|
676 celt_fir(exc+MAX_PERIOD-exc_length, lpc+c*LPC_ORDER,
|
Chris@69
|
677 fir_tmp, exc_length, LPC_ORDER, st->arch);
|
Chris@69
|
678 OPUS_COPY(exc+MAX_PERIOD-exc_length, fir_tmp, exc_length);
|
Chris@69
|
679 }
|
Chris@69
|
680
|
Chris@69
|
681 /* Check if the waveform is decaying, and if so how fast.
|
Chris@69
|
682 We do this to avoid adding energy when concealing in a segment
|
Chris@69
|
683 with decaying energy. */
|
Chris@69
|
684 {
|
Chris@69
|
685 opus_val32 E1=1, E2=1;
|
Chris@69
|
686 int decay_length;
|
Chris@69
|
687 #ifdef FIXED_POINT
|
Chris@69
|
688 int shift = IMAX(0,2*celt_zlog2(celt_maxabs16(&exc[MAX_PERIOD-exc_length], exc_length))-20);
|
Chris@69
|
689 #endif
|
Chris@69
|
690 decay_length = exc_length>>1;
|
Chris@69
|
691 for (i=0;i<decay_length;i++)
|
Chris@69
|
692 {
|
Chris@69
|
693 opus_val16 e;
|
Chris@69
|
694 e = exc[MAX_PERIOD-decay_length+i];
|
Chris@69
|
695 E1 += SHR32(MULT16_16(e, e), shift);
|
Chris@69
|
696 e = exc[MAX_PERIOD-2*decay_length+i];
|
Chris@69
|
697 E2 += SHR32(MULT16_16(e, e), shift);
|
Chris@69
|
698 }
|
Chris@69
|
699 E1 = MIN32(E1, E2);
|
Chris@69
|
700 decay = celt_sqrt(frac_div32(SHR32(E1, 1), E2));
|
Chris@69
|
701 }
|
Chris@69
|
702
|
Chris@69
|
703 /* Move the decoder memory one frame to the left to give us room to
|
Chris@69
|
704 add the data for the new frame. We ignore the overlap that extends
|
Chris@69
|
705 past the end of the buffer, because we aren't going to use it. */
|
Chris@69
|
706 OPUS_MOVE(buf, buf+N, DECODE_BUFFER_SIZE-N);
|
Chris@69
|
707
|
Chris@69
|
708 /* Extrapolate from the end of the excitation with a period of
|
Chris@69
|
709 "pitch_index", scaling down each period by an additional factor of
|
Chris@69
|
710 "decay". */
|
Chris@69
|
711 extrapolation_offset = MAX_PERIOD-pitch_index;
|
Chris@69
|
712 /* We need to extrapolate enough samples to cover a complete MDCT
|
Chris@69
|
713 window (including overlap/2 samples on both sides). */
|
Chris@69
|
714 extrapolation_len = N+overlap;
|
Chris@69
|
715 /* We also apply fading if this is not the first loss. */
|
Chris@69
|
716 attenuation = MULT16_16_Q15(fade, decay);
|
Chris@69
|
717 for (i=j=0;i<extrapolation_len;i++,j++)
|
Chris@69
|
718 {
|
Chris@69
|
719 opus_val16 tmp;
|
Chris@69
|
720 if (j >= pitch_index) {
|
Chris@69
|
721 j -= pitch_index;
|
Chris@69
|
722 attenuation = MULT16_16_Q15(attenuation, decay);
|
Chris@69
|
723 }
|
Chris@69
|
724 buf[DECODE_BUFFER_SIZE-N+i] =
|
Chris@69
|
725 SHL32(EXTEND32(MULT16_16_Q15(attenuation,
|
Chris@69
|
726 exc[extrapolation_offset+j])), SIG_SHIFT);
|
Chris@69
|
727 /* Compute the energy of the previously decoded signal whose
|
Chris@69
|
728 excitation we're copying. */
|
Chris@69
|
729 tmp = ROUND16(
|
Chris@69
|
730 buf[DECODE_BUFFER_SIZE-MAX_PERIOD-N+extrapolation_offset+j],
|
Chris@69
|
731 SIG_SHIFT);
|
Chris@69
|
732 S1 += SHR32(MULT16_16(tmp, tmp), 10);
|
Chris@69
|
733 }
|
Chris@69
|
734 {
|
Chris@69
|
735 opus_val16 lpc_mem[LPC_ORDER];
|
Chris@69
|
736 /* Copy the last decoded samples (prior to the overlap region) to
|
Chris@69
|
737 synthesis filter memory so we can have a continuous signal. */
|
Chris@69
|
738 for (i=0;i<LPC_ORDER;i++)
|
Chris@69
|
739 lpc_mem[i] = ROUND16(buf[DECODE_BUFFER_SIZE-N-1-i], SIG_SHIFT);
|
Chris@69
|
740 /* Apply the synthesis filter to convert the excitation back into
|
Chris@69
|
741 the signal domain. */
|
Chris@69
|
742 celt_iir(buf+DECODE_BUFFER_SIZE-N, lpc+c*LPC_ORDER,
|
Chris@69
|
743 buf+DECODE_BUFFER_SIZE-N, extrapolation_len, LPC_ORDER,
|
Chris@69
|
744 lpc_mem, st->arch);
|
Chris@69
|
745 #ifdef FIXED_POINT
|
Chris@69
|
746 for (i=0; i < extrapolation_len; i++)
|
Chris@69
|
747 buf[DECODE_BUFFER_SIZE-N+i] = SATURATE(buf[DECODE_BUFFER_SIZE-N+i], SIG_SAT);
|
Chris@69
|
748 #endif
|
Chris@69
|
749 }
|
Chris@69
|
750
|
Chris@69
|
751 /* Check if the synthesis energy is higher than expected, which can
|
Chris@69
|
752 happen with the signal changes during our window. If so,
|
Chris@69
|
753 attenuate. */
|
Chris@69
|
754 {
|
Chris@69
|
755 opus_val32 S2=0;
|
Chris@69
|
756 for (i=0;i<extrapolation_len;i++)
|
Chris@69
|
757 {
|
Chris@69
|
758 opus_val16 tmp = ROUND16(buf[DECODE_BUFFER_SIZE-N+i], SIG_SHIFT);
|
Chris@69
|
759 S2 += SHR32(MULT16_16(tmp, tmp), 10);
|
Chris@69
|
760 }
|
Chris@69
|
761 /* This checks for an "explosion" in the synthesis. */
|
Chris@69
|
762 #ifdef FIXED_POINT
|
Chris@69
|
763 if (!(S1 > SHR32(S2,2)))
|
Chris@69
|
764 #else
|
Chris@69
|
765 /* The float test is written this way to catch NaNs in the output
|
Chris@69
|
766 of the IIR filter at the same time. */
|
Chris@69
|
767 if (!(S1 > 0.2f*S2))
|
Chris@69
|
768 #endif
|
Chris@69
|
769 {
|
Chris@69
|
770 for (i=0;i<extrapolation_len;i++)
|
Chris@69
|
771 buf[DECODE_BUFFER_SIZE-N+i] = 0;
|
Chris@69
|
772 } else if (S1 < S2)
|
Chris@69
|
773 {
|
Chris@69
|
774 opus_val16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
|
Chris@69
|
775 for (i=0;i<overlap;i++)
|
Chris@69
|
776 {
|
Chris@69
|
777 opus_val16 tmp_g = Q15ONE
|
Chris@69
|
778 - MULT16_16_Q15(window[i], Q15ONE-ratio);
|
Chris@69
|
779 buf[DECODE_BUFFER_SIZE-N+i] =
|
Chris@69
|
780 MULT16_32_Q15(tmp_g, buf[DECODE_BUFFER_SIZE-N+i]);
|
Chris@69
|
781 }
|
Chris@69
|
782 for (i=overlap;i<extrapolation_len;i++)
|
Chris@69
|
783 {
|
Chris@69
|
784 buf[DECODE_BUFFER_SIZE-N+i] =
|
Chris@69
|
785 MULT16_32_Q15(ratio, buf[DECODE_BUFFER_SIZE-N+i]);
|
Chris@69
|
786 }
|
Chris@69
|
787 }
|
Chris@69
|
788 }
|
Chris@69
|
789
|
Chris@69
|
790 /* Apply the pre-filter to the MDCT overlap for the next frame because
|
Chris@69
|
791 the post-filter will be re-applied in the decoder after the MDCT
|
Chris@69
|
792 overlap. */
|
Chris@69
|
793 comb_filter(etmp, buf+DECODE_BUFFER_SIZE,
|
Chris@69
|
794 st->postfilter_period, st->postfilter_period, overlap,
|
Chris@69
|
795 -st->postfilter_gain, -st->postfilter_gain,
|
Chris@69
|
796 st->postfilter_tapset, st->postfilter_tapset, NULL, 0, st->arch);
|
Chris@69
|
797
|
Chris@69
|
798 /* Simulate TDAC on the concealed audio so that it blends with the
|
Chris@69
|
799 MDCT of the next frame. */
|
Chris@69
|
800 for (i=0;i<overlap/2;i++)
|
Chris@69
|
801 {
|
Chris@69
|
802 buf[DECODE_BUFFER_SIZE+i] =
|
Chris@69
|
803 MULT16_32_Q15(window[i], etmp[overlap-1-i])
|
Chris@69
|
804 + MULT16_32_Q15(window[overlap-i-1], etmp[i]);
|
Chris@69
|
805 }
|
Chris@69
|
806 } while (++c<C);
|
Chris@69
|
807 }
|
Chris@69
|
808
|
Chris@69
|
809 st->loss_count = loss_count+1;
|
Chris@69
|
810
|
Chris@69
|
811 RESTORE_STACK;
|
Chris@69
|
812 }
|
Chris@69
|
813
|
Chris@69
|
814 int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data,
|
Chris@69
|
815 int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum)
|
Chris@69
|
816 {
|
Chris@69
|
817 int c, i, N;
|
Chris@69
|
818 int spread_decision;
|
Chris@69
|
819 opus_int32 bits;
|
Chris@69
|
820 ec_dec _dec;
|
Chris@69
|
821 #ifdef NORM_ALIASING_HACK
|
Chris@69
|
822 celt_norm *X;
|
Chris@69
|
823 #else
|
Chris@69
|
824 VARDECL(celt_norm, X);
|
Chris@69
|
825 #endif
|
Chris@69
|
826 VARDECL(int, fine_quant);
|
Chris@69
|
827 VARDECL(int, pulses);
|
Chris@69
|
828 VARDECL(int, cap);
|
Chris@69
|
829 VARDECL(int, offsets);
|
Chris@69
|
830 VARDECL(int, fine_priority);
|
Chris@69
|
831 VARDECL(int, tf_res);
|
Chris@69
|
832 VARDECL(unsigned char, collapse_masks);
|
Chris@69
|
833 celt_sig *decode_mem[2];
|
Chris@69
|
834 celt_sig *out_syn[2];
|
Chris@69
|
835 opus_val16 *lpc;
|
Chris@69
|
836 opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
|
Chris@69
|
837
|
Chris@69
|
838 int shortBlocks;
|
Chris@69
|
839 int isTransient;
|
Chris@69
|
840 int intra_ener;
|
Chris@69
|
841 const int CC = st->channels;
|
Chris@69
|
842 int LM, M;
|
Chris@69
|
843 int start;
|
Chris@69
|
844 int end;
|
Chris@69
|
845 int effEnd;
|
Chris@69
|
846 int codedBands;
|
Chris@69
|
847 int alloc_trim;
|
Chris@69
|
848 int postfilter_pitch;
|
Chris@69
|
849 opus_val16 postfilter_gain;
|
Chris@69
|
850 int intensity=0;
|
Chris@69
|
851 int dual_stereo=0;
|
Chris@69
|
852 opus_int32 total_bits;
|
Chris@69
|
853 opus_int32 balance;
|
Chris@69
|
854 opus_int32 tell;
|
Chris@69
|
855 int dynalloc_logp;
|
Chris@69
|
856 int postfilter_tapset;
|
Chris@69
|
857 int anti_collapse_rsv;
|
Chris@69
|
858 int anti_collapse_on=0;
|
Chris@69
|
859 int silence;
|
Chris@69
|
860 int C = st->stream_channels;
|
Chris@69
|
861 const OpusCustomMode *mode;
|
Chris@69
|
862 int nbEBands;
|
Chris@69
|
863 int overlap;
|
Chris@69
|
864 const opus_int16 *eBands;
|
Chris@69
|
865 ALLOC_STACK;
|
Chris@69
|
866
|
Chris@69
|
867 VALIDATE_CELT_DECODER(st);
|
Chris@69
|
868 mode = st->mode;
|
Chris@69
|
869 nbEBands = mode->nbEBands;
|
Chris@69
|
870 overlap = mode->overlap;
|
Chris@69
|
871 eBands = mode->eBands;
|
Chris@69
|
872 start = st->start;
|
Chris@69
|
873 end = st->end;
|
Chris@69
|
874 frame_size *= st->downsample;
|
Chris@69
|
875
|
Chris@69
|
876 lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+overlap)*CC);
|
Chris@69
|
877 oldBandE = lpc+CC*LPC_ORDER;
|
Chris@69
|
878 oldLogE = oldBandE + 2*nbEBands;
|
Chris@69
|
879 oldLogE2 = oldLogE + 2*nbEBands;
|
Chris@69
|
880 backgroundLogE = oldLogE2 + 2*nbEBands;
|
Chris@69
|
881
|
Chris@69
|
882 #ifdef CUSTOM_MODES
|
Chris@69
|
883 if (st->signalling && data!=NULL)
|
Chris@69
|
884 {
|
Chris@69
|
885 int data0=data[0];
|
Chris@69
|
886 /* Convert "standard mode" to Opus header */
|
Chris@69
|
887 if (mode->Fs==48000 && mode->shortMdctSize==120)
|
Chris@69
|
888 {
|
Chris@69
|
889 data0 = fromOpus(data0);
|
Chris@69
|
890 if (data0<0)
|
Chris@69
|
891 return OPUS_INVALID_PACKET;
|
Chris@69
|
892 }
|
Chris@69
|
893 st->end = end = IMAX(1, mode->effEBands-2*(data0>>5));
|
Chris@69
|
894 LM = (data0>>3)&0x3;
|
Chris@69
|
895 C = 1 + ((data0>>2)&0x1);
|
Chris@69
|
896 data++;
|
Chris@69
|
897 len--;
|
Chris@69
|
898 if (LM>mode->maxLM)
|
Chris@69
|
899 return OPUS_INVALID_PACKET;
|
Chris@69
|
900 if (frame_size < mode->shortMdctSize<<LM)
|
Chris@69
|
901 return OPUS_BUFFER_TOO_SMALL;
|
Chris@69
|
902 else
|
Chris@69
|
903 frame_size = mode->shortMdctSize<<LM;
|
Chris@69
|
904 } else {
|
Chris@69
|
905 #else
|
Chris@69
|
906 {
|
Chris@69
|
907 #endif
|
Chris@69
|
908 for (LM=0;LM<=mode->maxLM;LM++)
|
Chris@69
|
909 if (mode->shortMdctSize<<LM==frame_size)
|
Chris@69
|
910 break;
|
Chris@69
|
911 if (LM>mode->maxLM)
|
Chris@69
|
912 return OPUS_BAD_ARG;
|
Chris@69
|
913 }
|
Chris@69
|
914 M=1<<LM;
|
Chris@69
|
915
|
Chris@69
|
916 if (len<0 || len>1275 || pcm==NULL)
|
Chris@69
|
917 return OPUS_BAD_ARG;
|
Chris@69
|
918
|
Chris@69
|
919 N = M*mode->shortMdctSize;
|
Chris@69
|
920 c=0; do {
|
Chris@69
|
921 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap);
|
Chris@69
|
922 out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N;
|
Chris@69
|
923 } while (++c<CC);
|
Chris@69
|
924
|
Chris@69
|
925 effEnd = end;
|
Chris@69
|
926 if (effEnd > mode->effEBands)
|
Chris@69
|
927 effEnd = mode->effEBands;
|
Chris@69
|
928
|
Chris@69
|
929 if (data == NULL || len<=1)
|
Chris@69
|
930 {
|
Chris@69
|
931 celt_decode_lost(st, N, LM);
|
Chris@69
|
932 deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum);
|
Chris@69
|
933 RESTORE_STACK;
|
Chris@69
|
934 return frame_size/st->downsample;
|
Chris@69
|
935 }
|
Chris@69
|
936
|
Chris@69
|
937 /* Check if there are at least two packets received consecutively before
|
Chris@69
|
938 * turning on the pitch-based PLC */
|
Chris@69
|
939 st->skip_plc = st->loss_count != 0;
|
Chris@69
|
940
|
Chris@69
|
941 if (dec == NULL)
|
Chris@69
|
942 {
|
Chris@69
|
943 ec_dec_init(&_dec,(unsigned char*)data,len);
|
Chris@69
|
944 dec = &_dec;
|
Chris@69
|
945 }
|
Chris@69
|
946
|
Chris@69
|
947 if (C==1)
|
Chris@69
|
948 {
|
Chris@69
|
949 for (i=0;i<nbEBands;i++)
|
Chris@69
|
950 oldBandE[i]=MAX16(oldBandE[i],oldBandE[nbEBands+i]);
|
Chris@69
|
951 }
|
Chris@69
|
952
|
Chris@69
|
953 total_bits = len*8;
|
Chris@69
|
954 tell = ec_tell(dec);
|
Chris@69
|
955
|
Chris@69
|
956 if (tell >= total_bits)
|
Chris@69
|
957 silence = 1;
|
Chris@69
|
958 else if (tell==1)
|
Chris@69
|
959 silence = ec_dec_bit_logp(dec, 15);
|
Chris@69
|
960 else
|
Chris@69
|
961 silence = 0;
|
Chris@69
|
962 if (silence)
|
Chris@69
|
963 {
|
Chris@69
|
964 /* Pretend we've read all the remaining bits */
|
Chris@69
|
965 tell = len*8;
|
Chris@69
|
966 dec->nbits_total+=tell-ec_tell(dec);
|
Chris@69
|
967 }
|
Chris@69
|
968
|
Chris@69
|
969 postfilter_gain = 0;
|
Chris@69
|
970 postfilter_pitch = 0;
|
Chris@69
|
971 postfilter_tapset = 0;
|
Chris@69
|
972 if (start==0 && tell+16 <= total_bits)
|
Chris@69
|
973 {
|
Chris@69
|
974 if(ec_dec_bit_logp(dec, 1))
|
Chris@69
|
975 {
|
Chris@69
|
976 int qg, octave;
|
Chris@69
|
977 octave = ec_dec_uint(dec, 6);
|
Chris@69
|
978 postfilter_pitch = (16<<octave)+ec_dec_bits(dec, 4+octave)-1;
|
Chris@69
|
979 qg = ec_dec_bits(dec, 3);
|
Chris@69
|
980 if (ec_tell(dec)+2<=total_bits)
|
Chris@69
|
981 postfilter_tapset = ec_dec_icdf(dec, tapset_icdf, 2);
|
Chris@69
|
982 postfilter_gain = QCONST16(.09375f,15)*(qg+1);
|
Chris@69
|
983 }
|
Chris@69
|
984 tell = ec_tell(dec);
|
Chris@69
|
985 }
|
Chris@69
|
986
|
Chris@69
|
987 if (LM > 0 && tell+3 <= total_bits)
|
Chris@69
|
988 {
|
Chris@69
|
989 isTransient = ec_dec_bit_logp(dec, 3);
|
Chris@69
|
990 tell = ec_tell(dec);
|
Chris@69
|
991 }
|
Chris@69
|
992 else
|
Chris@69
|
993 isTransient = 0;
|
Chris@69
|
994
|
Chris@69
|
995 if (isTransient)
|
Chris@69
|
996 shortBlocks = M;
|
Chris@69
|
997 else
|
Chris@69
|
998 shortBlocks = 0;
|
Chris@69
|
999
|
Chris@69
|
1000 /* Decode the global flags (first symbols in the stream) */
|
Chris@69
|
1001 intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0;
|
Chris@69
|
1002 /* Get band energies */
|
Chris@69
|
1003 unquant_coarse_energy(mode, start, end, oldBandE,
|
Chris@69
|
1004 intra_ener, dec, C, LM);
|
Chris@69
|
1005
|
Chris@69
|
1006 ALLOC(tf_res, nbEBands, int);
|
Chris@69
|
1007 tf_decode(start, end, isTransient, tf_res, LM, dec);
|
Chris@69
|
1008
|
Chris@69
|
1009 tell = ec_tell(dec);
|
Chris@69
|
1010 spread_decision = SPREAD_NORMAL;
|
Chris@69
|
1011 if (tell+4 <= total_bits)
|
Chris@69
|
1012 spread_decision = ec_dec_icdf(dec, spread_icdf, 5);
|
Chris@69
|
1013
|
Chris@69
|
1014 ALLOC(cap, nbEBands, int);
|
Chris@69
|
1015
|
Chris@69
|
1016 init_caps(mode,cap,LM,C);
|
Chris@69
|
1017
|
Chris@69
|
1018 ALLOC(offsets, nbEBands, int);
|
Chris@69
|
1019
|
Chris@69
|
1020 dynalloc_logp = 6;
|
Chris@69
|
1021 total_bits<<=BITRES;
|
Chris@69
|
1022 tell = ec_tell_frac(dec);
|
Chris@69
|
1023 for (i=start;i<end;i++)
|
Chris@69
|
1024 {
|
Chris@69
|
1025 int width, quanta;
|
Chris@69
|
1026 int dynalloc_loop_logp;
|
Chris@69
|
1027 int boost;
|
Chris@69
|
1028 width = C*(eBands[i+1]-eBands[i])<<LM;
|
Chris@69
|
1029 /* quanta is 6 bits, but no more than 1 bit/sample
|
Chris@69
|
1030 and no less than 1/8 bit/sample */
|
Chris@69
|
1031 quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));
|
Chris@69
|
1032 dynalloc_loop_logp = dynalloc_logp;
|
Chris@69
|
1033 boost = 0;
|
Chris@69
|
1034 while (tell+(dynalloc_loop_logp<<BITRES) < total_bits && boost < cap[i])
|
Chris@69
|
1035 {
|
Chris@69
|
1036 int flag;
|
Chris@69
|
1037 flag = ec_dec_bit_logp(dec, dynalloc_loop_logp);
|
Chris@69
|
1038 tell = ec_tell_frac(dec);
|
Chris@69
|
1039 if (!flag)
|
Chris@69
|
1040 break;
|
Chris@69
|
1041 boost += quanta;
|
Chris@69
|
1042 total_bits -= quanta;
|
Chris@69
|
1043 dynalloc_loop_logp = 1;
|
Chris@69
|
1044 }
|
Chris@69
|
1045 offsets[i] = boost;
|
Chris@69
|
1046 /* Making dynalloc more likely */
|
Chris@69
|
1047 if (boost>0)
|
Chris@69
|
1048 dynalloc_logp = IMAX(2, dynalloc_logp-1);
|
Chris@69
|
1049 }
|
Chris@69
|
1050
|
Chris@69
|
1051 ALLOC(fine_quant, nbEBands, int);
|
Chris@69
|
1052 alloc_trim = tell+(6<<BITRES) <= total_bits ?
|
Chris@69
|
1053 ec_dec_icdf(dec, trim_icdf, 7) : 5;
|
Chris@69
|
1054
|
Chris@69
|
1055 bits = (((opus_int32)len*8)<<BITRES) - ec_tell_frac(dec) - 1;
|
Chris@69
|
1056 anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0;
|
Chris@69
|
1057 bits -= anti_collapse_rsv;
|
Chris@69
|
1058
|
Chris@69
|
1059 ALLOC(pulses, nbEBands, int);
|
Chris@69
|
1060 ALLOC(fine_priority, nbEBands, int);
|
Chris@69
|
1061
|
Chris@69
|
1062 codedBands = clt_compute_allocation(mode, start, end, offsets, cap,
|
Chris@69
|
1063 alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
|
Chris@69
|
1064 fine_quant, fine_priority, C, LM, dec, 0, 0, 0);
|
Chris@69
|
1065
|
Chris@69
|
1066 unquant_fine_energy(mode, start, end, oldBandE, fine_quant, dec, C);
|
Chris@69
|
1067
|
Chris@69
|
1068 c=0; do {
|
Chris@69
|
1069 OPUS_MOVE(decode_mem[c], decode_mem[c]+N, DECODE_BUFFER_SIZE-N+overlap/2);
|
Chris@69
|
1070 } while (++c<CC);
|
Chris@69
|
1071
|
Chris@69
|
1072 /* Decode fixed codebook */
|
Chris@69
|
1073 ALLOC(collapse_masks, C*nbEBands, unsigned char);
|
Chris@69
|
1074
|
Chris@69
|
1075 #ifdef NORM_ALIASING_HACK
|
Chris@69
|
1076 /* This is an ugly hack that breaks aliasing rules and would be easily broken,
|
Chris@69
|
1077 but it saves almost 4kB of stack. */
|
Chris@69
|
1078 X = (celt_norm*)(out_syn[CC-1]+overlap/2);
|
Chris@69
|
1079 #else
|
Chris@69
|
1080 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
|
Chris@69
|
1081 #endif
|
Chris@69
|
1082
|
Chris@69
|
1083 quant_all_bands(0, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks,
|
Chris@69
|
1084 NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res,
|
Chris@69
|
1085 len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng, 0,
|
Chris@69
|
1086 st->arch, st->disable_inv);
|
Chris@69
|
1087
|
Chris@69
|
1088 if (anti_collapse_rsv > 0)
|
Chris@69
|
1089 {
|
Chris@69
|
1090 anti_collapse_on = ec_dec_bits(dec, 1);
|
Chris@69
|
1091 }
|
Chris@69
|
1092
|
Chris@69
|
1093 unquant_energy_finalise(mode, start, end, oldBandE,
|
Chris@69
|
1094 fine_quant, fine_priority, len*8-ec_tell(dec), dec, C);
|
Chris@69
|
1095
|
Chris@69
|
1096 if (anti_collapse_on)
|
Chris@69
|
1097 anti_collapse(mode, X, collapse_masks, LM, C, N,
|
Chris@69
|
1098 start, end, oldBandE, oldLogE, oldLogE2, pulses, st->rng, st->arch);
|
Chris@69
|
1099
|
Chris@69
|
1100 if (silence)
|
Chris@69
|
1101 {
|
Chris@69
|
1102 for (i=0;i<C*nbEBands;i++)
|
Chris@69
|
1103 oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
|
Chris@69
|
1104 }
|
Chris@69
|
1105
|
Chris@69
|
1106 celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd,
|
Chris@69
|
1107 C, CC, isTransient, LM, st->downsample, silence, st->arch);
|
Chris@69
|
1108
|
Chris@69
|
1109 c=0; do {
|
Chris@69
|
1110 st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD);
|
Chris@69
|
1111 st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD);
|
Chris@69
|
1112 comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, mode->shortMdctSize,
|
Chris@69
|
1113 st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset,
|
Chris@69
|
1114 mode->window, overlap, st->arch);
|
Chris@69
|
1115 if (LM!=0)
|
Chris@69
|
1116 comb_filter(out_syn[c]+mode->shortMdctSize, out_syn[c]+mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-mode->shortMdctSize,
|
Chris@69
|
1117 st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset,
|
Chris@69
|
1118 mode->window, overlap, st->arch);
|
Chris@69
|
1119
|
Chris@69
|
1120 } while (++c<CC);
|
Chris@69
|
1121 st->postfilter_period_old = st->postfilter_period;
|
Chris@69
|
1122 st->postfilter_gain_old = st->postfilter_gain;
|
Chris@69
|
1123 st->postfilter_tapset_old = st->postfilter_tapset;
|
Chris@69
|
1124 st->postfilter_period = postfilter_pitch;
|
Chris@69
|
1125 st->postfilter_gain = postfilter_gain;
|
Chris@69
|
1126 st->postfilter_tapset = postfilter_tapset;
|
Chris@69
|
1127 if (LM!=0)
|
Chris@69
|
1128 {
|
Chris@69
|
1129 st->postfilter_period_old = st->postfilter_period;
|
Chris@69
|
1130 st->postfilter_gain_old = st->postfilter_gain;
|
Chris@69
|
1131 st->postfilter_tapset_old = st->postfilter_tapset;
|
Chris@69
|
1132 }
|
Chris@69
|
1133
|
Chris@69
|
1134 if (C==1)
|
Chris@69
|
1135 OPUS_COPY(&oldBandE[nbEBands], oldBandE, nbEBands);
|
Chris@69
|
1136
|
Chris@69
|
1137 /* In case start or end were to change */
|
Chris@69
|
1138 if (!isTransient)
|
Chris@69
|
1139 {
|
Chris@69
|
1140 opus_val16 max_background_increase;
|
Chris@69
|
1141 OPUS_COPY(oldLogE2, oldLogE, 2*nbEBands);
|
Chris@69
|
1142 OPUS_COPY(oldLogE, oldBandE, 2*nbEBands);
|
Chris@69
|
1143 /* In normal circumstances, we only allow the noise floor to increase by
|
Chris@69
|
1144 up to 2.4 dB/second, but when we're in DTX, we allow up to 6 dB
|
Chris@69
|
1145 increase for each update.*/
|
Chris@69
|
1146 if (st->loss_count < 10)
|
Chris@69
|
1147 max_background_increase = M*QCONST16(0.001f,DB_SHIFT);
|
Chris@69
|
1148 else
|
Chris@69
|
1149 max_background_increase = QCONST16(1.f,DB_SHIFT);
|
Chris@69
|
1150 for (i=0;i<2*nbEBands;i++)
|
Chris@69
|
1151 backgroundLogE[i] = MIN16(backgroundLogE[i] + max_background_increase, oldBandE[i]);
|
Chris@69
|
1152 } else {
|
Chris@69
|
1153 for (i=0;i<2*nbEBands;i++)
|
Chris@69
|
1154 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
|
Chris@69
|
1155 }
|
Chris@69
|
1156 c=0; do
|
Chris@69
|
1157 {
|
Chris@69
|
1158 for (i=0;i<start;i++)
|
Chris@69
|
1159 {
|
Chris@69
|
1160 oldBandE[c*nbEBands+i]=0;
|
Chris@69
|
1161 oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
|
Chris@69
|
1162 }
|
Chris@69
|
1163 for (i=end;i<nbEBands;i++)
|
Chris@69
|
1164 {
|
Chris@69
|
1165 oldBandE[c*nbEBands+i]=0;
|
Chris@69
|
1166 oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
|
Chris@69
|
1167 }
|
Chris@69
|
1168 } while (++c<2);
|
Chris@69
|
1169 st->rng = dec->rng;
|
Chris@69
|
1170
|
Chris@69
|
1171 deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum);
|
Chris@69
|
1172 st->loss_count = 0;
|
Chris@69
|
1173 RESTORE_STACK;
|
Chris@69
|
1174 if (ec_tell(dec) > 8*len)
|
Chris@69
|
1175 return OPUS_INTERNAL_ERROR;
|
Chris@69
|
1176 if(ec_get_error(dec))
|
Chris@69
|
1177 st->error = 1;
|
Chris@69
|
1178 return frame_size/st->downsample;
|
Chris@69
|
1179 }
|
Chris@69
|
1180
|
Chris@69
|
1181
|
Chris@69
|
1182 #ifdef CUSTOM_MODES
|
Chris@69
|
1183
|
Chris@69
|
1184 #ifdef FIXED_POINT
|
Chris@69
|
1185 int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size)
|
Chris@69
|
1186 {
|
Chris@69
|
1187 return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0);
|
Chris@69
|
1188 }
|
Chris@69
|
1189
|
Chris@69
|
1190 #ifndef DISABLE_FLOAT_API
|
Chris@69
|
1191 int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size)
|
Chris@69
|
1192 {
|
Chris@69
|
1193 int j, ret, C, N;
|
Chris@69
|
1194 VARDECL(opus_int16, out);
|
Chris@69
|
1195 ALLOC_STACK;
|
Chris@69
|
1196
|
Chris@69
|
1197 if (pcm==NULL)
|
Chris@69
|
1198 return OPUS_BAD_ARG;
|
Chris@69
|
1199
|
Chris@69
|
1200 C = st->channels;
|
Chris@69
|
1201 N = frame_size;
|
Chris@69
|
1202
|
Chris@69
|
1203 ALLOC(out, C*N, opus_int16);
|
Chris@69
|
1204 ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0);
|
Chris@69
|
1205 if (ret>0)
|
Chris@69
|
1206 for (j=0;j<C*ret;j++)
|
Chris@69
|
1207 pcm[j]=out[j]*(1.f/32768.f);
|
Chris@69
|
1208
|
Chris@69
|
1209 RESTORE_STACK;
|
Chris@69
|
1210 return ret;
|
Chris@69
|
1211 }
|
Chris@69
|
1212 #endif /* DISABLE_FLOAT_API */
|
Chris@69
|
1213
|
Chris@69
|
1214 #else
|
Chris@69
|
1215
|
Chris@69
|
1216 int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size)
|
Chris@69
|
1217 {
|
Chris@69
|
1218 return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0);
|
Chris@69
|
1219 }
|
Chris@69
|
1220
|
Chris@69
|
1221 int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size)
|
Chris@69
|
1222 {
|
Chris@69
|
1223 int j, ret, C, N;
|
Chris@69
|
1224 VARDECL(celt_sig, out);
|
Chris@69
|
1225 ALLOC_STACK;
|
Chris@69
|
1226
|
Chris@69
|
1227 if (pcm==NULL)
|
Chris@69
|
1228 return OPUS_BAD_ARG;
|
Chris@69
|
1229
|
Chris@69
|
1230 C = st->channels;
|
Chris@69
|
1231 N = frame_size;
|
Chris@69
|
1232 ALLOC(out, C*N, celt_sig);
|
Chris@69
|
1233
|
Chris@69
|
1234 ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0);
|
Chris@69
|
1235
|
Chris@69
|
1236 if (ret>0)
|
Chris@69
|
1237 for (j=0;j<C*ret;j++)
|
Chris@69
|
1238 pcm[j] = FLOAT2INT16 (out[j]);
|
Chris@69
|
1239
|
Chris@69
|
1240 RESTORE_STACK;
|
Chris@69
|
1241 return ret;
|
Chris@69
|
1242 }
|
Chris@69
|
1243
|
Chris@69
|
1244 #endif
|
Chris@69
|
1245 #endif /* CUSTOM_MODES */
|
Chris@69
|
1246
|
Chris@69
|
1247 int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
|
Chris@69
|
1248 {
|
Chris@69
|
1249 va_list ap;
|
Chris@69
|
1250
|
Chris@69
|
1251 va_start(ap, request);
|
Chris@69
|
1252 switch (request)
|
Chris@69
|
1253 {
|
Chris@69
|
1254 case CELT_SET_START_BAND_REQUEST:
|
Chris@69
|
1255 {
|
Chris@69
|
1256 opus_int32 value = va_arg(ap, opus_int32);
|
Chris@69
|
1257 if (value<0 || value>=st->mode->nbEBands)
|
Chris@69
|
1258 goto bad_arg;
|
Chris@69
|
1259 st->start = value;
|
Chris@69
|
1260 }
|
Chris@69
|
1261 break;
|
Chris@69
|
1262 case CELT_SET_END_BAND_REQUEST:
|
Chris@69
|
1263 {
|
Chris@69
|
1264 opus_int32 value = va_arg(ap, opus_int32);
|
Chris@69
|
1265 if (value<1 || value>st->mode->nbEBands)
|
Chris@69
|
1266 goto bad_arg;
|
Chris@69
|
1267 st->end = value;
|
Chris@69
|
1268 }
|
Chris@69
|
1269 break;
|
Chris@69
|
1270 case CELT_SET_CHANNELS_REQUEST:
|
Chris@69
|
1271 {
|
Chris@69
|
1272 opus_int32 value = va_arg(ap, opus_int32);
|
Chris@69
|
1273 if (value<1 || value>2)
|
Chris@69
|
1274 goto bad_arg;
|
Chris@69
|
1275 st->stream_channels = value;
|
Chris@69
|
1276 }
|
Chris@69
|
1277 break;
|
Chris@69
|
1278 case CELT_GET_AND_CLEAR_ERROR_REQUEST:
|
Chris@69
|
1279 {
|
Chris@69
|
1280 opus_int32 *value = va_arg(ap, opus_int32*);
|
Chris@69
|
1281 if (value==NULL)
|
Chris@69
|
1282 goto bad_arg;
|
Chris@69
|
1283 *value=st->error;
|
Chris@69
|
1284 st->error = 0;
|
Chris@69
|
1285 }
|
Chris@69
|
1286 break;
|
Chris@69
|
1287 case OPUS_GET_LOOKAHEAD_REQUEST:
|
Chris@69
|
1288 {
|
Chris@69
|
1289 opus_int32 *value = va_arg(ap, opus_int32*);
|
Chris@69
|
1290 if (value==NULL)
|
Chris@69
|
1291 goto bad_arg;
|
Chris@69
|
1292 *value = st->overlap/st->downsample;
|
Chris@69
|
1293 }
|
Chris@69
|
1294 break;
|
Chris@69
|
1295 case OPUS_RESET_STATE:
|
Chris@69
|
1296 {
|
Chris@69
|
1297 int i;
|
Chris@69
|
1298 opus_val16 *lpc, *oldBandE, *oldLogE, *oldLogE2;
|
Chris@69
|
1299 lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels);
|
Chris@69
|
1300 oldBandE = lpc+st->channels*LPC_ORDER;
|
Chris@69
|
1301 oldLogE = oldBandE + 2*st->mode->nbEBands;
|
Chris@69
|
1302 oldLogE2 = oldLogE + 2*st->mode->nbEBands;
|
Chris@69
|
1303 OPUS_CLEAR((char*)&st->DECODER_RESET_START,
|
Chris@69
|
1304 opus_custom_decoder_get_size(st->mode, st->channels)-
|
Chris@69
|
1305 ((char*)&st->DECODER_RESET_START - (char*)st));
|
Chris@69
|
1306 for (i=0;i<2*st->mode->nbEBands;i++)
|
Chris@69
|
1307 oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT);
|
Chris@69
|
1308 st->skip_plc = 1;
|
Chris@69
|
1309 }
|
Chris@69
|
1310 break;
|
Chris@69
|
1311 case OPUS_GET_PITCH_REQUEST:
|
Chris@69
|
1312 {
|
Chris@69
|
1313 opus_int32 *value = va_arg(ap, opus_int32*);
|
Chris@69
|
1314 if (value==NULL)
|
Chris@69
|
1315 goto bad_arg;
|
Chris@69
|
1316 *value = st->postfilter_period;
|
Chris@69
|
1317 }
|
Chris@69
|
1318 break;
|
Chris@69
|
1319 case CELT_GET_MODE_REQUEST:
|
Chris@69
|
1320 {
|
Chris@69
|
1321 const CELTMode ** value = va_arg(ap, const CELTMode**);
|
Chris@69
|
1322 if (value==0)
|
Chris@69
|
1323 goto bad_arg;
|
Chris@69
|
1324 *value=st->mode;
|
Chris@69
|
1325 }
|
Chris@69
|
1326 break;
|
Chris@69
|
1327 case CELT_SET_SIGNALLING_REQUEST:
|
Chris@69
|
1328 {
|
Chris@69
|
1329 opus_int32 value = va_arg(ap, opus_int32);
|
Chris@69
|
1330 st->signalling = value;
|
Chris@69
|
1331 }
|
Chris@69
|
1332 break;
|
Chris@69
|
1333 case OPUS_GET_FINAL_RANGE_REQUEST:
|
Chris@69
|
1334 {
|
Chris@69
|
1335 opus_uint32 * value = va_arg(ap, opus_uint32 *);
|
Chris@69
|
1336 if (value==0)
|
Chris@69
|
1337 goto bad_arg;
|
Chris@69
|
1338 *value=st->rng;
|
Chris@69
|
1339 }
|
Chris@69
|
1340 break;
|
Chris@69
|
1341 case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
|
Chris@69
|
1342 {
|
Chris@69
|
1343 opus_int32 value = va_arg(ap, opus_int32);
|
Chris@69
|
1344 if(value<0 || value>1)
|
Chris@69
|
1345 {
|
Chris@69
|
1346 goto bad_arg;
|
Chris@69
|
1347 }
|
Chris@69
|
1348 st->disable_inv = value;
|
Chris@69
|
1349 }
|
Chris@69
|
1350 break;
|
Chris@69
|
1351 case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
|
Chris@69
|
1352 {
|
Chris@69
|
1353 opus_int32 *value = va_arg(ap, opus_int32*);
|
Chris@69
|
1354 if (!value)
|
Chris@69
|
1355 {
|
Chris@69
|
1356 goto bad_arg;
|
Chris@69
|
1357 }
|
Chris@69
|
1358 *value = st->disable_inv;
|
Chris@69
|
1359 }
|
Chris@69
|
1360 break;
|
Chris@69
|
1361 default:
|
Chris@69
|
1362 goto bad_request;
|
Chris@69
|
1363 }
|
Chris@69
|
1364 va_end(ap);
|
Chris@69
|
1365 return OPUS_OK;
|
Chris@69
|
1366 bad_arg:
|
Chris@69
|
1367 va_end(ap);
|
Chris@69
|
1368 return OPUS_BAD_ARG;
|
Chris@69
|
1369 bad_request:
|
Chris@69
|
1370 va_end(ap);
|
Chris@69
|
1371 return OPUS_UNIMPLEMENTED;
|
Chris@69
|
1372 }
|