OLD | NEW |
1 /* Copyright (c) 2010 Xiph.Org Foundation, Skype Limited | 1 /* Copyright (c) 2010 Xiph.Org Foundation, Skype Limited |
2 Written by Jean-Marc Valin and Koen Vos */ | 2 Written by Jean-Marc Valin and Koen Vos */ |
3 /* | 3 /* |
4 Redistribution and use in source and binary forms, with or without | 4 Redistribution and use in source and binary forms, with or without |
5 modification, are permitted provided that the following conditions | 5 modification, are permitted provided that the following conditions |
6 are met: | 6 are met: |
7 | 7 |
8 - Redistributions of source code must retain the above copyright | 8 - Redistributions of source code must retain the above copyright |
9 notice, this list of conditions and the following disclaimer. | 9 notice, this list of conditions and the following disclaimer. |
10 | 10 |
(...skipping 15 matching lines...) Expand all Loading... |
26 */ | 26 */ |
27 | 27 |
28 #ifdef HAVE_CONFIG_H | 28 #ifdef HAVE_CONFIG_H |
29 # include "config.h" | 29 # include "config.h" |
30 #endif | 30 #endif |
31 | 31 |
32 #ifndef OPUS_BUILD | 32 #ifndef OPUS_BUILD |
33 # error "OPUS_BUILD _MUST_ be defined to build Opus. This probably means you nee
d other defines as well, as in a config.h. See the included build files for deta
ils." | 33 # error "OPUS_BUILD _MUST_ be defined to build Opus. This probably means you nee
d other defines as well, as in a config.h. See the included build files for deta
ils." |
34 #endif | 34 #endif |
35 | 35 |
36 #if defined(__GNUC__) && (__GNUC__ >= 2) && !defined(__OPTIMIZE__) | 36 #if defined(__GNUC__) && (__GNUC__ >= 2) && !defined(__OPTIMIZE__) && !defined(O
PUS_WILL_BE_SLOW) |
37 # pragma message "You appear to be compiling without optimization, if so opus wi
ll be very slow." | 37 # pragma message "You appear to be compiling without optimization, if so opus wi
ll be very slow." |
38 #endif | 38 #endif |
39 | 39 |
40 #include <stdarg.h> | 40 #include <stdarg.h> |
41 #include "celt.h" | 41 #include "celt.h" |
42 #include "opus.h" | 42 #include "opus.h" |
43 #include "entdec.h" | 43 #include "entdec.h" |
44 #include "modes.h" | 44 #include "modes.h" |
45 #include "API.h" | 45 #include "API.h" |
46 #include "stack_alloc.h" | 46 #include "stack_alloc.h" |
(...skipping 21 matching lines...) Expand all Loading... |
68 int mode; | 68 int mode; |
69 int prev_mode; | 69 int prev_mode; |
70 int frame_size; | 70 int frame_size; |
71 int prev_redundancy; | 71 int prev_redundancy; |
72 int last_packet_duration; | 72 int last_packet_duration; |
73 #ifndef FIXED_POINT | 73 #ifndef FIXED_POINT |
74 opus_val16 softclip_mem[2]; | 74 opus_val16 softclip_mem[2]; |
75 #endif | 75 #endif |
76 | 76 |
77 opus_uint32 rangeFinal; | 77 opus_uint32 rangeFinal; |
| 78 int arch; |
78 }; | 79 }; |
79 | 80 |
80 #ifdef FIXED_POINT | |
81 static OPUS_INLINE opus_int16 SAT16(opus_int32 x) { | |
82 return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x; | |
83 } | |
84 #endif | |
85 | |
86 | 81 |
87 int opus_decoder_get_size(int channels) | 82 int opus_decoder_get_size(int channels) |
88 { | 83 { |
89 int silkDecSizeBytes, celtDecSizeBytes; | 84 int silkDecSizeBytes, celtDecSizeBytes; |
90 int ret; | 85 int ret; |
91 if (channels<1 || channels > 2) | 86 if (channels<1 || channels > 2) |
92 return 0; | 87 return 0; |
93 ret = silk_Get_Decoder_Size( &silkDecSizeBytes ); | 88 ret = silk_Get_Decoder_Size( &silkDecSizeBytes ); |
94 if(ret) | 89 if(ret) |
95 return 0; | 90 return 0; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 if(ret)return OPUS_INTERNAL_ERROR; | 125 if(ret)return OPUS_INTERNAL_ERROR; |
131 | 126 |
132 /* Initialize CELT decoder */ | 127 /* Initialize CELT decoder */ |
133 ret = celt_decoder_init(celt_dec, Fs, channels); | 128 ret = celt_decoder_init(celt_dec, Fs, channels); |
134 if(ret!=OPUS_OK)return OPUS_INTERNAL_ERROR; | 129 if(ret!=OPUS_OK)return OPUS_INTERNAL_ERROR; |
135 | 130 |
136 celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0)); | 131 celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0)); |
137 | 132 |
138 st->prev_mode = 0; | 133 st->prev_mode = 0; |
139 st->frame_size = Fs/400; | 134 st->frame_size = Fs/400; |
| 135 st->arch = opus_select_arch(); |
140 return OPUS_OK; | 136 return OPUS_OK; |
141 } | 137 } |
142 | 138 |
143 OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error) | 139 OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error) |
144 { | 140 { |
145 int ret; | 141 int ret; |
146 OpusDecoder *st; | 142 OpusDecoder *st; |
147 if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000) | 143 if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000) |
148 || (channels!=1&&channels!=2)) | 144 || (channels!=1&&channels!=2)) |
149 { | 145 { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 CELTDecoder *celt_dec; | 204 CELTDecoder *celt_dec; |
209 int i, silk_ret=0, celt_ret=0; | 205 int i, silk_ret=0, celt_ret=0; |
210 ec_dec dec; | 206 ec_dec dec; |
211 opus_int32 silk_frame_size; | 207 opus_int32 silk_frame_size; |
212 int pcm_silk_size; | 208 int pcm_silk_size; |
213 VARDECL(opus_int16, pcm_silk); | 209 VARDECL(opus_int16, pcm_silk); |
214 int pcm_transition_silk_size; | 210 int pcm_transition_silk_size; |
215 VARDECL(opus_val16, pcm_transition_silk); | 211 VARDECL(opus_val16, pcm_transition_silk); |
216 int pcm_transition_celt_size; | 212 int pcm_transition_celt_size; |
217 VARDECL(opus_val16, pcm_transition_celt); | 213 VARDECL(opus_val16, pcm_transition_celt); |
218 opus_val16 *pcm_transition; | 214 opus_val16 *pcm_transition=NULL; |
219 int redundant_audio_size; | 215 int redundant_audio_size; |
220 VARDECL(opus_val16, redundant_audio); | 216 VARDECL(opus_val16, redundant_audio); |
221 | 217 |
222 int audiosize; | 218 int audiosize; |
223 int mode; | 219 int mode; |
224 int transition=0; | 220 int transition=0; |
225 int start_band; | 221 int start_band; |
226 int redundancy=0; | 222 int redundancy=0; |
227 int redundancy_bytes = 0; | 223 int redundancy_bytes = 0; |
228 int celt_to_silk=0; | 224 int celt_to_silk=0; |
229 int c; | 225 int c; |
230 int F2_5, F5, F10, F20; | 226 int F2_5, F5, F10, F20; |
231 const opus_val16 *window; | 227 const opus_val16 *window; |
232 opus_uint32 redundant_rng = 0; | 228 opus_uint32 redundant_rng = 0; |
| 229 int celt_accum; |
233 ALLOC_STACK; | 230 ALLOC_STACK; |
234 | 231 |
235 silk_dec = (char*)st+st->silk_dec_offset; | 232 silk_dec = (char*)st+st->silk_dec_offset; |
236 celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); | 233 celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); |
237 F20 = st->Fs/50; | 234 F20 = st->Fs/50; |
238 F10 = F20>>1; | 235 F10 = F20>>1; |
239 F5 = F10>>1; | 236 F5 = F10>>1; |
240 F2_5 = F5>>1; | 237 F2_5 = F5>>1; |
241 if (frame_size < F2_5) | 238 if (frame_size < F2_5) |
242 { | 239 { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 return frame_size; | 285 return frame_size; |
289 } else if (audiosize < F20) | 286 } else if (audiosize < F20) |
290 { | 287 { |
291 if (audiosize > F10) | 288 if (audiosize > F10) |
292 audiosize = F10; | 289 audiosize = F10; |
293 else if (mode != MODE_SILK_ONLY && audiosize > F5 && audiosize < F10) | 290 else if (mode != MODE_SILK_ONLY && audiosize > F5 && audiosize < F10) |
294 audiosize = F5; | 291 audiosize = F5; |
295 } | 292 } |
296 } | 293 } |
297 | 294 |
| 295 /* In fixed-point, we can tell CELT to do the accumulation on top of the |
| 296 SILK PCM buffer. This saves some stack space. */ |
| 297 #ifdef FIXED_POINT |
| 298 celt_accum = (mode != MODE_CELT_ONLY) && (frame_size >= F10); |
| 299 #else |
| 300 celt_accum = 0; |
| 301 #endif |
| 302 |
298 pcm_transition_silk_size = ALLOC_NONE; | 303 pcm_transition_silk_size = ALLOC_NONE; |
299 pcm_transition_celt_size = ALLOC_NONE; | 304 pcm_transition_celt_size = ALLOC_NONE; |
300 if (data!=NULL && st->prev_mode > 0 && ( | 305 if (data!=NULL && st->prev_mode > 0 && ( |
301 (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_r
edundancy) | 306 (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_r
edundancy) |
302 || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ) | 307 || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ) |
303 ) | 308 ) |
304 { | 309 { |
305 transition = 1; | 310 transition = 1; |
306 /* Decide where to allocate the stack memory for pcm_transition */ | 311 /* Decide where to allocate the stack memory for pcm_transition */ |
307 if (mode == MODE_CELT_ONLY) | 312 if (mode == MODE_CELT_ONLY) |
(...skipping 10 matching lines...) Expand all Loading... |
318 if (audiosize > frame_size) | 323 if (audiosize > frame_size) |
319 { | 324 { |
320 /*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosiz
e, frame_size, mode);*/ | 325 /*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosiz
e, frame_size, mode);*/ |
321 RESTORE_STACK; | 326 RESTORE_STACK; |
322 return OPUS_BAD_ARG; | 327 return OPUS_BAD_ARG; |
323 } else { | 328 } else { |
324 frame_size = audiosize; | 329 frame_size = audiosize; |
325 } | 330 } |
326 | 331 |
327 /* Don't allocate any memory when in CELT-only mode */ | 332 /* Don't allocate any memory when in CELT-only mode */ |
328 pcm_silk_size = (mode != MODE_CELT_ONLY) ? IMAX(F10, frame_size)*st->channels
: ALLOC_NONE; | 333 pcm_silk_size = (mode != MODE_CELT_ONLY && !celt_accum) ? IMAX(F10, frame_siz
e)*st->channels : ALLOC_NONE; |
329 ALLOC(pcm_silk, pcm_silk_size, opus_int16); | 334 ALLOC(pcm_silk, pcm_silk_size, opus_int16); |
330 | 335 |
331 /* SILK processing */ | 336 /* SILK processing */ |
332 if (mode != MODE_CELT_ONLY) | 337 if (mode != MODE_CELT_ONLY) |
333 { | 338 { |
334 int lost_flag, decoded_samples; | 339 int lost_flag, decoded_samples; |
335 opus_int16 *pcm_ptr = pcm_silk; | 340 opus_int16 *pcm_ptr; |
| 341 #ifdef FIXED_POINT |
| 342 if (celt_accum) |
| 343 pcm_ptr = pcm; |
| 344 else |
| 345 #endif |
| 346 pcm_ptr = pcm_silk; |
336 | 347 |
337 if (st->prev_mode==MODE_CELT_ONLY) | 348 if (st->prev_mode==MODE_CELT_ONLY) |
338 silk_InitDecoder( silk_dec ); | 349 silk_InitDecoder( silk_dec ); |
339 | 350 |
340 /* The SILK PLC cannot produce frames of less than 10 ms */ | 351 /* The SILK PLC cannot produce frames of less than 10 ms */ |
341 st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs); | 352 st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs); |
342 | 353 |
343 if (data != NULL) | 354 if (data != NULL) |
344 { | 355 { |
345 st->DecControl.nChannelsInternal = st->stream_channels; | 356 st->DecControl.nChannelsInternal = st->stream_channels; |
(...skipping 13 matching lines...) Expand all Loading... |
359 st->DecControl.internalSampleRate = 16000; | 370 st->DecControl.internalSampleRate = 16000; |
360 } | 371 } |
361 } | 372 } |
362 | 373 |
363 lost_flag = data == NULL ? 1 : 2 * decode_fec; | 374 lost_flag = data == NULL ? 1 : 2 * decode_fec; |
364 decoded_samples = 0; | 375 decoded_samples = 0; |
365 do { | 376 do { |
366 /* Call SILK decoder */ | 377 /* Call SILK decoder */ |
367 int first_frame = decoded_samples == 0; | 378 int first_frame = decoded_samples == 0; |
368 silk_ret = silk_Decode( silk_dec, &st->DecControl, | 379 silk_ret = silk_Decode( silk_dec, &st->DecControl, |
369 lost_flag, first_frame, &dec, pcm_ptr, &silk_fra
me_size ); | 380 lost_flag, first_frame, &dec, pcm_ptr, &silk_fra
me_size, st->arch ); |
370 if( silk_ret ) { | 381 if( silk_ret ) { |
371 if (lost_flag) { | 382 if (lost_flag) { |
372 /* PLC failure should not be fatal */ | 383 /* PLC failure should not be fatal */ |
373 silk_frame_size = frame_size; | 384 silk_frame_size = frame_size; |
374 for (i=0;i<frame_size*st->channels;i++) | 385 for (i=0;i<frame_size*st->channels;i++) |
375 pcm_ptr[i] = 0; | 386 pcm_ptr[i] = 0; |
376 } else { | 387 } else { |
377 RESTORE_STACK; | 388 RESTORE_STACK; |
378 return OPUS_INTERNAL_ERROR; | 389 return OPUS_INTERNAL_ERROR; |
379 } | 390 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 | 466 |
456 /* Only allocation memory for redundancy if/when needed */ | 467 /* Only allocation memory for redundancy if/when needed */ |
457 redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE; | 468 redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE; |
458 ALLOC(redundant_audio, redundant_audio_size, opus_val16); | 469 ALLOC(redundant_audio, redundant_audio_size, opus_val16); |
459 | 470 |
460 /* 5 ms redundant frame for CELT->SILK*/ | 471 /* 5 ms redundant frame for CELT->SILK*/ |
461 if (redundancy && celt_to_silk) | 472 if (redundancy && celt_to_silk) |
462 { | 473 { |
463 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); | 474 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); |
464 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, | 475 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, |
465 redundant_audio, F5, NULL); | 476 redundant_audio, F5, NULL, 0); |
466 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); | 477 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); |
467 } | 478 } |
468 | 479 |
469 /* MUST be after PLC */ | 480 /* MUST be after PLC */ |
470 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band)); | 481 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band)); |
471 | 482 |
472 if (mode != MODE_SILK_ONLY) | 483 if (mode != MODE_SILK_ONLY) |
473 { | 484 { |
474 int celt_frame_size = IMIN(F20, frame_size); | 485 int celt_frame_size = IMIN(F20, frame_size); |
475 /* Make sure to discard any previous CELT state */ | 486 /* Make sure to discard any previous CELT state */ |
476 if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy) | 487 if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy) |
477 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); | 488 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); |
478 /* Decode CELT */ | 489 /* Decode CELT */ |
479 celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data, | 490 celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data, |
480 len, pcm, celt_frame_size, &dec); | 491 len, pcm, celt_frame_size, &dec, celt_accum
); |
481 } else { | 492 } else { |
482 unsigned char silence[2] = {0xFF, 0xFF}; | 493 unsigned char silence[2] = {0xFF, 0xFF}; |
483 for (i=0;i<frame_size*st->channels;i++) | 494 if (!celt_accum) |
484 pcm[i] = 0; | 495 { |
| 496 for (i=0;i<frame_size*st->channels;i++) |
| 497 pcm[i] = 0; |
| 498 } |
485 /* For hybrid -> SILK transitions, we let the CELT MDCT | 499 /* For hybrid -> SILK transitions, we let the CELT MDCT |
486 do a fade-out by decoding a silence frame */ | 500 do a fade-out by decoding a silence frame */ |
487 if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->pr
ev_redundancy) ) | 501 if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->pr
ev_redundancy) ) |
488 { | 502 { |
489 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); | 503 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); |
490 celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL); | 504 celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL, celt_accum); |
491 } | 505 } |
492 } | 506 } |
493 | 507 |
494 if (mode != MODE_CELT_ONLY) | 508 if (mode != MODE_CELT_ONLY && !celt_accum) |
495 { | 509 { |
496 #ifdef FIXED_POINT | 510 #ifdef FIXED_POINT |
497 for (i=0;i<frame_size*st->channels;i++) | 511 for (i=0;i<frame_size*st->channels;i++) |
498 pcm[i] = SAT16(pcm[i] + pcm_silk[i]); | 512 pcm[i] = SAT16(ADD32(pcm[i], pcm_silk[i])); |
499 #else | 513 #else |
500 for (i=0;i<frame_size*st->channels;i++) | 514 for (i=0;i<frame_size*st->channels;i++) |
501 pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]); | 515 pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]); |
502 #endif | 516 #endif |
503 } | 517 } |
504 | 518 |
505 { | 519 { |
506 const CELTMode *celt_mode; | 520 const CELTMode *celt_mode; |
507 celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode)); | 521 celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode)); |
508 window = celt_mode->window; | 522 window = celt_mode->window; |
509 } | 523 } |
510 | 524 |
511 /* 5 ms redundant frame for SILK->CELT */ | 525 /* 5 ms redundant frame for SILK->CELT */ |
512 if (redundancy && !celt_to_silk) | 526 if (redundancy && !celt_to_silk) |
513 { | 527 { |
514 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); | 528 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); |
515 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); | 529 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); |
516 | 530 |
517 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio,
F5, NULL); | 531 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio,
F5, NULL, 0); |
518 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); | 532 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); |
519 smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channe
ls*F2_5, | 533 smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channe
ls*F2_5, |
520 pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window
, st->Fs); | 534 pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window
, st->Fs); |
521 } | 535 } |
522 if (redundancy && celt_to_silk) | 536 if (redundancy && celt_to_silk) |
523 { | 537 { |
524 for (c=0;c<st->channels;c++) | 538 for (c=0;c<st->channels;c++) |
525 { | 539 { |
526 for (i=0;i<F2_5;i++) | 540 for (i=0;i<F2_5;i++) |
527 pcm[st->channels*i+c] = redundant_audio[st->channels*i+c]; | 541 pcm[st->channels*i+c] = redundant_audio[st->channels*i+c]; |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 return OPUS_BAD_ARG; | 717 return OPUS_BAD_ARG; |
704 return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL
, 0); | 718 return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL
, 0); |
705 } | 719 } |
706 | 720 |
707 #ifndef DISABLE_FLOAT_API | 721 #ifndef DISABLE_FLOAT_API |
708 int opus_decode_float(OpusDecoder *st, const unsigned char *data, | 722 int opus_decode_float(OpusDecoder *st, const unsigned char *data, |
709 opus_int32 len, float *pcm, int frame_size, int decode_fec) | 723 opus_int32 len, float *pcm, int frame_size, int decode_fec) |
710 { | 724 { |
711 VARDECL(opus_int16, out); | 725 VARDECL(opus_int16, out); |
712 int ret, i; | 726 int ret, i; |
| 727 int nb_samples; |
713 ALLOC_STACK; | 728 ALLOC_STACK; |
714 | 729 |
715 if(frame_size<=0) | 730 if(frame_size<=0) |
716 { | 731 { |
717 RESTORE_STACK; | 732 RESTORE_STACK; |
718 return OPUS_BAD_ARG; | 733 return OPUS_BAD_ARG; |
719 } | 734 } |
| 735 if (data != NULL && len > 0 && !decode_fec) |
| 736 { |
| 737 nb_samples = opus_decoder_get_nb_samples(st, data, len); |
| 738 if (nb_samples>0) |
| 739 frame_size = IMIN(frame_size, nb_samples); |
| 740 else |
| 741 return OPUS_INVALID_PACKET; |
| 742 } |
720 ALLOC(out, frame_size*st->channels, opus_int16); | 743 ALLOC(out, frame_size*st->channels, opus_int16); |
721 | 744 |
722 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL,
0); | 745 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL,
0); |
723 if (ret > 0) | 746 if (ret > 0) |
724 { | 747 { |
725 for (i=0;i<ret*st->channels;i++) | 748 for (i=0;i<ret*st->channels;i++) |
726 pcm[i] = (1.f/32768.f)*(out[i]); | 749 pcm[i] = (1.f/32768.f)*(out[i]); |
727 } | 750 } |
728 RESTORE_STACK; | 751 RESTORE_STACK; |
729 return ret; | 752 return ret; |
730 } | 753 } |
731 #endif | 754 #endif |
732 | 755 |
733 | 756 |
734 #else | 757 #else |
735 int opus_decode(OpusDecoder *st, const unsigned char *data, | 758 int opus_decode(OpusDecoder *st, const unsigned char *data, |
736 opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec) | 759 opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec) |
737 { | 760 { |
738 VARDECL(float, out); | 761 VARDECL(float, out); |
739 int ret, i; | 762 int ret, i; |
| 763 int nb_samples; |
740 ALLOC_STACK; | 764 ALLOC_STACK; |
741 | 765 |
742 if(frame_size<=0) | 766 if(frame_size<=0) |
743 { | 767 { |
744 RESTORE_STACK; | 768 RESTORE_STACK; |
745 return OPUS_BAD_ARG; | 769 return OPUS_BAD_ARG; |
746 } | 770 } |
747 | 771 |
| 772 if (data != NULL && len > 0 && !decode_fec) |
| 773 { |
| 774 nb_samples = opus_decoder_get_nb_samples(st, data, len); |
| 775 if (nb_samples>0) |
| 776 frame_size = IMIN(frame_size, nb_samples); |
| 777 else |
| 778 return OPUS_INVALID_PACKET; |
| 779 } |
748 ALLOC(out, frame_size*st->channels, float); | 780 ALLOC(out, frame_size*st->channels, float); |
749 | 781 |
750 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL,
1); | 782 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL,
1); |
751 if (ret > 0) | 783 if (ret > 0) |
752 { | 784 { |
753 for (i=0;i<ret*st->channels;i++) | 785 for (i=0;i<ret*st->channels;i++) |
754 pcm[i] = FLOAT2INT16(out[i]); | 786 pcm[i] = FLOAT2INT16(out[i]); |
755 } | 787 } |
756 RESTORE_STACK; | 788 RESTORE_STACK; |
757 return ret; | 789 return ret; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
897 } else if ((data[0]&0x60) == 0x60) | 929 } else if ((data[0]&0x60) == 0x60) |
898 { | 930 { |
899 bandwidth = (data[0]&0x10) ? OPUS_BANDWIDTH_FULLBAND : | 931 bandwidth = (data[0]&0x10) ? OPUS_BANDWIDTH_FULLBAND : |
900 OPUS_BANDWIDTH_SUPERWIDEBAND; | 932 OPUS_BANDWIDTH_SUPERWIDEBAND; |
901 } else { | 933 } else { |
902 bandwidth = OPUS_BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3); | 934 bandwidth = OPUS_BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3); |
903 } | 935 } |
904 return bandwidth; | 936 return bandwidth; |
905 } | 937 } |
906 | 938 |
907 int 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 | |
928 int opus_packet_get_nb_channels(const unsigned char *data) | 939 int opus_packet_get_nb_channels(const unsigned char *data) |
929 { | 940 { |
930 return (data[0]&0x4) ? 2 : 1; | 941 return (data[0]&0x4) ? 2 : 1; |
931 } | 942 } |
932 | 943 |
933 int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) | 944 int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) |
934 { | 945 { |
935 int count; | 946 int count; |
936 if (len<1) | 947 if (len<1) |
937 return OPUS_BAD_ARG; | 948 return OPUS_BAD_ARG; |
(...skipping 23 matching lines...) Expand all Loading... |
961 return OPUS_INVALID_PACKET; | 972 return OPUS_INVALID_PACKET; |
962 else | 973 else |
963 return samples; | 974 return samples; |
964 } | 975 } |
965 | 976 |
966 int opus_decoder_get_nb_samples(const OpusDecoder *dec, | 977 int opus_decoder_get_nb_samples(const OpusDecoder *dec, |
967 const unsigned char packet[], opus_int32 len) | 978 const unsigned char packet[], opus_int32 len) |
968 { | 979 { |
969 return opus_packet_get_nb_samples(packet, len, dec->Fs); | 980 return opus_packet_get_nb_samples(packet, len, dec->Fs); |
970 } | 981 } |
OLD | NEW |