| 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 |