diff options
-rw-r--r-- | celt/_kiss_fft_guts.h | 32 | ||||
-rw-r--r-- | celt/arch.h | 8 | ||||
-rw-r--r-- | celt/celt.c | 2 | ||||
-rw-r--r-- | celt/float_cast.h | 120 | ||||
-rw-r--r-- | celt/kiss_fft.h | 6 | ||||
-rw-r--r-- | celt/static_modes_fixed.h | 70 | ||||
-rw-r--r-- | celt/static_modes_float.h | 78 | ||||
-rw-r--r-- | src/opus_decoder.c | 894 | ||||
-rw-r--r-- | src/opus_demo.c | 58 | ||||
-rw-r--r-- | src/opus_multistream.c | 16 |
10 files changed, 659 insertions, 625 deletions
diff --git a/celt/_kiss_fft_guts.h b/celt/_kiss_fft_guts.h index d0631fa4..637ce2a0 100644 --- a/celt/_kiss_fft_guts.h +++ b/celt/_kiss_fft_guts.h @@ -120,28 +120,28 @@ #ifndef C_ADD #define C_ADD( res, a,b)\ do { \ - CHECK_OVERFLOW_OP((a).r,+,(b).r)\ - CHECK_OVERFLOW_OP((a).i,+,(b).i)\ - (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ + CHECK_OVERFLOW_OP((a).r,+,(b).r)\ + CHECK_OVERFLOW_OP((a).i,+,(b).i)\ + (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ }while(0) #define C_SUB( res, a,b)\ do { \ - CHECK_OVERFLOW_OP((a).r,-,(b).r)\ - CHECK_OVERFLOW_OP((a).i,-,(b).i)\ - (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ + CHECK_OVERFLOW_OP((a).r,-,(b).r)\ + CHECK_OVERFLOW_OP((a).i,-,(b).i)\ + (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ }while(0) #define C_ADDTO( res , a)\ do { \ - CHECK_OVERFLOW_OP((res).r,+,(a).r)\ - CHECK_OVERFLOW_OP((res).i,+,(a).i)\ - (res).r += (a).r; (res).i += (a).i;\ + CHECK_OVERFLOW_OP((res).r,+,(a).r)\ + CHECK_OVERFLOW_OP((res).i,+,(a).i)\ + (res).r += (a).r; (res).i += (a).i;\ }while(0) #define C_SUBFROM( res , a)\ do {\ - CHECK_OVERFLOW_OP((res).r,-,(a).r)\ - CHECK_OVERFLOW_OP((res).i,-,(a).i)\ - (res).r -= (a).r; (res).i -= (a).i; \ + CHECK_OVERFLOW_OP((res).r,-,(a).r)\ + CHECK_OVERFLOW_OP((res).i,-,(a).i)\ + (res).r -= (a).r; (res).i -= (a).i; \ }while(0) #endif /* C_ADD defined */ @@ -162,10 +162,10 @@ #endif #define kf_cexp(x,phase) \ - do{ \ - (x)->r = KISS_FFT_COS(phase);\ - (x)->i = KISS_FFT_SIN(phase);\ - }while(0) + do{ \ + (x)->r = KISS_FFT_COS(phase);\ + (x)->i = KISS_FFT_SIN(phase);\ + }while(0) #define kf_cexp2(x,phase) \ do{ \ diff --git a/celt/arch.h b/celt/arch.h index 7bd82777..48428c23 100644 --- a/celt/arch.h +++ b/celt/arch.h @@ -103,8 +103,8 @@ typedef opus_val32 celt_ener; #define VERY_LARGE16 ((opus_val16)32767) #define Q15_ONE ((opus_val16)32767) -#define SCALEIN(a) (a) -#define SCALEOUT(a) (a) +#define SCALEIN(a) (a) +#define SCALEOUT(a) (a) #ifdef FIXED_DEBUG #include "fixed_debug.h" @@ -192,8 +192,8 @@ typedef float celt_ener; #define DIV32_16(a,b) (((opus_val32)(a))/(opus_val16)(b)) #define DIV32(a,b) (((opus_val32)(a))/(opus_val32)(b)) -#define SCALEIN(a) ((a)*CELT_SIG_SCALE) -#define SCALEOUT(a) ((a)*(1/CELT_SIG_SCALE)) +#define SCALEIN(a) ((a)*CELT_SIG_SCALE) +#define SCALEOUT(a) ((a)*(1/CELT_SIG_SCALE)) #endif /* !FIXED_POINT */ diff --git a/celt/celt.c b/celt/celt.c index 3567680f..fce15591 100644 --- a/celt/celt.c +++ b/celt/celt.c @@ -2391,7 +2391,7 @@ int celt_decode_with_ec(CELTDecoder * restrict st, const unsigned char *data, in tell = ec_tell(dec); if (tell >= total_bits) - silence = 1; + silence = 1; else if (tell==1) silence = ec_dec_bit_logp(dec, 15); else diff --git a/celt/float_cast.h b/celt/float_cast.h index 1b3f1991..39f63d42 100644 --- a/celt/float_cast.h +++ b/celt/float_cast.h @@ -30,98 +30,98 @@ #define FLOAT_CAST_H /*============================================================================ -** On Intel Pentium processors (especially PIII and probably P4), converting -** from float to int is very slow. To meet the C specs, the code produced by -** most C compilers targeting Pentium needs to change the FPU rounding mode -** before the float to int conversion is performed. +** On Intel Pentium processors (especially PIII and probably P4), converting +** from float to int is very slow. To meet the C specs, the code produced by +** most C compilers targeting Pentium needs to change the FPU rounding mode +** before the float to int conversion is performed. ** -** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It -** is this flushing of the pipeline which is so slow. +** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It +** is this flushing of the pipeline which is so slow. ** -** Fortunately the ISO C99 specifications define the functions lrint, lrintf, -** llrint and llrintf which fix this problem as a side effect. +** Fortunately the ISO C99 specifications define the functions lrint, lrintf, +** llrint and llrintf which fix this problem as a side effect. ** -** On Unix-like systems, the configure process should have detected the -** presence of these functions. If they weren't found we have to replace them -** here with a standard C cast. +** On Unix-like systems, the configure process should have detected the +** presence of these functions. If they weren't found we have to replace them +** here with a standard C cast. */ -/* -** The C99 prototypes for lrint and lrintf are as follows: -** -** long int lrintf (float x) ; -** long int lrint (double x) ; +/* +** The C99 prototypes for lrint and lrintf are as follows: +** +** long int lrintf (float x) ; +** long int lrint (double x) ; */ -/* The presence of the required functions are detected during the configure -** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in -** the config.h file. +/* The presence of the required functions are detected during the configure +** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in +** the config.h file. */ #if (HAVE_LRINTF) -/* These defines enable functionality introduced with the 1999 ISO C -** standard. They must be defined before the inclusion of math.h to -** engage them. If optimisation is enabled, these functions will be -** inlined. With optimisation switched off, you have to link in the -** maths library using -lm. +/* These defines enable functionality introduced with the 1999 ISO C +** standard. They must be defined before the inclusion of math.h to +** engage them. If optimisation is enabled, these functions will be +** inlined. With optimisation switched off, you have to link in the +** maths library using -lm. */ -#define _ISOC9X_SOURCE 1 -#define _ISOC99_SOURCE 1 +#define _ISOC9X_SOURCE 1 +#define _ISOC99_SOURCE 1 -#define __USE_ISOC9X 1 -#define __USE_ISOC99 1 +#define __USE_ISOC9X 1 +#define __USE_ISOC99 1 -#include <math.h> +#include <math.h> #define float2int(x) lrintf(x) #elif (defined(HAVE_LRINT)) -#define _ISOC9X_SOURCE 1 -#define _ISOC99_SOURCE 1 +#define _ISOC9X_SOURCE 1 +#define _ISOC99_SOURCE 1 -#define __USE_ISOC9X 1 -#define __USE_ISOC99 1 +#define __USE_ISOC9X 1 +#define __USE_ISOC99 1 -#include <math.h> +#include <math.h> #define float2int(x) lrint(x) #elif (defined (WIN64) || defined (_WIN64)) - #include <xmmintrin.h> + #include <xmmintrin.h> - __inline long int float2int(float value) - { - return _mm_cvtss_si32(_mm_load_ss(&value)); - } + __inline long int float2int(float value) + { + return _mm_cvtss_si32(_mm_load_ss(&value)); + } #elif (defined (WIN32) || defined (_WIN32)) - #include <math.h> - - /* Win32 doesn't seem to have these functions. - ** Therefore implement inline versions of these functions here. - */ - - __inline long int - float2int (float flt) - { int intgr; - - _asm - { fld flt - fistp intgr - } ; - - return intgr ; - } + #include <math.h> + + /* Win32 doesn't seem to have these functions. + ** Therefore implement inline versions of these functions here. + */ + + __inline long int + float2int (float flt) + { int intgr; + + _asm + { fld flt + fistp intgr + } ; + + return intgr ; + } #else #if (defined(__GNUC__) && defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) /* supported by gcc in C99 mode, but not by all other compilers */ - #warning "Don't have the functions lrint() and lrintf ()." - #warning "Replacing these functions with a standard C cast." + #warning "Don't have the functions lrint() and lrintf ()." + #warning "Replacing these functions with a standard C cast." #endif /* __STDC_VERSION__ >= 199901L */ - #include <math.h> - #define float2int(flt) ((int)(floor(.5+flt))) + #include <math.h> + #define float2int(flt) ((int)(floor(.5+flt))) #endif static inline opus_int16 FLOAT2INT16(float x) diff --git a/celt/kiss_fft.h b/celt/kiss_fft.h index 95adf055..fe5a7b4d 100644 --- a/celt/kiss_fft.h +++ b/celt/kiss_fft.h @@ -54,12 +54,12 @@ extern "C" { # include <xmmintrin.h> # define kiss_fft_scalar __m128 #define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes) -#else +#else #define KISS_FFT_MALLOC opus_alloc -#endif +#endif #ifdef FIXED_POINT -#include "arch.h" +#include "arch.h" # define kiss_fft_scalar opus_int32 # define kiss_twiddle_scalar opus_int16 diff --git a/celt/static_modes_fixed.h b/celt/static_modes_fixed.h index 98f27559..216df9e6 100644 --- a/celt/static_modes_fixed.h +++ b/celt/static_modes_fixed.h @@ -425,44 +425,44 @@ static const opus_int16 fft_bitrev60[60] = { #ifndef FFT_STATE48000_960_0 #define FFT_STATE48000_960_0 static const kiss_fft_state fft_state48000_960_0 = { -480, /* nfft */ --1, /* shift */ -{4, 120, 4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev480, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ +480, /* nfft */ +-1, /* shift */ +{4, 120, 4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev480, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ }; #endif #ifndef FFT_STATE48000_960_1 #define FFT_STATE48000_960_1 static const kiss_fft_state fft_state48000_960_1 = { -240, /* nfft */ -1, /* shift */ -{4, 60, 4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev240, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ +240, /* nfft */ +1, /* shift */ +{4, 60, 4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev240, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ }; #endif #ifndef FFT_STATE48000_960_2 #define FFT_STATE48000_960_2 static const kiss_fft_state fft_state48000_960_2 = { -120, /* nfft */ -2, /* shift */ -{4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev120, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ +120, /* nfft */ +2, /* shift */ +{4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev120, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ }; #endif #ifndef FFT_STATE48000_960_3 #define FFT_STATE48000_960_3 static const kiss_fft_state fft_state48000_960_3 = { -60, /* nfft */ -3, /* shift */ -{4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev60, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ +60, /* nfft */ +3, /* shift */ +{4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev60, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ }; #endif @@ -571,21 +571,21 @@ static const opus_val16 mdct_twiddles960[481] = { #endif static const CELTMode mode48000_960_120 = { -48000, /* Fs */ -120, /* overlap */ -21, /* nbEBands */ -21, /* effEBands */ -{27853, 0, 4096, 8192, }, /* preemph */ -eband5ms, /* eBands */ -3, /* maxLM */ -8, /* nbShortMdcts */ -120, /* shortMdctSize */ -11, /* nbAllocVectors */ -band_allocation, /* allocVectors */ -logN400, /* logN */ -window120, /* window */ -{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960}, /* mdct */ -{392, cache_index50, cache_bits50, cache_caps50}, /* cache */ +48000, /* Fs */ +120, /* overlap */ +21, /* nbEBands */ +21, /* effEBands */ +{27853, 0, 4096, 8192, }, /* preemph */ +eband5ms, /* eBands */ +3, /* maxLM */ +8, /* nbShortMdcts */ +120, /* shortMdctSize */ +11, /* nbAllocVectors */ +band_allocation, /* allocVectors */ +logN400, /* logN */ +window120, /* window */ +{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960}, /* mdct */ +{392, cache_index50, cache_bits50, cache_caps50}, /* cache */ }; /* List of all the available modes */ diff --git a/celt/static_modes_float.h b/celt/static_modes_float.h index fcb24f4b..5d7e7b8e 100644 --- a/celt/static_modes_float.h +++ b/celt/static_modes_float.h @@ -425,48 +425,48 @@ static const opus_int16 fft_bitrev60[60] = { #ifndef FFT_STATE48000_960_0 #define FFT_STATE48000_960_0 static const kiss_fft_state fft_state48000_960_0 = { -480, /* nfft */ -0.002083333f, /* scale */ --1, /* shift */ -{4, 120, 4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev480, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ +480, /* nfft */ +0.002083333f, /* scale */ +-1, /* shift */ +{4, 120, 4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev480, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ }; #endif #ifndef FFT_STATE48000_960_1 #define FFT_STATE48000_960_1 static const kiss_fft_state fft_state48000_960_1 = { -240, /* nfft */ -0.004166667f, /* scale */ -1, /* shift */ -{4, 60, 4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev240, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ +240, /* nfft */ +0.004166667f, /* scale */ +1, /* shift */ +{4, 60, 4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev240, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ }; #endif #ifndef FFT_STATE48000_960_2 #define FFT_STATE48000_960_2 static const kiss_fft_state fft_state48000_960_2 = { -120, /* nfft */ -0.008333333f, /* scale */ -2, /* shift */ -{4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev120, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ +120, /* nfft */ +0.008333333f, /* scale */ +2, /* shift */ +{4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev120, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ }; #endif #ifndef FFT_STATE48000_960_3 #define FFT_STATE48000_960_3 static const kiss_fft_state fft_state48000_960_3 = { -60, /* nfft */ -0.016666667f, /* scale */ -3, /* shift */ -{4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev60, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ +60, /* nfft */ +0.016666667f, /* scale */ +3, /* shift */ +{4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev60, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ }; #endif @@ -575,21 +575,21 @@ static const opus_val16 mdct_twiddles960[481] = { #endif static const CELTMode mode48000_960_120 = { -48000, /* Fs */ -120, /* overlap */ -21, /* nbEBands */ -21, /* effEBands */ -{0.85000610f, 0.0000000f, 1.0000000f, 1.0000000f, }, /* preemph */ -eband5ms, /* eBands */ -3, /* maxLM */ -8, /* nbShortMdcts */ -120, /* shortMdctSize */ -11, /* nbAllocVectors */ -band_allocation, /* allocVectors */ -logN400, /* logN */ -window120, /* window */ -{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960}, /* mdct */ -{392, cache_index50, cache_bits50, cache_caps50}, /* cache */ +48000, /* Fs */ +120, /* overlap */ +21, /* nbEBands */ +21, /* effEBands */ +{0.85000610f, 0.0000000f, 1.0000000f, 1.0000000f, }, /* preemph */ +eband5ms, /* eBands */ +3, /* maxLM */ +8, /* nbShortMdcts */ +120, /* shortMdctSize */ +11, /* nbAllocVectors */ +band_allocation, /* allocVectors */ +logN400, /* logN */ +window120, /* window */ +{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960}, /* mdct */ +{392, cache_index50, cache_bits50, cache_caps50}, /* cache */ }; /* List of all the available modes */ diff --git a/src/opus_decoder.c b/src/opus_decoder.c index 4f4d6487..2fbe13f2 100644 --- a/src/opus_decoder.c +++ b/src/opus_decoder.c @@ -64,7 +64,7 @@ struct OpusDecoder { #ifdef FIXED_POINT static inline opus_int16 SAT16(opus_int32 x) { - return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x; + return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x; }; #endif @@ -89,13 +89,15 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels) CELTDecoder *celt_dec; int ret, silkDecSizeBytes; - if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)) + if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000) + || (channels!=1&&channels!=2)) return OPUS_BAD_ARG; OPUS_CLEAR((char*)st, opus_decoder_get_size(channels)); /* Initialize SILK encoder */ ret = silk_Get_Decoder_Size(&silkDecSizeBytes); - if(ret)return OPUS_INTERNAL_ERROR; + if (ret) + return OPUS_INTERNAL_ERROR; silkDecSizeBytes = align(silkDecSizeBytes); st->silk_dec_offset = align(sizeof(OpusDecoder)); @@ -127,7 +129,8 @@ OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error) { int ret; OpusDecoder *st; - if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)) + if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000) + || (channels!=1&&channels!=2)) { if (error) *error = OPUS_BAD_ARG; @@ -151,354 +154,361 @@ OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error) return st; } -static void smooth_fade(const opus_val16 *in1, const opus_val16 *in2, opus_val16 *out, - int overlap, int channels, const opus_val16 *window, opus_int32 Fs) +static void smooth_fade(const opus_val16 *in1, const opus_val16 *in2, + opus_val16 *out, int overlap, int channels, + const opus_val16 *window, opus_int32 Fs) { - int i, c; - int inc = 48000/Fs; - for (c=0;c<channels;c++) - { - for (i=0;i<overlap;i++) - { - opus_val16 w = MULT16_16_Q15(window[i*inc], window[i*inc]); - out[i*channels+c] = SHR32(MAC16_16(MULT16_16(w,in2[i*channels+c]), - Q15ONE-w, in1[i*channels+c]), 15); - } - } + int i, c; + int inc = 48000/Fs; + for (c=0;c<channels;c++) + { + for (i=0;i<overlap;i++) + { + opus_val16 w = MULT16_16_Q15(window[i*inc], window[i*inc]); + out[i*channels+c] = SHR32(MAC16_16(MULT16_16(w,in2[i*channels+c]), + Q15ONE-w, in1[i*channels+c]), 15); + } + } } static int opus_packet_get_mode(const unsigned char *data) { - int mode; - if (data[0]&0x80) - { - mode = MODE_CELT_ONLY; - } else if ((data[0]&0x60) == 0x60) - { - mode = MODE_HYBRID; - } else { - - mode = MODE_SILK_ONLY; - } - return mode; + int mode; + if (data[0]&0x80) + { + mode = MODE_CELT_ONLY; + } else if ((data[0]&0x60) == 0x60) + { + mode = MODE_HYBRID; + } else { + mode = MODE_SILK_ONLY; + } + return mode; } static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, - int len, opus_val16 *pcm, int frame_size, int decode_fec) + int len, opus_val16 *pcm, int frame_size, int decode_fec) { - void *silk_dec; - CELTDecoder *celt_dec; - int i, silk_ret=0, celt_ret=0; - ec_dec dec; - opus_int32 silk_frame_size; - VARDECL(opus_int16, pcm_silk); - VARDECL(opus_val16, pcm_transition); - VARDECL(opus_val16, redundant_audio); - - int audiosize; - int mode; - int transition=0; - int start_band; - int redundancy=0; - int redundancy_bytes = 0; - int celt_to_silk=0; - int c; - int F2_5, F5, F10, F20; - const opus_val16 *window; - opus_uint32 redundant_rng = 0; - ALLOC_STACK; - - silk_dec = (char*)st+st->silk_dec_offset; - celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); - F20 = st->Fs/50; - F10 = F20>>1; - F5 = F10>>1; - F2_5 = F5>>1; - if (frame_size < F2_5) - return OPUS_BUFFER_TOO_SMALL; - /* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */ - if (len<=1) - { - data = NULL; - /* In that case, don't conceal more than what the ToC says */ - frame_size = IMIN(frame_size, st->frame_size); - } - if (data != NULL) - { - audiosize = st->frame_size; - mode = st->mode; - ec_dec_init(&dec,(unsigned char*)data,len); - } else { - audiosize = frame_size; - - if (st->prev_mode == 0) - { - /* If we haven't got any packet yet, all we can do is return zeros */ - for (i=0;i<audiosize*st->channels;i++) - pcm[i] = 0; - RESTORE_STACK; - return audiosize; - } else { - mode = st->prev_mode; - } - } - - ALLOC(pcm_transition, F5*st->channels, opus_val16); - - if (data!=NULL && st->prev_mode > 0 && ( - (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy) - || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ) - ) - { - transition = 1; - if (mode == MODE_CELT_ONLY) - opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); - } - if (audiosize > frame_size) - { - /*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosize, frame_size, mode);*/ - RESTORE_STACK; - return OPUS_BAD_ARG; - } else { - frame_size = audiosize; - } - - ALLOC(pcm_silk, IMAX(F10, frame_size)*st->channels, opus_int16); - ALLOC(redundant_audio, F5*st->channels, opus_val16); - - /* SILK processing */ - if (mode != MODE_CELT_ONLY) - { - int lost_flag, decoded_samples; - opus_int16 *pcm_ptr = pcm_silk; - - if (st->prev_mode==MODE_CELT_ONLY) - silk_InitDecoder( silk_dec ); - - /* The SILK PLC cannot support produce frames of less than 10 ms */ - st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs); - - if (data != NULL) - { - st->DecControl.nChannelsInternal = st->stream_channels; - if( mode == MODE_SILK_ONLY ) { - if( st->bandwidth == OPUS_BANDWIDTH_NARROWBAND ) { - st->DecControl.internalSampleRate = 8000; - } else if( st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) { - st->DecControl.internalSampleRate = 12000; - } else if( st->bandwidth == OPUS_BANDWIDTH_WIDEBAND ) { - st->DecControl.internalSampleRate = 16000; - } else { - st->DecControl.internalSampleRate = 16000; - silk_assert( 0 ); - } - } else { - /* Hybrid mode */ - st->DecControl.internalSampleRate = 16000; - } - } + void *silk_dec; + CELTDecoder *celt_dec; + int i, silk_ret=0, celt_ret=0; + ec_dec dec; + opus_int32 silk_frame_size; + VARDECL(opus_int16, pcm_silk); + VARDECL(opus_val16, pcm_transition); + VARDECL(opus_val16, redundant_audio); + + int audiosize; + int mode; + int transition=0; + int start_band; + int redundancy=0; + int redundancy_bytes = 0; + int celt_to_silk=0; + int c; + int F2_5, F5, F10, F20; + const opus_val16 *window; + opus_uint32 redundant_rng = 0; + ALLOC_STACK; - lost_flag = data == NULL ? 1 : 2 * decode_fec; - decoded_samples = 0; - do { - /* Call SILK decoder */ - int first_frame = decoded_samples == 0; - silk_ret = silk_Decode( silk_dec, &st->DecControl, - lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size ); - if( silk_ret ) { - if (lost_flag) { - /* PLC failure should not be fatal */ - silk_frame_size = frame_size; - for (i=0;i<frame_size*st->channels;i++) - pcm_ptr[i] = 0; - } else { - RESTORE_STACK; - return OPUS_INVALID_PACKET; - } - } - pcm_ptr += silk_frame_size * st->channels; - decoded_samples += silk_frame_size; - } while( decoded_samples < frame_size ); - } - - start_band = 0; - if (!decode_fec && mode != MODE_CELT_ONLY && data != NULL && ec_tell(&dec)+17+20*(st->mode == MODE_HYBRID) <= 8*len) - { - /* Check if we have a redundant 0-8 kHz band */ - if (mode == MODE_HYBRID) - redundancy = ec_dec_bit_logp(&dec, 12); - else - redundancy = 1; - if (redundancy) - { - celt_to_silk = ec_dec_bit_logp(&dec, 1); - /* redundancy_bytes will be at least two, in the non-hybrid case due to the ec_tell() check above */ - redundancy_bytes = mode==MODE_HYBRID ? (opus_int32)ec_dec_uint(&dec, 256)+2 : len-((ec_tell(&dec)+7)>>3); - len -= redundancy_bytes; - /* This is a sanity check. It should never happen for a valid packet, - so the exact behaviour is not normative. */ - if (len*8 < ec_tell(&dec)) - { - len=0; - redundancy_bytes=0; - redundancy = 0; - } - /* Shrink decoder because of raw bits */ - dec.storage -= redundancy_bytes; + silk_dec = (char*)st+st->silk_dec_offset; + celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); + F20 = st->Fs/50; + F10 = F20>>1; + F5 = F10>>1; + F2_5 = F5>>1; + if (frame_size < F2_5) + return OPUS_BUFFER_TOO_SMALL; + /* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */ + if (len<=1) + { + data = NULL; + /* In that case, don't conceal more than what the ToC says */ + frame_size = IMIN(frame_size, st->frame_size); + } + if (data != NULL) + { + audiosize = st->frame_size; + mode = st->mode; + ec_dec_init(&dec,(unsigned char*)data,len); + } else { + audiosize = frame_size; + + if (st->prev_mode == 0) + { + /* If we haven't got any packet yet, all we can do is return zeros */ + for (i=0;i<audiosize*st->channels;i++) + pcm[i] = 0; + RESTORE_STACK; + return audiosize; + } else { + mode = st->prev_mode; + } + } + + ALLOC(pcm_transition, F5*st->channels, opus_val16); + + if (data!=NULL && st->prev_mode > 0 && ( + (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy) + || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ) + ) + { + transition = 1; + if (mode == MODE_CELT_ONLY) + opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); + } + if (audiosize > frame_size) + { + /*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosize, frame_size, mode);*/ + RESTORE_STACK; + return OPUS_BAD_ARG; + } else { + frame_size = audiosize; + } + + ALLOC(pcm_silk, IMAX(F10, frame_size)*st->channels, opus_int16); + ALLOC(redundant_audio, F5*st->channels, opus_val16); + + /* SILK processing */ + if (mode != MODE_CELT_ONLY) + { + int lost_flag, decoded_samples; + opus_int16 *pcm_ptr = pcm_silk; + + if (st->prev_mode==MODE_CELT_ONLY) + silk_InitDecoder( silk_dec ); + + /* The SILK PLC cannot support produce frames of less than 10 ms */ + st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs); + + if (data != NULL) + { + st->DecControl.nChannelsInternal = st->stream_channels; + if( mode == MODE_SILK_ONLY ) { + if( st->bandwidth == OPUS_BANDWIDTH_NARROWBAND ) { + st->DecControl.internalSampleRate = 8000; + } else if( st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) { + st->DecControl.internalSampleRate = 12000; + } else if( st->bandwidth == OPUS_BANDWIDTH_WIDEBAND ) { + st->DecControl.internalSampleRate = 16000; + } else { + st->DecControl.internalSampleRate = 16000; + silk_assert( 0 ); + } + } else { + /* Hybrid mode */ + st->DecControl.internalSampleRate = 16000; } - } - if (mode != MODE_CELT_ONLY) - start_band = 17; - - { - int endband=21; - - switch(st->bandwidth) - { - case OPUS_BANDWIDTH_NARROWBAND: - endband = 13; - break; - case OPUS_BANDWIDTH_MEDIUMBAND: - case OPUS_BANDWIDTH_WIDEBAND: - endband = 17; - break; - case OPUS_BANDWIDTH_SUPERWIDEBAND: - endband = 19; - break; - case OPUS_BANDWIDTH_FULLBAND: - endband = 21; - break; + } + + lost_flag = data == NULL ? 1 : 2 * decode_fec; + decoded_samples = 0; + do { + /* Call SILK decoder */ + int first_frame = decoded_samples == 0; + silk_ret = silk_Decode( silk_dec, &st->DecControl, + lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size ); + if( silk_ret ) { + if (lost_flag) { + /* PLC failure should not be fatal */ + silk_frame_size = frame_size; + for (i=0;i<frame_size*st->channels;i++) + pcm_ptr[i] = 0; + } else { + RESTORE_STACK; + return OPUS_INVALID_PACKET; + } } - celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband)); - celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels)); - } - - if (redundancy) - transition = 0; - - if (transition && mode != MODE_CELT_ONLY) - opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); - - /* 5 ms redundant frame for CELT->SILK*/ - if (redundancy && celt_to_silk) - { - celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); - celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL); - celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); - } - - /* MUST be after PLC */ - celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band)); - - if (mode != MODE_SILK_ONLY) - { - int celt_frame_size = IMIN(F20, frame_size); - /* Make sure to discard any previous CELT state */ - if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy) - celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); - /* Decode CELT */ - celt_ret = celt_decode_with_ec(celt_dec, decode_fec?NULL:data, len, pcm, celt_frame_size, &dec); - } else { - unsigned char silence[2] = {0xFF, 0xFF}; - for (i=0;i<frame_size*st->channels;i++) - pcm[i] = 0; - /* For hybrid -> SILK transitions, we let the CELT MDCT do a fade-out by decoding a silence frame */ - if (st->prev_mode == MODE_HYBRID) - { - celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); - celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL); - } - } - - if (mode != MODE_CELT_ONLY) - { + pcm_ptr += silk_frame_size * st->channels; + decoded_samples += silk_frame_size; + } while( decoded_samples < frame_size ); + } + + start_band = 0; + if (!decode_fec && mode != MODE_CELT_ONLY && data != NULL + && ec_tell(&dec)+17+20*(st->mode == MODE_HYBRID) <= 8*len) + { + /* Check if we have a redundant 0-8 kHz band */ + if (mode == MODE_HYBRID) + redundancy = ec_dec_bit_logp(&dec, 12); + else + redundancy = 1; + if (redundancy) + { + celt_to_silk = ec_dec_bit_logp(&dec, 1); + /* redundancy_bytes will be at least two, in the non-hybrid + case due to the ec_tell() check above */ + redundancy_bytes = mode==MODE_HYBRID ? + (opus_int32)ec_dec_uint(&dec, 256)+2 : + len-((ec_tell(&dec)+7)>>3); + len -= redundancy_bytes; + /* This is a sanity check. It should never happen for a valid + packet, so the exact behaviour is not normative. */ + if (len*8 < ec_tell(&dec)) + { + len = 0; + redundancy_bytes = 0; + redundancy = 0; + } + /* Shrink decoder because of raw bits */ + dec.storage -= redundancy_bytes; + } + } + if (mode != MODE_CELT_ONLY) + start_band = 17; + + { + int endband=21; + + switch(st->bandwidth) + { + case OPUS_BANDWIDTH_NARROWBAND: + endband = 13; + break; + case OPUS_BANDWIDTH_MEDIUMBAND: + case OPUS_BANDWIDTH_WIDEBAND: + endband = 17; + break; + case OPUS_BANDWIDTH_SUPERWIDEBAND: + endband = 19; + break; + case OPUS_BANDWIDTH_FULLBAND: + endband = 21; + break; + } + celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband)); + celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels)); + } + + if (redundancy) + transition = 0; + + if (transition && mode != MODE_CELT_ONLY) + opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); + + /* 5 ms redundant frame for CELT->SILK*/ + if (redundancy && celt_to_silk) + { + celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); + celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, + redundant_audio, F5, NULL); + celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); + } + + /* MUST be after PLC */ + celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band)); + + if (mode != MODE_SILK_ONLY) + { + int celt_frame_size = IMIN(F20, frame_size); + /* Make sure to discard any previous CELT state */ + if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy) + celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); + /* Decode CELT */ + celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data, + len, pcm, celt_frame_size, &dec); + } else { + unsigned char silence[2] = {0xFF, 0xFF}; + for (i=0;i<frame_size*st->channels;i++) + pcm[i] = 0; + /* For hybrid -> SILK transitions, we let the CELT MDCT + do a fade-out by decoding a silence frame */ + if (st->prev_mode == MODE_HYBRID) + { + celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); + celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL); + } + } + + if (mode != MODE_CELT_ONLY) + { #ifdef FIXED_POINT - for (i=0;i<frame_size*st->channels;i++) - pcm[i] = SAT16(pcm[i] + pcm_silk[i]); + for (i=0;i<frame_size*st->channels;i++) + pcm[i] = SAT16(pcm[i] + pcm_silk[i]); #else - for (i=0;i<frame_size*st->channels;i++) - pcm[i] = pcm[i] + (opus_val16)((1./32768.)*pcm_silk[i]); + for (i=0;i<frame_size*st->channels;i++) + pcm[i] = pcm[i] + (opus_val16)((1./32768.)*pcm_silk[i]); #endif - } - - { - const CELTMode *celt_mode; - celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode)); - window = celt_mode->window; - } - - /* 5 ms redundant frame for SILK->CELT */ - if (redundancy && !celt_to_silk) - { - celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); - celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); - - celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL); - celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); - smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5, - pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs); - } - if (redundancy && celt_to_silk) - { - for (c=0;c<st->channels;c++) - { - for (i=0;i<F2_5;i++) - pcm[st->channels*i+c] = redundant_audio[st->channels*i+c]; - } - smooth_fade(redundant_audio+st->channels*F2_5, pcm+st->channels*F2_5, - pcm+st->channels*F2_5, F2_5, st->channels, window, st->Fs); - } - if (transition) - { - if (audiosize >= F5) - { - for (i=0;i<st->channels*F2_5;i++) - pcm[i] = pcm_transition[i]; - smooth_fade(pcm_transition+st->channels*F2_5, pcm+st->channels*F2_5, - pcm+st->channels*F2_5, F2_5, - st->channels, window, st->Fs); - } else { - /* Not enough time to do a clean transition, but we do it anyway - This will not preserve amplitude perfectly and may introduce - a bit of temporal aliasing, but it shouldn't be too bad and - that's pretty much the best we can do. In any case, generating this - transition it pretty silly in the first place */ - smooth_fade(pcm_transition, pcm, - pcm, F2_5, - st->channels, window, st->Fs); - } - } - - if (len <= 1) - st->rangeFinal = 0; - else - st->rangeFinal = dec.rng ^ redundant_rng; - - st->prev_mode = mode; - st->prev_redundancy = redundancy && !celt_to_silk; - RESTORE_STACK; - return celt_ret<0 ? celt_ret : audiosize; + } + + { + const CELTMode *celt_mode; + celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode)); + window = celt_mode->window; + } + + /* 5 ms redundant frame for SILK->CELT */ + if (redundancy && !celt_to_silk) + { + celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); + celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); + + celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL); + celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); + smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5, + pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs); + } + if (redundancy && celt_to_silk) + { + for (c=0;c<st->channels;c++) + { + for (i=0;i<F2_5;i++) + pcm[st->channels*i+c] = redundant_audio[st->channels*i+c]; + } + smooth_fade(redundant_audio+st->channels*F2_5, pcm+st->channels*F2_5, + pcm+st->channels*F2_5, F2_5, st->channels, window, st->Fs); + } + if (transition) + { + if (audiosize >= F5) + { + for (i=0;i<st->channels*F2_5;i++) + pcm[i] = pcm_transition[i]; + smooth_fade(pcm_transition+st->channels*F2_5, pcm+st->channels*F2_5, + pcm+st->channels*F2_5, F2_5, + st->channels, window, st->Fs); + } else { + /* Not enough time to do a clean transition, but we do it anyway + This will not preserve amplitude perfectly and may introduce + a bit of temporal aliasing, but it shouldn't be too bad and + that's pretty much the best we can do. In any case, generating this + transition it pretty silly in the first place */ + smooth_fade(pcm_transition, pcm, + pcm, F2_5, + st->channels, window, st->Fs); + } + } + + if (len <= 1) + st->rangeFinal = 0; + else + st->rangeFinal = dec.rng ^ redundant_rng; + + st->prev_mode = mode; + st->prev_redundancy = redundancy && !celt_to_silk; + RESTORE_STACK; + return celt_ret < 0 ? celt_ret : audiosize; } static int parse_size(const unsigned char *data, int len, short *size) { - if (len<1) - { - *size = -1; - return -1; - } else if (data[0]<252) - { - *size = data[0]; - return 1; - } else if (len<2) - { - *size = -1; - return -1; - } else { - *size = 4*data[1] + data[0]; - return 2; - } + if (len<1) + { + *size = -1; + return -1; + } else if (data[0]<252) + { + *size = data[0]; + return 1; + } else if (len<2) + { + *size = -1; + return -1; + } else { + *size = 4*data[1] + data[0]; + return 2; + } } static int opus_packet_parse_impl(const unsigned char *data, int len, @@ -528,7 +538,7 @@ static int opus_packet_parse_impl(const unsigned char *data, int len, case 0: count=1; break; - /* Two CBR frames */ + /* Two CBR frames */ case 1: count=2; cbr = 1; @@ -539,7 +549,7 @@ static int opus_packet_parse_impl(const unsigned char *data, int len, size[0] = last_size = len/2; } break; - /* Two VBR frames */ + /* Two VBR frames */ case 2: count = 2; bytes = parse_size(data, len, size); @@ -549,7 +559,7 @@ static int opus_packet_parse_impl(const unsigned char *data, int len, data += bytes; last_size = len-size[0]; break; - /* Multiple CBR/VBR frames (from 0 to 120 ms) */ + /* Multiple CBR/VBR frames (from 0 to 120 ms) */ case 3: if (len<1) return OPUS_INVALID_PACKET; @@ -557,7 +567,7 @@ static int opus_packet_parse_impl(const unsigned char *data, int len, ch = *data++; count = ch&0x3F; if (count <= 0 || framesize*count > 5760) - return OPUS_INVALID_PACKET; + return OPUS_INVALID_PACKET; len--; /* Padding flag is bit 6 */ if (ch&0x40) @@ -623,11 +633,10 @@ static int opus_packet_parse_impl(const unsigned char *data, int len, } else { /* Because it's not encoded explicitly, it's possible the size of the - last packet (or all the packets, for the CBR case) is larger than - 1275. - Reject them here.*/ + last packet (or all the packets, for the CBR case) is larger than + 1275. Reject them here.*/ if (last_size > 1275) - return OPUS_INVALID_PACKET; + return OPUS_INVALID_PACKET; size[count-1] = last_size; } @@ -653,55 +662,57 @@ int opus_packet_parse(const unsigned char *data, int len, unsigned char *out_toc, const unsigned char *frames[48], short size[48], int *payload_offset) { - return opus_packet_parse_impl(data, len, 0, - out_toc, frames, size, payload_offset); + return opus_packet_parse_impl(data, len, 0, out_toc, + frames, size, payload_offset); } int opus_decode_native(OpusDecoder *st, const unsigned char *data, - int len, opus_val16 *pcm, int frame_size, int decode_fec, int self_delimited, int *packet_offset) + int len, opus_val16 *pcm, int frame_size, int decode_fec, + int self_delimited, int *packet_offset) { - int i, nb_samples; - int count, offset; - unsigned char toc; - int tot_offset; - /* 48 x 2.5 ms = 120 ms */ - short size[48]; - if (decode_fec<0 || decode_fec>1)return OPUS_BAD_ARG; - if (len==0 || data==NULL) - return opus_decode_frame(st, NULL, 0, pcm, frame_size, 0); - else if (len<0) - return OPUS_BAD_ARG; - - tot_offset = 0; - st->mode = opus_packet_get_mode(data); - st->bandwidth = opus_packet_get_bandwidth(data); - st->frame_size = opus_packet_get_samples_per_frame(data, st->Fs); - st->stream_channels = opus_packet_get_nb_channels(data); - - count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset); - if (count < 0) - return count; - - data += offset; - tot_offset += offset; - - if (count*st->frame_size > frame_size) - return OPUS_BUFFER_TOO_SMALL; - nb_samples=0; - for (i=0;i<count;i++) - { - int ret; - ret = opus_decode_frame(st, data, size[i], pcm, frame_size-nb_samples, decode_fec); - if (ret<0) - return ret; - data += size[i]; - tot_offset += size[i]; - pcm += ret*st->channels; - nb_samples += ret; - } - if (packet_offset != NULL) - *packet_offset = tot_offset; - return nb_samples; + int i, nb_samples; + int count, offset; + unsigned char toc; + int tot_offset; + /* 48 x 2.5 ms = 120 ms */ + short size[48]; + if (decode_fec<0 || decode_fec>1) + return OPUS_BAD_ARG; + if (len==0 || data==NULL) + return opus_decode_frame(st, NULL, 0, pcm, frame_size, 0); + else if (len<0) + return OPUS_BAD_ARG; + + tot_offset = 0; + st->mode = opus_packet_get_mode(data); + st->bandwidth = opus_packet_get_bandwidth(data); + st->frame_size = opus_packet_get_samples_per_frame(data, st->Fs); + st->stream_channels = opus_packet_get_nb_channels(data); + + count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset); + if (count < 0) + return count; + + data += offset; + tot_offset += offset; + + if (count*st->frame_size > frame_size) + return OPUS_BUFFER_TOO_SMALL; + nb_samples=0; + for (i=0;i<count;i++) + { + int ret; + ret = opus_decode_frame(st, data, size[i], pcm, frame_size-nb_samples, decode_fec); + if (ret<0) + return ret; + data += size[i]; + tot_offset += size[i]; + pcm += ret*st->channels; + nb_samples += ret; + } + if (packet_offset != NULL) + *packet_offset = tot_offset; + return nb_samples; } #ifdef FIXED_POINT @@ -755,7 +766,7 @@ int opus_decode(OpusDecoder *st, const unsigned char *data, } int opus_decode_float(OpusDecoder *st, const unsigned char *data, - int len, opus_val16 *pcm, int frame_size, int decode_fec) + int len, opus_val16 *pcm, int frame_size, int decode_fec) { return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL); } @@ -827,78 +838,79 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) void opus_decoder_destroy(OpusDecoder *st) { - opus_free(st); + opus_free(st); } int opus_packet_get_bandwidth(const unsigned char *data) { - int bandwidth; - if (data[0]&0x80) - { - bandwidth = OPUS_BANDWIDTH_MEDIUMBAND + ((data[0]>>5)&0x3); - if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) - bandwidth = OPUS_BANDWIDTH_NARROWBAND; - } else if ((data[0]&0x60) == 0x60) - { - bandwidth = (data[0]&0x10) ? OPUS_BANDWIDTH_FULLBAND : OPUS_BANDWIDTH_SUPERWIDEBAND; - } else { - - bandwidth = OPUS_BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3); - } - return bandwidth; + int bandwidth; + if (data[0]&0x80) + { + bandwidth = OPUS_BANDWIDTH_MEDIUMBAND + ((data[0]>>5)&0x3); + if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) + bandwidth = OPUS_BANDWIDTH_NARROWBAND; + } else if ((data[0]&0x60) == 0x60) + { + bandwidth = (data[0]&0x10) ? OPUS_BANDWIDTH_FULLBAND : + OPUS_BANDWIDTH_SUPERWIDEBAND; + } else { + bandwidth = OPUS_BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3); + } + return bandwidth; } -int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs) +int opus_packet_get_samples_per_frame(const unsigned char *data, + opus_int32 Fs) { - int audiosize; - if (data[0]&0x80) - { - audiosize = ((data[0]>>3)&0x3); - audiosize = (Fs<<audiosize)/400; - } else if ((data[0]&0x60) == 0x60) - { - audiosize = (data[0]&0x08) ? Fs/50 : Fs/100; - } else { - - audiosize = ((data[0]>>3)&0x3); - if (audiosize == 3) - audiosize = Fs*60/1000; - else - audiosize = (Fs<<audiosize)/100; - } - return audiosize; + int audiosize; + if (data[0]&0x80) + { + audiosize = ((data[0]>>3)&0x3); + audiosize = (Fs<<audiosize)/400; + } else if ((data[0]&0x60) == 0x60) + { + audiosize = (data[0]&0x08) ? Fs/50 : Fs/100; + } else { + audiosize = ((data[0]>>3)&0x3); + if (audiosize == 3) + audiosize = Fs*60/1000; + else + audiosize = (Fs<<audiosize)/100; + } + return audiosize; } int opus_packet_get_nb_channels(const unsigned char *data) { - return (data[0]&0x4) ? 2 : 1; + return (data[0]&0x4) ? 2 : 1; } int opus_packet_get_nb_frames(const unsigned char packet[], int len) { - int count; - if (len<1) - return OPUS_BAD_ARG; - count = packet[0]&0x3; - if (count==0) - return 1; - else if (count!=3) - return 2; - else if (len<2) - return OPUS_INVALID_PACKET; - else - return packet[1]&0x3F; + int count; + if (len<1) + return OPUS_BAD_ARG; + count = packet[0]&0x3; + if (count==0) + return 1; + else if (count!=3) + return 2; + else if (len<2) + return OPUS_INVALID_PACKET; + else + return packet[1]&0x3F; } -int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], int len) +int opus_decoder_get_nb_samples(const OpusDecoder *dec, + const unsigned char packet[], int len) { - int samples; - int count = opus_packet_get_nb_frames(packet, len); - samples = count*opus_packet_get_samples_per_frame(packet, dec->Fs); - /* Can't have more than 120 ms */ - if (samples*25 > dec->Fs*3) - return OPUS_INVALID_PACKET; - else - return samples; + int samples; + int count = opus_packet_get_nb_frames(packet, len); + samples = count*opus_packet_get_samples_per_frame(packet, dec->Fs); + /* Can't have more than 120 ms */ + if (samples*25 > dec->Fs*3) + return OPUS_INVALID_PACKET; + else + return samples; } diff --git a/src/opus_demo.c b/src/opus_demo.c index c1ef4f92..414ce229 100644 --- a/src/opus_demo.c +++ b/src/opus_demo.c @@ -169,11 +169,12 @@ int main(int argc, char *argv[]) args++; } - if (sampling_rate != 8000 && sampling_rate != 12000 && sampling_rate != 16000 - && sampling_rate != 24000 && sampling_rate != 48000) + if (sampling_rate != 8000 && sampling_rate != 12000 + && sampling_rate != 16000 && sampling_rate != 24000 + && sampling_rate != 48000) { - fprintf(stderr, "Supported sampling rates are 8000, 12000, 16000, " - "24000 and 48000.\n"); + fprintf(stderr, "Supported sampling rates are 8000, 12000, " + "16000, 24000 and 48000.\n"); return 1; } frame_size = sampling_rate/50; @@ -207,7 +208,9 @@ int main(int argc, char *argv[]) else if (strcmp(argv[ args + 1 ], "FB")==0) bandwidth = OPUS_BANDWIDTH_FULLBAND; else { - fprintf(stderr, "Unknown bandwidth %s. Supported are NB, MB, WB, SWB, FB.\n", argv[ args + 1 ]); + fprintf(stderr, "Unknown bandwidth %s. " + "Supported are NB, MB, WB, SWB, FB.\n", + argv[ args + 1 ]); return 1; } args += 2; @@ -225,7 +228,9 @@ int main(int argc, char *argv[]) else if (strcmp(argv[ args + 1 ], "60")==0) frame_size = 3*sampling_rate/50; else { - fprintf(stderr, "Unsupported frame size: %s ms. Supported are 2.5, 5, 10, 20, 40, 60.\n", argv[ args + 1 ]); + fprintf(stderr, "Unsupported frame size: %s ms. " + "Supported are 2.5, 5, 10, 20, 40, 60.\n", + argv[ args + 1 ]); return 1; } args += 2; @@ -339,9 +344,13 @@ int main(int argc, char *argv[]) } if (decode_only) - fprintf(stderr, "Decoding with %ld Hz output (%d channels)\n", (long)sampling_rate, channels); + fprintf(stderr, "Decoding with %ld Hz output (%d channels)\n", + (long)sampling_rate, channels); else - fprintf(stderr, "Encoding %ld Hz input at %.3f kb/s in %s mode with %d-sample frames.\n", (long)sampling_rate, bitrate_bps*0.001, bandwidth_string, frame_size); + fprintf(stderr, "Encoding %ld Hz input at %.3f kb/s " + "in %s mode with %d-sample frames.\n", + (long)sampling_rate, bitrate_bps*0.001, + bandwidth_string, frame_size); in = (short*)malloc(frame_size*channels*sizeof(short)); out = (short*)malloc(max_frame_size*channels*sizeof(short)); @@ -368,7 +377,9 @@ int main(int argc, char *argv[]) err = fread(data[toggle], 1, len[toggle], fin); if (err<len[toggle]) { - fprintf(stderr, "Ran out of input, expecting %d bytes got %d\n",len[toggle],err); + fprintf(stderr, "Ran out of input, " + "expecting %d bytes got %d\n", + len[toggle],err); break; } } else { @@ -428,7 +439,8 @@ int main(int argc, char *argv[]) fwrite(out+skip*channels, sizeof(short)*channels, output_samples-skip, fout); skip = 0; } else { - fprintf(stderr, "error decoding frame: %s\n", opus_strerror(output_samples)); + fprintf(stderr, "error decoding frame: %s\n", + opus_strerror(output_samples)); } } } @@ -436,9 +448,15 @@ int main(int argc, char *argv[]) if (!encode_only) opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range)); /* compare final range encoder rng values of encoder and decoder */ - if( enc_final_range[toggle^use_inbandfec]!=0 && !encode_only && !lost && !lost_prev && - dec_final_range != enc_final_range[toggle^use_inbandfec] ) { - fprintf (stderr, "Error: Range coder state mismatch between encoder and decoder in frame %ld: 0x%8lx vs 0x%8lx\n", (long)count, (unsigned long)enc_final_range[toggle^use_inbandfec], (unsigned long)dec_final_range); + if( enc_final_range[toggle^use_inbandfec]!=0 && !encode_only + && !lost && !lost_prev + && dec_final_range != enc_final_range[toggle^use_inbandfec] ) { + fprintf (stderr, "Error: Range coder state mismatch " + "between encoder and decoder " + "in frame %ld: 0x%8lx vs 0x%8lx\n", + (long)count, + (unsigned long)enc_final_range[toggle^use_inbandfec], + (unsigned long)dec_final_range); return 0; } @@ -459,17 +477,21 @@ int main(int argc, char *argv[]) bits_act += len[toggle]*8; count_act++; } - /* Variance */ + /* Variance */ bits2 += len[toggle]*len[toggle]*64; } count++; toggle = (toggle + use_inbandfec) & 1; } - fprintf (stderr, "average bitrate: %7.3f kb/s\n", 1e-3*bits*sampling_rate/(frame_size*(double)count)); - fprintf (stderr, "maximum bitrate: %7.3f bkp/s\n", 1e-3*bits_max*sampling_rate/frame_size); + fprintf (stderr, "average bitrate: %7.3f kb/s\n", + 1e-3*bits*sampling_rate/(frame_size*(double)count)); + fprintf (stderr, "maximum bitrate: %7.3f bkp/s\n", + 1e-3*bits_max*sampling_rate/frame_size); if (!decode_only) - fprintf (stderr, "active bitrate: %7.3f kb/s\n", 1e-3*bits_act*sampling_rate/(frame_size*(double)count_act)); - fprintf (stderr, "bitrate standard deviation: %7.3f kb/s\n", 1e-3*sqrt(bits2/count - bits*bits/(count*(double)count))*sampling_rate/frame_size); + fprintf (stderr, "active bitrate: %7.3f kb/s\n", + 1e-3*bits_act*sampling_rate/(frame_size*(double)count_act)); + fprintf (stderr, "bitrate standard deviation: %7.3f kb/s\n", + 1e-3*sqrt(bits2/count - bits*bits/(count*(double)count))*sampling_rate/frame_size); /* Close any files to which intermediate results were stored */ SILK_DEBUG_STORE_CLOSE_FILES silk_TimerSave("opus_timing.txt"); diff --git a/src/opus_multistream.c b/src/opus_multistream.c index b5f7bbaf..a4415680 100644 --- a/src/opus_multistream.c +++ b/src/opus_multistream.c @@ -135,14 +135,14 @@ static int validate_encoder_layout(const ChannelLayout *layout) int opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams) { - int coupled_size; - int mono_size; - - coupled_size = opus_encoder_get_size(2); - mono_size = opus_encoder_get_size(1); - return align(sizeof(OpusMSEncoder)) - + nb_coupled_streams * align(coupled_size) - + (nb_streams-nb_coupled_streams) * align(mono_size); + int coupled_size; + int mono_size; + + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + return align(sizeof(OpusMSEncoder)) + + nb_coupled_streams * align(coupled_size) + + (nb_streams-nb_coupled_streams) * align(mono_size); } |