blob: 919ba521b56046d2ba081f387ded1a46f942120c [file] [log] [blame]
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +00001/* Copyright (c) 2010 Xiph.Org Foundation, Skype Limited
2 Written by Jean-Marc Valin and Koen Vos */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
tlegrand@google.com3c3902f2013-12-09 08:35:25 +000029# include "config.h"
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +000030#endif
31
32#ifndef OPUS_BUILD
tlegrand@google.com3c3902f2013-12-09 08:35:25 +000033# error "OPUS_BUILD _MUST_ be defined to build Opus. This probably means you need other defines as well, as in a config.h. See the included build files for details."
34#endif
35
36#if defined(__GNUC__) && (__GNUC__ >= 2) && !defined(__OPTIMIZE__)
37# pragma message "You appear to be compiling without optimization, if so opus will be very slow."
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +000038#endif
39
40#include <stdarg.h>
41#include "celt.h"
42#include "opus.h"
43#include "entdec.h"
44#include "modes.h"
45#include "API.h"
46#include "stack_alloc.h"
47#include "float_cast.h"
48#include "opus_private.h"
49#include "os_support.h"
50#include "structs.h"
51#include "define.h"
52#include "mathops.h"
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +000053#include "cpu_support.h"
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +000054
55struct OpusDecoder {
56 int celt_dec_offset;
57 int silk_dec_offset;
58 int channels;
59 opus_int32 Fs; /** Sampling rate (at the API level) */
60 silk_DecControlStruct DecControl;
61 int decode_gain;
62
63 /* Everything beyond this point gets cleared on a reset */
64#define OPUS_DECODER_RESET_START stream_channels
65 int stream_channels;
66
67 int bandwidth;
68 int mode;
69 int prev_mode;
70 int frame_size;
71 int prev_redundancy;
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +000072 int last_packet_duration;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +000073#ifndef FIXED_POINT
74 opus_val16 softclip_mem[2];
75#endif
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +000076
77 opus_uint32 rangeFinal;
78};
79
80#ifdef FIXED_POINT
tlegrand@google.com3c3902f2013-12-09 08:35:25 +000081static OPUS_INLINE opus_int16 SAT16(opus_int32 x) {
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +000082 return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x;
83}
84#endif
85
86
87int opus_decoder_get_size(int channels)
88{
89 int silkDecSizeBytes, celtDecSizeBytes;
90 int ret;
91 if (channels<1 || channels > 2)
92 return 0;
93 ret = silk_Get_Decoder_Size( &silkDecSizeBytes );
94 if(ret)
95 return 0;
96 silkDecSizeBytes = align(silkDecSizeBytes);
97 celtDecSizeBytes = celt_decoder_get_size(channels);
98 return align(sizeof(OpusDecoder))+silkDecSizeBytes+celtDecSizeBytes;
99}
100
101int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
102{
103 void *silk_dec;
104 CELTDecoder *celt_dec;
105 int ret, silkDecSizeBytes;
106
107 if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)
108 || (channels!=1&&channels!=2))
109 return OPUS_BAD_ARG;
110
111 OPUS_CLEAR((char*)st, opus_decoder_get_size(channels));
112 /* Initialize SILK encoder */
113 ret = silk_Get_Decoder_Size(&silkDecSizeBytes);
114 if (ret)
115 return OPUS_INTERNAL_ERROR;
116
117 silkDecSizeBytes = align(silkDecSizeBytes);
118 st->silk_dec_offset = align(sizeof(OpusDecoder));
119 st->celt_dec_offset = st->silk_dec_offset+silkDecSizeBytes;
120 silk_dec = (char*)st+st->silk_dec_offset;
121 celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
122 st->stream_channels = st->channels = channels;
123
124 st->Fs = Fs;
125 st->DecControl.API_sampleRate = st->Fs;
126 st->DecControl.nChannelsAPI = st->channels;
127
128 /* Reset decoder */
129 ret = silk_InitDecoder( silk_dec );
130 if(ret)return OPUS_INTERNAL_ERROR;
131
132 /* Initialize CELT decoder */
133 ret = celt_decoder_init(celt_dec, Fs, channels);
134 if(ret!=OPUS_OK)return OPUS_INTERNAL_ERROR;
135
136 celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0));
137
138 st->prev_mode = 0;
139 st->frame_size = Fs/400;
140 return OPUS_OK;
141}
142
143OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
144{
145 int ret;
146 OpusDecoder *st;
147 if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)
148 || (channels!=1&&channels!=2))
149 {
150 if (error)
151 *error = OPUS_BAD_ARG;
152 return NULL;
153 }
154 st = (OpusDecoder *)opus_alloc(opus_decoder_get_size(channels));
155 if (st == NULL)
156 {
157 if (error)
158 *error = OPUS_ALLOC_FAIL;
159 return NULL;
160 }
161 ret = opus_decoder_init(st, Fs, channels);
162 if (error)
163 *error = ret;
164 if (ret != OPUS_OK)
165 {
166 opus_free(st);
167 st = NULL;
168 }
169 return st;
170}
171
172static void smooth_fade(const opus_val16 *in1, const opus_val16 *in2,
173 opus_val16 *out, int overlap, int channels,
174 const opus_val16 *window, opus_int32 Fs)
175{
176 int i, c;
177 int inc = 48000/Fs;
178 for (c=0;c<channels;c++)
179 {
180 for (i=0;i<overlap;i++)
181 {
182 opus_val16 w = MULT16_16_Q15(window[i*inc], window[i*inc]);
183 out[i*channels+c] = SHR32(MAC16_16(MULT16_16(w,in2[i*channels+c]),
184 Q15ONE-w, in1[i*channels+c]), 15);
185 }
186 }
187}
188
189static int opus_packet_get_mode(const unsigned char *data)
190{
191 int mode;
192 if (data[0]&0x80)
193 {
194 mode = MODE_CELT_ONLY;
195 } else if ((data[0]&0x60) == 0x60)
196 {
197 mode = MODE_HYBRID;
198 } else {
199 mode = MODE_SILK_ONLY;
200 }
201 return mode;
202}
203
204static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
205 opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
206{
207 void *silk_dec;
208 CELTDecoder *celt_dec;
209 int i, silk_ret=0, celt_ret=0;
210 ec_dec dec;
211 opus_int32 silk_frame_size;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000212 int pcm_silk_size;
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000213 VARDECL(opus_int16, pcm_silk);
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000214 int pcm_transition_silk_size;
215 VARDECL(opus_val16, pcm_transition_silk);
216 int pcm_transition_celt_size;
217 VARDECL(opus_val16, pcm_transition_celt);
218 opus_val16 *pcm_transition;
219 int redundant_audio_size;
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000220 VARDECL(opus_val16, redundant_audio);
221
222 int audiosize;
223 int mode;
224 int transition=0;
225 int start_band;
226 int redundancy=0;
227 int redundancy_bytes = 0;
228 int celt_to_silk=0;
229 int c;
230 int F2_5, F5, F10, F20;
231 const opus_val16 *window;
232 opus_uint32 redundant_rng = 0;
233 ALLOC_STACK;
234
235 silk_dec = (char*)st+st->silk_dec_offset;
236 celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
237 F20 = st->Fs/50;
238 F10 = F20>>1;
239 F5 = F10>>1;
240 F2_5 = F5>>1;
241 if (frame_size < F2_5)
242 {
243 RESTORE_STACK;
244 return OPUS_BUFFER_TOO_SMALL;
245 }
sergeyu@chromium.org660e25f2012-11-01 20:44:27 +0000246 /* Limit frame_size to avoid excessive stack allocations. */
247 frame_size = IMIN(frame_size, st->Fs/25*3);
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000248 /* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */
249 if (len<=1)
250 {
251 data = NULL;
252 /* In that case, don't conceal more than what the ToC says */
253 frame_size = IMIN(frame_size, st->frame_size);
254 }
255 if (data != NULL)
256 {
257 audiosize = st->frame_size;
258 mode = st->mode;
259 ec_dec_init(&dec,(unsigned char*)data,len);
260 } else {
261 audiosize = frame_size;
tlegrand@google.com3c3902f2013-12-09 08:35:25 +0000262 mode = st->prev_mode;
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000263
tlegrand@google.com3c3902f2013-12-09 08:35:25 +0000264 if (mode == 0)
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000265 {
266 /* If we haven't got any packet yet, all we can do is return zeros */
267 for (i=0;i<audiosize*st->channels;i++)
268 pcm[i] = 0;
269 RESTORE_STACK;
270 return audiosize;
tlegrand@google.com3c3902f2013-12-09 08:35:25 +0000271 }
272
273 /* Avoids trying to run the PLC on sizes other than 2.5 (CELT), 5 (CELT),
274 10, or 20 (e.g. 12.5 or 30 ms). */
275 if (audiosize > F20)
276 {
277 do {
278 int ret = opus_decode_frame(st, NULL, 0, pcm, IMIN(audiosize, F20), 0);
279 if (ret<0)
280 {
281 RESTORE_STACK;
282 return ret;
283 }
284 pcm += ret*st->channels;
285 audiosize -= ret;
286 } while (audiosize > 0);
287 RESTORE_STACK;
288 return frame_size;
289 } else if (audiosize < F20)
290 {
291 if (audiosize > F10)
292 audiosize = F10;
293 else if (mode != MODE_SILK_ONLY && audiosize > F5 && audiosize < F10)
294 audiosize = F5;
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000295 }
296 }
297
tlegrand@google.com3c3902f2013-12-09 08:35:25 +0000298 pcm_transition_silk_size = ALLOC_NONE;
299 pcm_transition_celt_size = ALLOC_NONE;
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000300 if (data!=NULL && st->prev_mode > 0 && (
301 (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy)
302 || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) )
303 )
304 {
305 transition = 1;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000306 /* Decide where to allocate the stack memory for pcm_transition */
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000307 if (mode == MODE_CELT_ONLY)
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000308 pcm_transition_celt_size = F5*st->channels;
309 else
310 pcm_transition_silk_size = F5*st->channels;
311 }
312 ALLOC(pcm_transition_celt, pcm_transition_celt_size, opus_val16);
313 if (transition && mode == MODE_CELT_ONLY)
314 {
315 pcm_transition = pcm_transition_celt;
316 opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000317 }
318 if (audiosize > frame_size)
319 {
320 /*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosize, frame_size, mode);*/
321 RESTORE_STACK;
322 return OPUS_BAD_ARG;
323 } else {
324 frame_size = audiosize;
325 }
326
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000327 /* Don't allocate any memory when in CELT-only mode */
tlegrand@google.com3c3902f2013-12-09 08:35:25 +0000328 pcm_silk_size = (mode != MODE_CELT_ONLY) ? IMAX(F10, frame_size)*st->channels : ALLOC_NONE;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000329 ALLOC(pcm_silk, pcm_silk_size, opus_int16);
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000330
331 /* SILK processing */
332 if (mode != MODE_CELT_ONLY)
333 {
334 int lost_flag, decoded_samples;
335 opus_int16 *pcm_ptr = pcm_silk;
336
337 if (st->prev_mode==MODE_CELT_ONLY)
338 silk_InitDecoder( silk_dec );
339
340 /* The SILK PLC cannot produce frames of less than 10 ms */
341 st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs);
342
343 if (data != NULL)
344 {
345 st->DecControl.nChannelsInternal = st->stream_channels;
346 if( mode == MODE_SILK_ONLY ) {
347 if( st->bandwidth == OPUS_BANDWIDTH_NARROWBAND ) {
348 st->DecControl.internalSampleRate = 8000;
349 } else if( st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) {
350 st->DecControl.internalSampleRate = 12000;
351 } else if( st->bandwidth == OPUS_BANDWIDTH_WIDEBAND ) {
352 st->DecControl.internalSampleRate = 16000;
353 } else {
354 st->DecControl.internalSampleRate = 16000;
355 silk_assert( 0 );
356 }
357 } else {
358 /* Hybrid mode */
359 st->DecControl.internalSampleRate = 16000;
360 }
361 }
362
363 lost_flag = data == NULL ? 1 : 2 * decode_fec;
364 decoded_samples = 0;
365 do {
366 /* Call SILK decoder */
367 int first_frame = decoded_samples == 0;
368 silk_ret = silk_Decode( silk_dec, &st->DecControl,
369 lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size );
370 if( silk_ret ) {
371 if (lost_flag) {
372 /* PLC failure should not be fatal */
373 silk_frame_size = frame_size;
374 for (i=0;i<frame_size*st->channels;i++)
375 pcm_ptr[i] = 0;
376 } else {
377 RESTORE_STACK;
tlegrand@google.com3c3902f2013-12-09 08:35:25 +0000378 return OPUS_INTERNAL_ERROR;
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000379 }
380 }
381 pcm_ptr += silk_frame_size * st->channels;
382 decoded_samples += silk_frame_size;
383 } while( decoded_samples < frame_size );
384 }
385
386 start_band = 0;
387 if (!decode_fec && mode != MODE_CELT_ONLY && data != NULL
388 && ec_tell(&dec)+17+20*(st->mode == MODE_HYBRID) <= 8*len)
389 {
390 /* Check if we have a redundant 0-8 kHz band */
391 if (mode == MODE_HYBRID)
392 redundancy = ec_dec_bit_logp(&dec, 12);
393 else
394 redundancy = 1;
395 if (redundancy)
396 {
397 celt_to_silk = ec_dec_bit_logp(&dec, 1);
398 /* redundancy_bytes will be at least two, in the non-hybrid
399 case due to the ec_tell() check above */
400 redundancy_bytes = mode==MODE_HYBRID ?
401 (opus_int32)ec_dec_uint(&dec, 256)+2 :
402 len-((ec_tell(&dec)+7)>>3);
403 len -= redundancy_bytes;
404 /* This is a sanity check. It should never happen for a valid
405 packet, so the exact behaviour is not normative. */
406 if (len*8 < ec_tell(&dec))
407 {
408 len = 0;
409 redundancy_bytes = 0;
410 redundancy = 0;
411 }
412 /* Shrink decoder because of raw bits */
413 dec.storage -= redundancy_bytes;
414 }
415 }
416 if (mode != MODE_CELT_ONLY)
417 start_band = 17;
418
419 {
420 int endband=21;
421
422 switch(st->bandwidth)
423 {
424 case OPUS_BANDWIDTH_NARROWBAND:
425 endband = 13;
426 break;
427 case OPUS_BANDWIDTH_MEDIUMBAND:
428 case OPUS_BANDWIDTH_WIDEBAND:
429 endband = 17;
430 break;
431 case OPUS_BANDWIDTH_SUPERWIDEBAND:
432 endband = 19;
433 break;
434 case OPUS_BANDWIDTH_FULLBAND:
435 endband = 21;
436 break;
437 }
438 celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband));
439 celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels));
440 }
441
442 if (redundancy)
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000443 {
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000444 transition = 0;
tlegrand@google.com3c3902f2013-12-09 08:35:25 +0000445 pcm_transition_silk_size=ALLOC_NONE;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000446 }
447
448 ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16);
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000449
450 if (transition && mode != MODE_CELT_ONLY)
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000451 {
452 pcm_transition = pcm_transition_silk;
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000453 opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000454 }
455
456 /* Only allocation memory for redundancy if/when needed */
tlegrand@google.com3c3902f2013-12-09 08:35:25 +0000457 redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000458 ALLOC(redundant_audio, redundant_audio_size, opus_val16);
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000459
460 /* 5 ms redundant frame for CELT->SILK*/
461 if (redundancy && celt_to_silk)
462 {
463 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
464 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes,
465 redundant_audio, F5, NULL);
466 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
467 }
468
469 /* MUST be after PLC */
470 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band));
471
472 if (mode != MODE_SILK_ONLY)
473 {
474 int celt_frame_size = IMIN(F20, frame_size);
475 /* Make sure to discard any previous CELT state */
476 if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy)
477 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
478 /* Decode CELT */
479 celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data,
480 len, pcm, celt_frame_size, &dec);
481 } else {
482 unsigned char silence[2] = {0xFF, 0xFF};
483 for (i=0;i<frame_size*st->channels;i++)
484 pcm[i] = 0;
485 /* For hybrid -> SILK transitions, we let the CELT MDCT
486 do a fade-out by decoding a silence frame */
487 if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->prev_redundancy) )
488 {
489 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
490 celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL);
491 }
492 }
493
494 if (mode != MODE_CELT_ONLY)
495 {
496#ifdef FIXED_POINT
497 for (i=0;i<frame_size*st->channels;i++)
498 pcm[i] = SAT16(pcm[i] + pcm_silk[i]);
499#else
500 for (i=0;i<frame_size*st->channels;i++)
501 pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]);
502#endif
503 }
504
505 {
506 const CELTMode *celt_mode;
507 celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode));
508 window = celt_mode->window;
509 }
510
511 /* 5 ms redundant frame for SILK->CELT */
512 if (redundancy && !celt_to_silk)
513 {
514 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
515 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
516
517 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL);
518 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
519 smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5,
520 pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs);
521 }
522 if (redundancy && celt_to_silk)
523 {
524 for (c=0;c<st->channels;c++)
525 {
526 for (i=0;i<F2_5;i++)
527 pcm[st->channels*i+c] = redundant_audio[st->channels*i+c];
528 }
529 smooth_fade(redundant_audio+st->channels*F2_5, pcm+st->channels*F2_5,
530 pcm+st->channels*F2_5, F2_5, st->channels, window, st->Fs);
531 }
532 if (transition)
533 {
534 if (audiosize >= F5)
535 {
536 for (i=0;i<st->channels*F2_5;i++)
537 pcm[i] = pcm_transition[i];
538 smooth_fade(pcm_transition+st->channels*F2_5, pcm+st->channels*F2_5,
539 pcm+st->channels*F2_5, F2_5,
540 st->channels, window, st->Fs);
541 } else {
542 /* Not enough time to do a clean transition, but we do it anyway
543 This will not preserve amplitude perfectly and may introduce
544 a bit of temporal aliasing, but it shouldn't be too bad and
545 that's pretty much the best we can do. In any case, generating this
546 transition it pretty silly in the first place */
547 smooth_fade(pcm_transition, pcm,
548 pcm, F2_5,
549 st->channels, window, st->Fs);
550 }
551 }
552
553 if(st->decode_gain)
554 {
555 opus_val32 gain;
556 gain = celt_exp2(MULT16_16_P15(QCONST16(6.48814081e-4f, 25), st->decode_gain));
557 for (i=0;i<frame_size*st->channels;i++)
558 {
559 opus_val32 x;
560 x = MULT16_32_P16(pcm[i],gain);
561 pcm[i] = SATURATE(x, 32767);
562 }
563 }
564
565 if (len <= 1)
566 st->rangeFinal = 0;
567 else
568 st->rangeFinal = dec.rng ^ redundant_rng;
569
570 st->prev_mode = mode;
571 st->prev_redundancy = redundancy && !celt_to_silk;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000572
573 if (celt_ret>=0)
574 {
575 if (OPUS_CHECK_ARRAY(pcm, audiosize*st->channels))
576 OPUS_PRINT_INT(audiosize);
577 }
578
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000579 RESTORE_STACK;
580 return celt_ret < 0 ? celt_ret : audiosize;
581
582}
583
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000584int opus_decode_native(OpusDecoder *st, const unsigned char *data,
585 opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec,
tlegrand@google.com3c3902f2013-12-09 08:35:25 +0000586 int self_delimited, opus_int32 *packet_offset, int soft_clip)
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000587{
588 int i, nb_samples;
589 int count, offset;
590 unsigned char toc;
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000591 int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels;
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000592 /* 48 x 2.5 ms = 120 ms */
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000593 opus_int16 size[48];
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000594 if (decode_fec<0 || decode_fec>1)
595 return OPUS_BAD_ARG;
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000596 /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */
597 if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0)
598 return OPUS_BAD_ARG;
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000599 if (len==0 || data==NULL)
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000600 {
601 int pcm_count=0;
602 do {
603 int ret;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000604 ret = opus_decode_frame(st, NULL, 0, pcm+pcm_count*st->channels, frame_size-pcm_count, 0);
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000605 if (ret<0)
606 return ret;
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000607 pcm_count += ret;
608 } while (pcm_count < frame_size);
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000609 celt_assert(pcm_count == frame_size);
610 if (OPUS_CHECK_ARRAY(pcm, pcm_count*st->channels))
611 OPUS_PRINT_INT(pcm_count);
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000612 st->last_packet_duration = pcm_count;
613 return pcm_count;
614 } else if (len<0)
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000615 return OPUS_BAD_ARG;
616
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000617 packet_mode = opus_packet_get_mode(data);
618 packet_bandwidth = opus_packet_get_bandwidth(data);
619 packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs);
620 packet_stream_channels = opus_packet_get_nb_channels(data);
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000621
tlegrand@google.com3c3902f2013-12-09 08:35:25 +0000622 count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL,
623 size, &offset, packet_offset);
624 if (count<0)
625 return count;
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000626
627 data += offset;
628
629 if (decode_fec)
630 {
631 int duration_copy;
632 int ret;
633 /* If no FEC can be present, run the PLC (recursive call) */
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000634 if (frame_size < packet_frame_size || packet_mode == MODE_CELT_ONLY || st->mode == MODE_CELT_ONLY)
635 return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL, soft_clip);
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000636 /* Otherwise, run the PLC on everything except the size for which we might have FEC */
637 duration_copy = st->last_packet_duration;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000638 if (frame_size-packet_frame_size!=0)
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000639 {
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000640 ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0, 0, NULL, soft_clip);
641 if (ret<0)
642 {
643 st->last_packet_duration = duration_copy;
644 return ret;
645 }
646 celt_assert(ret==frame_size-packet_frame_size);
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000647 }
648 /* Complete with FEC */
649 st->mode = packet_mode;
650 st->bandwidth = packet_bandwidth;
651 st->frame_size = packet_frame_size;
652 st->stream_channels = packet_stream_channels;
653 ret = opus_decode_frame(st, data, size[0], pcm+st->channels*(frame_size-packet_frame_size),
654 packet_frame_size, 1);
655 if (ret<0)
656 return ret;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000657 else {
658 if (OPUS_CHECK_ARRAY(pcm, frame_size*st->channels))
659 OPUS_PRINT_INT(frame_size);
660 st->last_packet_duration = frame_size;
661 return frame_size;
662 }
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000663 }
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000664
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000665 if (count*packet_frame_size > frame_size)
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000666 return OPUS_BUFFER_TOO_SMALL;
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000667
668 /* Update the state as the last step to avoid updating it on an invalid packet */
669 st->mode = packet_mode;
670 st->bandwidth = packet_bandwidth;
671 st->frame_size = packet_frame_size;
672 st->stream_channels = packet_stream_channels;
673
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000674 nb_samples=0;
675 for (i=0;i<count;i++)
676 {
677 int ret;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000678 ret = opus_decode_frame(st, data, size[i], pcm+nb_samples*st->channels, frame_size-nb_samples, 0);
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000679 if (ret<0)
680 return ret;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000681 celt_assert(ret==packet_frame_size);
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000682 data += size[i];
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000683 nb_samples += ret;
684 }
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000685 st->last_packet_duration = nb_samples;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000686 if (OPUS_CHECK_ARRAY(pcm, nb_samples*st->channels))
687 OPUS_PRINT_INT(nb_samples);
688#ifndef FIXED_POINT
689 if (soft_clip)
690 opus_pcm_soft_clip(pcm, nb_samples, st->channels, st->softclip_mem);
691 else
692 st->softclip_mem[0]=st->softclip_mem[1]=0;
693#endif
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000694 return nb_samples;
695}
696
697#ifdef FIXED_POINT
698
699int opus_decode(OpusDecoder *st, const unsigned char *data,
700 opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
701{
tlegrand@google.com3c3902f2013-12-09 08:35:25 +0000702 if(frame_size<=0)
703 return OPUS_BAD_ARG;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000704 return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0);
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000705}
706
707#ifndef DISABLE_FLOAT_API
708int opus_decode_float(OpusDecoder *st, const unsigned char *data,
709 opus_int32 len, float *pcm, int frame_size, int decode_fec)
710{
711 VARDECL(opus_int16, out);
712 int ret, i;
713 ALLOC_STACK;
714
tlegrand@google.com3c3902f2013-12-09 08:35:25 +0000715 if(frame_size<=0)
716 {
717 RESTORE_STACK;
718 return OPUS_BAD_ARG;
719 }
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000720 ALLOC(out, frame_size*st->channels, opus_int16);
721
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000722 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0);
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000723 if (ret > 0)
724 {
725 for (i=0;i<ret*st->channels;i++)
726 pcm[i] = (1.f/32768.f)*(out[i]);
727 }
728 RESTORE_STACK;
729 return ret;
730}
731#endif
732
733
734#else
735int opus_decode(OpusDecoder *st, const unsigned char *data,
736 opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
737{
738 VARDECL(float, out);
739 int ret, i;
740 ALLOC_STACK;
741
tlegrand@google.com3c3902f2013-12-09 08:35:25 +0000742 if(frame_size<=0)
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000743 {
744 RESTORE_STACK;
745 return OPUS_BAD_ARG;
746 }
747
748 ALLOC(out, frame_size*st->channels, float);
749
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000750 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1);
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000751 if (ret > 0)
752 {
753 for (i=0;i<ret*st->channels;i++)
754 pcm[i] = FLOAT2INT16(out[i]);
755 }
756 RESTORE_STACK;
757 return ret;
758}
759
760int opus_decode_float(OpusDecoder *st, const unsigned char *data,
761 opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
762{
tlegrand@google.com3c3902f2013-12-09 08:35:25 +0000763 if(frame_size<=0)
764 return OPUS_BAD_ARG;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000765 return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0);
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000766}
767
768#endif
769
770int opus_decoder_ctl(OpusDecoder *st, int request, ...)
771{
772 int ret = OPUS_OK;
773 va_list ap;
774 void *silk_dec;
775 CELTDecoder *celt_dec;
776
777 silk_dec = (char*)st+st->silk_dec_offset;
778 celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
779
780
781 va_start(ap, request);
782
783 switch (request)
784 {
785 case OPUS_GET_BANDWIDTH_REQUEST:
786 {
787 opus_int32 *value = va_arg(ap, opus_int32*);
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000788 if (!value)
789 {
790 goto bad_arg;
791 }
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000792 *value = st->bandwidth;
793 }
794 break;
795 case OPUS_GET_FINAL_RANGE_REQUEST:
796 {
797 opus_uint32 *value = va_arg(ap, opus_uint32*);
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000798 if (!value)
799 {
800 goto bad_arg;
801 }
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000802 *value = st->rangeFinal;
803 }
804 break;
805 case OPUS_RESET_STATE:
806 {
807 OPUS_CLEAR((char*)&st->OPUS_DECODER_RESET_START,
808 sizeof(OpusDecoder)-
809 ((char*)&st->OPUS_DECODER_RESET_START - (char*)st));
810
811 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
812 silk_InitDecoder( silk_dec );
813 st->stream_channels = st->channels;
814 st->frame_size = st->Fs/400;
815 }
816 break;
sergeyu@chromium.org660e25f2012-11-01 20:44:27 +0000817 case OPUS_GET_SAMPLE_RATE_REQUEST:
818 {
819 opus_int32 *value = va_arg(ap, opus_int32*);
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000820 if (!value)
sergeyu@chromium.org660e25f2012-11-01 20:44:27 +0000821 {
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000822 goto bad_arg;
sergeyu@chromium.org660e25f2012-11-01 20:44:27 +0000823 }
824 *value = st->Fs;
825 }
826 break;
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000827 case OPUS_GET_PITCH_REQUEST:
828 {
829 opus_int32 *value = va_arg(ap, opus_int32*);
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000830 if (!value)
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000831 {
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000832 goto bad_arg;
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000833 }
834 if (st->prev_mode == MODE_CELT_ONLY)
835 celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value));
836 else
837 *value = st->DecControl.prevPitchLag;
838 }
839 break;
840 case OPUS_GET_GAIN_REQUEST:
841 {
842 opus_int32 *value = va_arg(ap, opus_int32*);
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000843 if (!value)
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000844 {
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000845 goto bad_arg;
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000846 }
847 *value = st->decode_gain;
848 }
849 break;
850 case OPUS_SET_GAIN_REQUEST:
851 {
852 opus_int32 value = va_arg(ap, opus_int32);
853 if (value<-32768 || value>32767)
854 {
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000855 goto bad_arg;
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000856 }
857 st->decode_gain = value;
858 }
859 break;
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000860 case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
861 {
862 opus_uint32 *value = va_arg(ap, opus_uint32*);
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000863 if (!value)
864 {
865 goto bad_arg;
866 }
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000867 *value = st->last_packet_duration;
868 }
869 break;
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000870 default:
871 /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/
872 ret = OPUS_UNIMPLEMENTED;
873 break;
874 }
875
876 va_end(ap);
877 return ret;
tlegrand@chromium.orge3ea0492013-10-23 09:13:50 +0000878bad_arg:
879 va_end(ap);
880 return OPUS_BAD_ARG;
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000881}
882
883void opus_decoder_destroy(OpusDecoder *st)
884{
885 opus_free(st);
886}
887
888
889int opus_packet_get_bandwidth(const unsigned char *data)
890{
891 int bandwidth;
892 if (data[0]&0x80)
893 {
894 bandwidth = OPUS_BANDWIDTH_MEDIUMBAND + ((data[0]>>5)&0x3);
895 if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)
896 bandwidth = OPUS_BANDWIDTH_NARROWBAND;
897 } else if ((data[0]&0x60) == 0x60)
898 {
899 bandwidth = (data[0]&0x10) ? OPUS_BANDWIDTH_FULLBAND :
900 OPUS_BANDWIDTH_SUPERWIDEBAND;
901 } else {
902 bandwidth = OPUS_BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3);
903 }
904 return bandwidth;
905}
906
907int opus_packet_get_samples_per_frame(const unsigned char *data,
908 opus_int32 Fs)
909{
910 int audiosize;
911 if (data[0]&0x80)
912 {
913 audiosize = ((data[0]>>3)&0x3);
914 audiosize = (Fs<<audiosize)/400;
915 } else if ((data[0]&0x60) == 0x60)
916 {
917 audiosize = (data[0]&0x08) ? Fs/50 : Fs/100;
918 } else {
919 audiosize = ((data[0]>>3)&0x3);
920 if (audiosize == 3)
921 audiosize = Fs*60/1000;
922 else
923 audiosize = (Fs<<audiosize)/100;
924 }
925 return audiosize;
926}
927
928int opus_packet_get_nb_channels(const unsigned char *data)
929{
930 return (data[0]&0x4) ? 2 : 1;
931}
932
933int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len)
934{
935 int count;
936 if (len<1)
937 return OPUS_BAD_ARG;
938 count = packet[0]&0x3;
939 if (count==0)
940 return 1;
941 else if (count!=3)
942 return 2;
943 else if (len<2)
944 return OPUS_INVALID_PACKET;
945 else
946 return packet[1]&0x3F;
947}
948
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000949int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len,
950 opus_int32 Fs)
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000951{
952 int samples;
953 int count = opus_packet_get_nb_frames(packet, len);
954
955 if (count<0)
956 return count;
957
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000958 samples = count*opus_packet_get_samples_per_frame(packet, Fs);
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000959 /* Can't have more than 120 ms */
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000960 if (samples*25 > Fs*3)
sergeyu@chromium.org885f2ff2012-10-17 22:31:52 +0000961 return OPUS_INVALID_PACKET;
962 else
963 return samples;
964}
sergeyu@chromium.org6b6bee22013-02-28 21:17:26 +0000965
966int opus_decoder_get_nb_samples(const OpusDecoder *dec,
967 const unsigned char packet[], opus_int32 len)
968{
969 return opus_packet_get_nb_samples(packet, len, dec->Fs);
970}