Convert tabs to spaces in the opus and celt code.

Also reformat some, but by no means all, of the opus
code for line length and three-character indents.
This commit is contained in:
Ralph Giles 2011-10-26 20:24:49 -07:00
parent 4923f3f80e
commit da025d5632
10 changed files with 629 additions and 595 deletions

View file

@ -120,28 +120,28 @@
#ifndef C_ADD #ifndef C_ADD
#define C_ADD( res, a,b)\ #define C_ADD( res, a,b)\
do { \ do { \
CHECK_OVERFLOW_OP((a).r,+,(b).r)\ CHECK_OVERFLOW_OP((a).r,+,(b).r)\
CHECK_OVERFLOW_OP((a).i,+,(b).i)\ CHECK_OVERFLOW_OP((a).i,+,(b).i)\
(res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \
}while(0) }while(0)
#define C_SUB( res, a,b)\ #define C_SUB( res, a,b)\
do { \ do { \
CHECK_OVERFLOW_OP((a).r,-,(b).r)\ CHECK_OVERFLOW_OP((a).r,-,(b).r)\
CHECK_OVERFLOW_OP((a).i,-,(b).i)\ CHECK_OVERFLOW_OP((a).i,-,(b).i)\
(res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \
}while(0) }while(0)
#define C_ADDTO( res , a)\ #define C_ADDTO( res , a)\
do { \ do { \
CHECK_OVERFLOW_OP((res).r,+,(a).r)\ CHECK_OVERFLOW_OP((res).r,+,(a).r)\
CHECK_OVERFLOW_OP((res).i,+,(a).i)\ CHECK_OVERFLOW_OP((res).i,+,(a).i)\
(res).r += (a).r; (res).i += (a).i;\ (res).r += (a).r; (res).i += (a).i;\
}while(0) }while(0)
#define C_SUBFROM( res , a)\ #define C_SUBFROM( res , a)\
do {\ do {\
CHECK_OVERFLOW_OP((res).r,-,(a).r)\ CHECK_OVERFLOW_OP((res).r,-,(a).r)\
CHECK_OVERFLOW_OP((res).i,-,(a).i)\ CHECK_OVERFLOW_OP((res).i,-,(a).i)\
(res).r -= (a).r; (res).i -= (a).i; \ (res).r -= (a).r; (res).i -= (a).i; \
}while(0) }while(0)
#endif /* C_ADD defined */ #endif /* C_ADD defined */
@ -162,10 +162,10 @@
#endif #endif
#define kf_cexp(x,phase) \ #define kf_cexp(x,phase) \
do{ \ do{ \
(x)->r = KISS_FFT_COS(phase);\ (x)->r = KISS_FFT_COS(phase);\
(x)->i = KISS_FFT_SIN(phase);\ (x)->i = KISS_FFT_SIN(phase);\
}while(0) }while(0)
#define kf_cexp2(x,phase) \ #define kf_cexp2(x,phase) \
do{ \ do{ \

View file

@ -103,8 +103,8 @@ typedef opus_val32 celt_ener;
#define VERY_LARGE16 ((opus_val16)32767) #define VERY_LARGE16 ((opus_val16)32767)
#define Q15_ONE ((opus_val16)32767) #define Q15_ONE ((opus_val16)32767)
#define SCALEIN(a) (a) #define SCALEIN(a) (a)
#define SCALEOUT(a) (a) #define SCALEOUT(a) (a)
#ifdef FIXED_DEBUG #ifdef FIXED_DEBUG
#include "fixed_debug.h" #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_16(a,b) (((opus_val32)(a))/(opus_val16)(b))
#define DIV32(a,b) (((opus_val32)(a))/(opus_val32)(b)) #define DIV32(a,b) (((opus_val32)(a))/(opus_val32)(b))
#define SCALEIN(a) ((a)*CELT_SIG_SCALE) #define SCALEIN(a) ((a)*CELT_SIG_SCALE)
#define SCALEOUT(a) ((a)*(1/CELT_SIG_SCALE)) #define SCALEOUT(a) ((a)*(1/CELT_SIG_SCALE))
#endif /* !FIXED_POINT */ #endif /* !FIXED_POINT */

View file

@ -2391,7 +2391,7 @@ int celt_decode_with_ec(CELTDecoder * restrict st, const unsigned char *data, in
tell = ec_tell(dec); tell = ec_tell(dec);
if (tell >= total_bits) if (tell >= total_bits)
silence = 1; silence = 1;
else if (tell==1) else if (tell==1)
silence = ec_dec_bit_logp(dec, 15); silence = ec_dec_bit_logp(dec, 15);
else else

View file

@ -30,98 +30,98 @@
#define FLOAT_CAST_H #define FLOAT_CAST_H
/*============================================================================ /*============================================================================
** On Intel Pentium processors (especially PIII and probably P4), converting ** 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 ** 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 ** most C compilers targeting Pentium needs to change the FPU rounding mode
** before the float to int conversion is performed. ** before the float to int conversion is performed.
** **
** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It ** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It
** is this flushing of the pipeline which is so slow. ** is this flushing of the pipeline which is so slow.
** **
** Fortunately the ISO C99 specifications define the functions lrint, lrintf, ** Fortunately the ISO C99 specifications define the functions lrint, lrintf,
** llrint and llrintf which fix this problem as a side effect. ** llrint and llrintf which fix this problem as a side effect.
** **
** On Unix-like systems, the configure process should have detected the ** 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 ** presence of these functions. If they weren't found we have to replace them
** here with a standard C cast. ** here with a standard C cast.
*/ */
/* /*
** The C99 prototypes for lrint and lrintf are as follows: ** The C99 prototypes for lrint and lrintf are as follows:
** **
** long int lrintf (float x) ; ** long int lrintf (float x) ;
** long int lrint (double x) ; ** long int lrint (double x) ;
*/ */
/* The presence of the required functions are detected during the configure /* The presence of the required functions are detected during the configure
** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in ** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in
** the config.h file. ** the config.h file.
*/ */
#if (HAVE_LRINTF) #if (HAVE_LRINTF)
/* These defines enable functionality introduced with the 1999 ISO C /* These defines enable functionality introduced with the 1999 ISO C
** standard. They must be defined before the inclusion of math.h to ** standard. They must be defined before the inclusion of math.h to
** engage them. If optimisation is enabled, these functions will be ** engage them. If optimisation is enabled, these functions will be
** inlined. With optimisation switched off, you have to link in the ** inlined. With optimisation switched off, you have to link in the
** maths library using -lm. ** maths library using -lm.
*/ */
#define _ISOC9X_SOURCE 1 #define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1 #define _ISOC99_SOURCE 1
#define __USE_ISOC9X 1 #define __USE_ISOC9X 1
#define __USE_ISOC99 1 #define __USE_ISOC99 1
#include <math.h> #include <math.h>
#define float2int(x) lrintf(x) #define float2int(x) lrintf(x)
#elif (defined(HAVE_LRINT)) #elif (defined(HAVE_LRINT))
#define _ISOC9X_SOURCE 1 #define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1 #define _ISOC99_SOURCE 1
#define __USE_ISOC9X 1 #define __USE_ISOC9X 1
#define __USE_ISOC99 1 #define __USE_ISOC99 1
#include <math.h> #include <math.h>
#define float2int(x) lrint(x) #define float2int(x) lrint(x)
#elif (defined (WIN64) || defined (_WIN64)) #elif (defined (WIN64) || defined (_WIN64))
#include <xmmintrin.h> #include <xmmintrin.h>
__inline long int float2int(float value) __inline long int float2int(float value)
{ {
return _mm_cvtss_si32(_mm_load_ss(&value)); return _mm_cvtss_si32(_mm_load_ss(&value));
} }
#elif (defined (WIN32) || defined (_WIN32)) #elif (defined (WIN32) || defined (_WIN32))
#include <math.h> #include <math.h>
/* Win32 doesn't seem to have these functions. /* Win32 doesn't seem to have these functions.
** Therefore implement inline versions of these functions here. ** Therefore implement inline versions of these functions here.
*/ */
__inline long int
float2int (float flt)
{ int intgr;
_asm __inline long int
{ fld flt float2int (float flt)
fistp intgr { int intgr;
} ;
_asm
return intgr ; { fld flt
} fistp intgr
} ;
return intgr ;
}
#else #else
#if (defined(__GNUC__) && defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) #if (defined(__GNUC__) && defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L)
/* supported by gcc in C99 mode, but not by all other compilers */ /* supported by gcc in C99 mode, but not by all other compilers */
#warning "Don't have the functions lrint() and lrintf ()." #warning "Don't have the functions lrint() and lrintf ()."
#warning "Replacing these functions with a standard C cast." #warning "Replacing these functions with a standard C cast."
#endif /* __STDC_VERSION__ >= 199901L */ #endif /* __STDC_VERSION__ >= 199901L */
#include <math.h> #include <math.h>
#define float2int(flt) ((int)(floor(.5+flt))) #define float2int(flt) ((int)(floor(.5+flt)))
#endif #endif
static inline opus_int16 FLOAT2INT16(float x) static inline opus_int16 FLOAT2INT16(float x)

View file

@ -54,12 +54,12 @@ extern "C" {
# include <xmmintrin.h> # include <xmmintrin.h>
# define kiss_fft_scalar __m128 # define kiss_fft_scalar __m128
#define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes) #define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes)
#else #else
#define KISS_FFT_MALLOC opus_alloc #define KISS_FFT_MALLOC opus_alloc
#endif #endif
#ifdef FIXED_POINT #ifdef FIXED_POINT
#include "arch.h" #include "arch.h"
# define kiss_fft_scalar opus_int32 # define kiss_fft_scalar opus_int32
# define kiss_twiddle_scalar opus_int16 # define kiss_twiddle_scalar opus_int16

View file

@ -425,44 +425,44 @@ static const opus_int16 fft_bitrev60[60] = {
#ifndef FFT_STATE48000_960_0 #ifndef FFT_STATE48000_960_0
#define FFT_STATE48000_960_0 #define FFT_STATE48000_960_0
static const kiss_fft_state fft_state48000_960_0 = { static const kiss_fft_state fft_state48000_960_0 = {
480, /* nfft */ 480, /* nfft */
-1, /* shift */ -1, /* shift */
{4, 120, 4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, }, /* factors */ {4, 120, 4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev480, /* bitrev */ fft_bitrev480, /* bitrev */
fft_twiddles48000_960, /* bitrev */ fft_twiddles48000_960, /* bitrev */
}; };
#endif #endif
#ifndef FFT_STATE48000_960_1 #ifndef FFT_STATE48000_960_1
#define FFT_STATE48000_960_1 #define FFT_STATE48000_960_1
static const kiss_fft_state fft_state48000_960_1 = { static const kiss_fft_state fft_state48000_960_1 = {
240, /* nfft */ 240, /* nfft */
1, /* shift */ 1, /* shift */
{4, 60, 4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ {4, 60, 4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev240, /* bitrev */ fft_bitrev240, /* bitrev */
fft_twiddles48000_960, /* bitrev */ fft_twiddles48000_960, /* bitrev */
}; };
#endif #endif
#ifndef FFT_STATE48000_960_2 #ifndef FFT_STATE48000_960_2
#define FFT_STATE48000_960_2 #define FFT_STATE48000_960_2
static const kiss_fft_state fft_state48000_960_2 = { static const kiss_fft_state fft_state48000_960_2 = {
120, /* nfft */ 120, /* nfft */
2, /* shift */ 2, /* shift */
{4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ {4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev120, /* bitrev */ fft_bitrev120, /* bitrev */
fft_twiddles48000_960, /* bitrev */ fft_twiddles48000_960, /* bitrev */
}; };
#endif #endif
#ifndef FFT_STATE48000_960_3 #ifndef FFT_STATE48000_960_3
#define FFT_STATE48000_960_3 #define FFT_STATE48000_960_3
static const kiss_fft_state fft_state48000_960_3 = { static const kiss_fft_state fft_state48000_960_3 = {
60, /* nfft */ 60, /* nfft */
3, /* shift */ 3, /* shift */
{4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ {4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev60, /* bitrev */ fft_bitrev60, /* bitrev */
fft_twiddles48000_960, /* bitrev */ fft_twiddles48000_960, /* bitrev */
}; };
#endif #endif
@ -571,21 +571,21 @@ static const opus_val16 mdct_twiddles960[481] = {
#endif #endif
static const CELTMode mode48000_960_120 = { static const CELTMode mode48000_960_120 = {
48000, /* Fs */ 48000, /* Fs */
120, /* overlap */ 120, /* overlap */
21, /* nbEBands */ 21, /* nbEBands */
21, /* effEBands */ 21, /* effEBands */
{27853, 0, 4096, 8192, }, /* preemph */ {27853, 0, 4096, 8192, }, /* preemph */
eband5ms, /* eBands */ eband5ms, /* eBands */
3, /* maxLM */ 3, /* maxLM */
8, /* nbShortMdcts */ 8, /* nbShortMdcts */
120, /* shortMdctSize */ 120, /* shortMdctSize */
11, /* nbAllocVectors */ 11, /* nbAllocVectors */
band_allocation, /* allocVectors */ band_allocation, /* allocVectors */
logN400, /* logN */ logN400, /* logN */
window120, /* window */ window120, /* window */
{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960}, /* mdct */ {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 */ {392, cache_index50, cache_bits50, cache_caps50}, /* cache */
}; };
/* List of all the available modes */ /* List of all the available modes */

View file

@ -425,48 +425,48 @@ static const opus_int16 fft_bitrev60[60] = {
#ifndef FFT_STATE48000_960_0 #ifndef FFT_STATE48000_960_0
#define FFT_STATE48000_960_0 #define FFT_STATE48000_960_0
static const kiss_fft_state fft_state48000_960_0 = { static const kiss_fft_state fft_state48000_960_0 = {
480, /* nfft */ 480, /* nfft */
0.002083333f, /* scale */ 0.002083333f, /* scale */
-1, /* shift */ -1, /* shift */
{4, 120, 4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, }, /* factors */ {4, 120, 4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev480, /* bitrev */ fft_bitrev480, /* bitrev */
fft_twiddles48000_960, /* bitrev */ fft_twiddles48000_960, /* bitrev */
}; };
#endif #endif
#ifndef FFT_STATE48000_960_1 #ifndef FFT_STATE48000_960_1
#define FFT_STATE48000_960_1 #define FFT_STATE48000_960_1
static const kiss_fft_state fft_state48000_960_1 = { static const kiss_fft_state fft_state48000_960_1 = {
240, /* nfft */ 240, /* nfft */
0.004166667f, /* scale */ 0.004166667f, /* scale */
1, /* shift */ 1, /* shift */
{4, 60, 4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ {4, 60, 4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev240, /* bitrev */ fft_bitrev240, /* bitrev */
fft_twiddles48000_960, /* bitrev */ fft_twiddles48000_960, /* bitrev */
}; };
#endif #endif
#ifndef FFT_STATE48000_960_2 #ifndef FFT_STATE48000_960_2
#define FFT_STATE48000_960_2 #define FFT_STATE48000_960_2
static const kiss_fft_state fft_state48000_960_2 = { static const kiss_fft_state fft_state48000_960_2 = {
120, /* nfft */ 120, /* nfft */
0.008333333f, /* scale */ 0.008333333f, /* scale */
2, /* shift */ 2, /* shift */
{4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ {4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev120, /* bitrev */ fft_bitrev120, /* bitrev */
fft_twiddles48000_960, /* bitrev */ fft_twiddles48000_960, /* bitrev */
}; };
#endif #endif
#ifndef FFT_STATE48000_960_3 #ifndef FFT_STATE48000_960_3
#define FFT_STATE48000_960_3 #define FFT_STATE48000_960_3
static const kiss_fft_state fft_state48000_960_3 = { static const kiss_fft_state fft_state48000_960_3 = {
60, /* nfft */ 60, /* nfft */
0.016666667f, /* scale */ 0.016666667f, /* scale */
3, /* shift */ 3, /* shift */
{4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ {4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
fft_bitrev60, /* bitrev */ fft_bitrev60, /* bitrev */
fft_twiddles48000_960, /* bitrev */ fft_twiddles48000_960, /* bitrev */
}; };
#endif #endif
@ -575,21 +575,21 @@ static const opus_val16 mdct_twiddles960[481] = {
#endif #endif
static const CELTMode mode48000_960_120 = { static const CELTMode mode48000_960_120 = {
48000, /* Fs */ 48000, /* Fs */
120, /* overlap */ 120, /* overlap */
21, /* nbEBands */ 21, /* nbEBands */
21, /* effEBands */ 21, /* effEBands */
{0.85000610f, 0.0000000f, 1.0000000f, 1.0000000f, }, /* preemph */ {0.85000610f, 0.0000000f, 1.0000000f, 1.0000000f, }, /* preemph */
eband5ms, /* eBands */ eband5ms, /* eBands */
3, /* maxLM */ 3, /* maxLM */
8, /* nbShortMdcts */ 8, /* nbShortMdcts */
120, /* shortMdctSize */ 120, /* shortMdctSize */
11, /* nbAllocVectors */ 11, /* nbAllocVectors */
band_allocation, /* allocVectors */ band_allocation, /* allocVectors */
logN400, /* logN */ logN400, /* logN */
window120, /* window */ window120, /* window */
{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960}, /* mdct */ {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 */ {392, cache_index50, cache_bits50, cache_caps50}, /* cache */
}; };
/* List of all the available modes */ /* List of all the available modes */

View file

@ -64,7 +64,7 @@ struct OpusDecoder {
#ifdef FIXED_POINT #ifdef FIXED_POINT
static inline opus_int16 SAT16(opus_int32 x) { 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 #endif
@ -89,13 +89,15 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
CELTDecoder *celt_dec; CELTDecoder *celt_dec;
int ret, silkDecSizeBytes; 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; return OPUS_BAD_ARG;
OPUS_CLEAR((char*)st, opus_decoder_get_size(channels)); OPUS_CLEAR((char*)st, opus_decoder_get_size(channels));
/* Initialize SILK encoder */ /* Initialize SILK encoder */
ret = silk_Get_Decoder_Size(&silkDecSizeBytes); ret = silk_Get_Decoder_Size(&silkDecSizeBytes);
if(ret)return OPUS_INTERNAL_ERROR; if (ret)
return OPUS_INTERNAL_ERROR;
silkDecSizeBytes = align(silkDecSizeBytes); silkDecSizeBytes = align(silkDecSizeBytes);
st->silk_dec_offset = align(sizeof(OpusDecoder)); st->silk_dec_offset = align(sizeof(OpusDecoder));
@ -127,7 +129,8 @@ OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
{ {
int ret; int ret;
OpusDecoder *st; 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) if (error)
*error = OPUS_BAD_ARG; *error = OPUS_BAD_ARG;
@ -151,354 +154,361 @@ OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
return st; return st;
} }
static void smooth_fade(const opus_val16 *in1, const opus_val16 *in2, opus_val16 *out, static void smooth_fade(const opus_val16 *in1, const opus_val16 *in2,
int overlap, int channels, const opus_val16 *window, opus_int32 Fs) opus_val16 *out, int overlap, int channels,
const opus_val16 *window, opus_int32 Fs)
{ {
int i, c; int i, c;
int inc = 48000/Fs; int inc = 48000/Fs;
for (c=0;c<channels;c++) for (c=0;c<channels;c++)
{ {
for (i=0;i<overlap;i++) for (i=0;i<overlap;i++)
{ {
opus_val16 w = MULT16_16_Q15(window[i*inc], window[i*inc]); 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]), out[i*channels+c] = SHR32(MAC16_16(MULT16_16(w,in2[i*channels+c]),
Q15ONE-w, in1[i*channels+c]), 15); Q15ONE-w, in1[i*channels+c]), 15);
} }
} }
} }
static int opus_packet_get_mode(const unsigned char *data) static int opus_packet_get_mode(const unsigned char *data)
{ {
int mode; int mode;
if (data[0]&0x80) if (data[0]&0x80)
{ {
mode = MODE_CELT_ONLY; mode = MODE_CELT_ONLY;
} else if ((data[0]&0x60) == 0x60) } else if ((data[0]&0x60) == 0x60)
{ {
mode = MODE_HYBRID; mode = MODE_HYBRID;
} else { } else {
mode = MODE_SILK_ONLY;
mode = MODE_SILK_ONLY; }
} return mode;
return mode;
} }
static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, 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; void *silk_dec;
CELTDecoder *celt_dec; CELTDecoder *celt_dec;
int i, silk_ret=0, celt_ret=0; int i, silk_ret=0, celt_ret=0;
ec_dec dec; ec_dec dec;
opus_int32 silk_frame_size; opus_int32 silk_frame_size;
VARDECL(opus_int16, pcm_silk); VARDECL(opus_int16, pcm_silk);
VARDECL(opus_val16, pcm_transition); VARDECL(opus_val16, pcm_transition);
VARDECL(opus_val16, redundant_audio); VARDECL(opus_val16, redundant_audio);
int audiosize; int audiosize;
int mode; int mode;
int transition=0; int transition=0;
int start_band; int start_band;
int redundancy=0; int redundancy=0;
int redundancy_bytes = 0; int redundancy_bytes = 0;
int celt_to_silk=0; int celt_to_silk=0;
int c; int c;
int F2_5, F5, F10, F20; int F2_5, F5, F10, F20;
const opus_val16 *window; const opus_val16 *window;
opus_uint32 redundant_rng = 0; opus_uint32 redundant_rng = 0;
ALLOC_STACK; ALLOC_STACK;
silk_dec = (char*)st+st->silk_dec_offset; silk_dec = (char*)st+st->silk_dec_offset;
celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
F20 = st->Fs/50; F20 = st->Fs/50;
F10 = F20>>1; F10 = F20>>1;
F5 = F10>>1; F5 = F10>>1;
F2_5 = F5>>1; F2_5 = F5>>1;
if (frame_size < F2_5) if (frame_size < F2_5)
return OPUS_BUFFER_TOO_SMALL; return OPUS_BUFFER_TOO_SMALL;
/* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */ /* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */
if (len<=1) if (len<=1)
{ {
data = NULL; data = NULL;
/* In that case, don't conceal more than what the ToC says */ /* In that case, don't conceal more than what the ToC says */
frame_size = IMIN(frame_size, st->frame_size); frame_size = IMIN(frame_size, st->frame_size);
} }
if (data != NULL) if (data != NULL)
{ {
audiosize = st->frame_size; audiosize = st->frame_size;
mode = st->mode; mode = st->mode;
ec_dec_init(&dec,(unsigned char*)data,len); ec_dec_init(&dec,(unsigned char*)data,len);
} else { } else {
audiosize = frame_size; audiosize = frame_size;
if (st->prev_mode == 0) if (st->prev_mode == 0)
{ {
/* If we haven't got any packet yet, all we can do is return zeros */ /* If we haven't got any packet yet, all we can do is return zeros */
for (i=0;i<audiosize*st->channels;i++) for (i=0;i<audiosize*st->channels;i++)
pcm[i] = 0; pcm[i] = 0;
RESTORE_STACK; RESTORE_STACK;
return audiosize; return audiosize;
} else { } else {
mode = st->prev_mode; mode = st->prev_mode;
} }
} }
ALLOC(pcm_transition, F5*st->channels, opus_val16); ALLOC(pcm_transition, F5*st->channels, opus_val16);
if (data!=NULL && st->prev_mode > 0 && ( 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 && !st->prev_redundancy)
|| (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ) || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) )
) )
{ {
transition = 1; transition = 1;
if (mode == MODE_CELT_ONLY) if (mode == MODE_CELT_ONLY)
opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
} }
if (audiosize > frame_size) if (audiosize > frame_size)
{ {
/*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosize, frame_size, mode);*/ /*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosize, frame_size, mode);*/
RESTORE_STACK; RESTORE_STACK;
return OPUS_BAD_ARG; return OPUS_BAD_ARG;
} else { } else {
frame_size = audiosize; frame_size = audiosize;
} }
ALLOC(pcm_silk, IMAX(F10, frame_size)*st->channels, opus_int16); ALLOC(pcm_silk, IMAX(F10, frame_size)*st->channels, opus_int16);
ALLOC(redundant_audio, F5*st->channels, opus_val16); ALLOC(redundant_audio, F5*st->channels, opus_val16);
/* SILK processing */ /* SILK processing */
if (mode != MODE_CELT_ONLY) if (mode != MODE_CELT_ONLY)
{ {
int lost_flag, decoded_samples; int lost_flag, decoded_samples;
opus_int16 *pcm_ptr = pcm_silk; opus_int16 *pcm_ptr = pcm_silk;
if (st->prev_mode==MODE_CELT_ONLY) if (st->prev_mode==MODE_CELT_ONLY)
silk_InitDecoder( silk_dec ); silk_InitDecoder( silk_dec );
/* The SILK PLC cannot support produce frames of less than 10 ms */ /* The SILK PLC cannot support produce frames of less than 10 ms */
st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs); st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs);
if (data != NULL) if (data != NULL)
{ {
st->DecControl.nChannelsInternal = st->stream_channels; st->DecControl.nChannelsInternal = st->stream_channels;
if( mode == MODE_SILK_ONLY ) { if( mode == MODE_SILK_ONLY ) {
if( st->bandwidth == OPUS_BANDWIDTH_NARROWBAND ) { if( st->bandwidth == OPUS_BANDWIDTH_NARROWBAND ) {
st->DecControl.internalSampleRate = 8000; st->DecControl.internalSampleRate = 8000;
} else if( st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) { } else if( st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) {
st->DecControl.internalSampleRate = 12000; st->DecControl.internalSampleRate = 12000;
} else if( st->bandwidth == OPUS_BANDWIDTH_WIDEBAND ) { } else if( st->bandwidth == OPUS_BANDWIDTH_WIDEBAND ) {
st->DecControl.internalSampleRate = 16000; st->DecControl.internalSampleRate = 16000;
} else { } else {
st->DecControl.internalSampleRate = 16000; st->DecControl.internalSampleRate = 16000;
silk_assert( 0 ); silk_assert( 0 );
} }
} else { } else {
/* Hybrid mode */ /* Hybrid mode */
st->DecControl.internalSampleRate = 16000; st->DecControl.internalSampleRate = 16000;
}
} }
}
lost_flag = data == NULL ? 1 : 2 * decode_fec; lost_flag = data == NULL ? 1 : 2 * decode_fec;
decoded_samples = 0; decoded_samples = 0;
do { do {
/* Call SILK decoder */ /* Call SILK decoder */
int first_frame = decoded_samples == 0; int first_frame = decoded_samples == 0;
silk_ret = silk_Decode( silk_dec, &st->DecControl, silk_ret = silk_Decode( silk_dec, &st->DecControl,
lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size ); lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size );
if( silk_ret ) { if( silk_ret ) {
if (lost_flag) { if (lost_flag) {
/* PLC failure should not be fatal */ /* PLC failure should not be fatal */
silk_frame_size = frame_size; silk_frame_size = frame_size;
for (i=0;i<frame_size*st->channels;i++) for (i=0;i<frame_size*st->channels;i++)
pcm_ptr[i] = 0; pcm_ptr[i] = 0;
} else { } else {
RESTORE_STACK; RESTORE_STACK;
return OPUS_INVALID_PACKET; 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;
} }
} pcm_ptr += silk_frame_size * st->channels;
if (mode != MODE_CELT_ONLY) decoded_samples += silk_frame_size;
start_band = 17; } while( decoded_samples < frame_size );
}
{ start_band = 0;
int endband=21; 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;
switch(st->bandwidth) {
{ int endband=21;
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) switch(st->bandwidth)
transition = 0; {
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 (transition && mode != MODE_CELT_ONLY) if (redundancy)
opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); transition = 0;
/* 5 ms redundant frame for CELT->SILK*/ if (transition && mode != MODE_CELT_ONLY)
if (redundancy && celt_to_silk) opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
{
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 */ /* 5 ms redundant frame for CELT->SILK*/
celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band)); 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));
}
if (mode != MODE_SILK_ONLY) /* MUST be after PLC */
{ celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band));
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) 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 #ifdef FIXED_POINT
for (i=0;i<frame_size*st->channels;i++) for (i=0;i<frame_size*st->channels;i++)
pcm[i] = SAT16(pcm[i] + pcm_silk[i]); pcm[i] = SAT16(pcm[i] + pcm_silk[i]);
#else #else
for (i=0;i<frame_size*st->channels;i++) for (i=0;i<frame_size*st->channels;i++)
pcm[i] = pcm[i] + (opus_val16)((1./32768.)*pcm_silk[i]); pcm[i] = pcm[i] + (opus_val16)((1./32768.)*pcm_silk[i]);
#endif #endif
} }
{ {
const CELTMode *celt_mode; const CELTMode *celt_mode;
celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode)); celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode));
window = celt_mode->window; window = celt_mode->window;
} }
/* 5 ms redundant frame for SILK->CELT */ /* 5 ms redundant frame for SILK->CELT */
if (redundancy && !celt_to_silk) if (redundancy && !celt_to_silk)
{ {
celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); 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_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL);
celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); 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, 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); pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs);
} }
if (redundancy && celt_to_silk) if (redundancy && celt_to_silk)
{ {
for (c=0;c<st->channels;c++) for (c=0;c<st->channels;c++)
{ {
for (i=0;i<F2_5;i++) for (i=0;i<F2_5;i++)
pcm[st->channels*i+c] = redundant_audio[st->channels*i+c]; pcm[st->channels*i+c] = redundant_audio[st->channels*i+c];
} }
smooth_fade(redundant_audio+st->channels*F2_5, pcm+st->channels*F2_5, 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); pcm+st->channels*F2_5, F2_5, st->channels, window, st->Fs);
} }
if (transition) if (transition)
{ {
if (audiosize >= F5) if (audiosize >= F5)
{ {
for (i=0;i<st->channels*F2_5;i++) for (i=0;i<st->channels*F2_5;i++)
pcm[i] = pcm_transition[i]; pcm[i] = pcm_transition[i];
smooth_fade(pcm_transition+st->channels*F2_5, pcm+st->channels*F2_5, smooth_fade(pcm_transition+st->channels*F2_5, pcm+st->channels*F2_5,
pcm+st->channels*F2_5, F2_5, pcm+st->channels*F2_5, F2_5,
st->channels, window, st->Fs); st->channels, window, st->Fs);
} else { } else {
/* Not enough time to do a clean transition, but we do it anyway /* Not enough time to do a clean transition, but we do it anyway
This will not preserve amplitude perfectly and may introduce This will not preserve amplitude perfectly and may introduce
a bit of temporal aliasing, but it shouldn't be too bad and 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 that's pretty much the best we can do. In any case, generating this
transition it pretty silly in the first place */ transition it pretty silly in the first place */
smooth_fade(pcm_transition, pcm, smooth_fade(pcm_transition, pcm,
pcm, F2_5, pcm, F2_5,
st->channels, window, st->Fs); st->channels, window, st->Fs);
} }
} }
if (len <= 1) if (len <= 1)
st->rangeFinal = 0; st->rangeFinal = 0;
else else
st->rangeFinal = dec.rng ^ redundant_rng; st->rangeFinal = dec.rng ^ redundant_rng;
st->prev_mode = mode; st->prev_mode = mode;
st->prev_redundancy = redundancy && !celt_to_silk; st->prev_redundancy = redundancy && !celt_to_silk;
RESTORE_STACK; RESTORE_STACK;
return celt_ret<0 ? celt_ret : audiosize; return celt_ret < 0 ? celt_ret : audiosize;
} }
static int parse_size(const unsigned char *data, int len, short *size) static int parse_size(const unsigned char *data, int len, short *size)
{ {
if (len<1) if (len<1)
{ {
*size = -1; *size = -1;
return -1; return -1;
} else if (data[0]<252) } else if (data[0]<252)
{ {
*size = data[0]; *size = data[0];
return 1; return 1;
} else if (len<2) } else if (len<2)
{ {
*size = -1; *size = -1;
return -1; return -1;
} else { } else {
*size = 4*data[1] + data[0]; *size = 4*data[1] + data[0];
return 2; return 2;
} }
} }
static int opus_packet_parse_impl(const unsigned char *data, int len, 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: case 0:
count=1; count=1;
break; break;
/* Two CBR frames */ /* Two CBR frames */
case 1: case 1:
count=2; count=2;
cbr = 1; cbr = 1;
@ -539,7 +549,7 @@ static int opus_packet_parse_impl(const unsigned char *data, int len,
size[0] = last_size = len/2; size[0] = last_size = len/2;
} }
break; break;
/* Two VBR frames */ /* Two VBR frames */
case 2: case 2:
count = 2; count = 2;
bytes = parse_size(data, len, size); bytes = parse_size(data, len, size);
@ -549,7 +559,7 @@ static int opus_packet_parse_impl(const unsigned char *data, int len,
data += bytes; data += bytes;
last_size = len-size[0]; last_size = len-size[0];
break; break;
/* Multiple CBR/VBR frames (from 0 to 120 ms) */ /* Multiple CBR/VBR frames (from 0 to 120 ms) */
case 3: case 3:
if (len<1) if (len<1)
return OPUS_INVALID_PACKET; return OPUS_INVALID_PACKET;
@ -557,7 +567,7 @@ static int opus_packet_parse_impl(const unsigned char *data, int len,
ch = *data++; ch = *data++;
count = ch&0x3F; count = ch&0x3F;
if (count <= 0 || framesize*count > 5760) if (count <= 0 || framesize*count > 5760)
return OPUS_INVALID_PACKET; return OPUS_INVALID_PACKET;
len--; len--;
/* Padding flag is bit 6 */ /* Padding flag is bit 6 */
if (ch&0x40) if (ch&0x40)
@ -623,11 +633,10 @@ static int opus_packet_parse_impl(const unsigned char *data, int len,
} else } else
{ {
/* Because it's not encoded explicitly, it's possible the size of the /* 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 last packet (or all the packets, for the CBR case) is larger than
1275. 1275. Reject them here.*/
Reject them here.*/
if (last_size > 1275) if (last_size > 1275)
return OPUS_INVALID_PACKET; return OPUS_INVALID_PACKET;
size[count-1] = last_size; 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], unsigned char *out_toc, const unsigned char *frames[48],
short size[48], int *payload_offset) short size[48], int *payload_offset)
{ {
return opus_packet_parse_impl(data, len, 0, return opus_packet_parse_impl(data, len, 0, out_toc,
out_toc, frames, size, payload_offset); frames, size, payload_offset);
} }
int opus_decode_native(OpusDecoder *st, const unsigned char *data, 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 i, nb_samples;
int count, offset; int count, offset;
unsigned char toc; unsigned char toc;
int tot_offset; int tot_offset;
/* 48 x 2.5 ms = 120 ms */ /* 48 x 2.5 ms = 120 ms */
short size[48]; short size[48];
if (decode_fec<0 || decode_fec>1)return OPUS_BAD_ARG; if (decode_fec<0 || decode_fec>1)
if (len==0 || data==NULL) return OPUS_BAD_ARG;
return opus_decode_frame(st, NULL, 0, pcm, frame_size, 0); if (len==0 || data==NULL)
else if (len<0) return opus_decode_frame(st, NULL, 0, pcm, frame_size, 0);
return OPUS_BAD_ARG; else if (len<0)
return OPUS_BAD_ARG;
tot_offset = 0; tot_offset = 0;
st->mode = opus_packet_get_mode(data); st->mode = opus_packet_get_mode(data);
st->bandwidth = opus_packet_get_bandwidth(data); st->bandwidth = opus_packet_get_bandwidth(data);
st->frame_size = opus_packet_get_samples_per_frame(data, st->Fs); st->frame_size = opus_packet_get_samples_per_frame(data, st->Fs);
st->stream_channels = opus_packet_get_nb_channels(data); st->stream_channels = opus_packet_get_nb_channels(data);
count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset); count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset);
if (count < 0) if (count < 0)
return count; return count;
data += offset; data += offset;
tot_offset += offset; tot_offset += offset;
if (count*st->frame_size > frame_size) if (count*st->frame_size > frame_size)
return OPUS_BUFFER_TOO_SMALL; return OPUS_BUFFER_TOO_SMALL;
nb_samples=0; nb_samples=0;
for (i=0;i<count;i++) for (i=0;i<count;i++)
{ {
int ret; int ret;
ret = opus_decode_frame(st, data, size[i], pcm, frame_size-nb_samples, decode_fec); ret = opus_decode_frame(st, data, size[i], pcm, frame_size-nb_samples, decode_fec);
if (ret<0) if (ret<0)
return ret; return ret;
data += size[i]; data += size[i];
tot_offset += size[i]; tot_offset += size[i];
pcm += ret*st->channels; pcm += ret*st->channels;
nb_samples += ret; nb_samples += ret;
} }
if (packet_offset != NULL) if (packet_offset != NULL)
*packet_offset = tot_offset; *packet_offset = tot_offset;
return nb_samples; return nb_samples;
} }
#ifdef FIXED_POINT #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 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); 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) void opus_decoder_destroy(OpusDecoder *st)
{ {
opus_free(st); opus_free(st);
} }
int opus_packet_get_bandwidth(const unsigned char *data) int opus_packet_get_bandwidth(const unsigned char *data)
{ {
int bandwidth; int bandwidth;
if (data[0]&0x80) if (data[0]&0x80)
{ {
bandwidth = OPUS_BANDWIDTH_MEDIUMBAND + ((data[0]>>5)&0x3); bandwidth = OPUS_BANDWIDTH_MEDIUMBAND + ((data[0]>>5)&0x3);
if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)
bandwidth = OPUS_BANDWIDTH_NARROWBAND; bandwidth = OPUS_BANDWIDTH_NARROWBAND;
} else if ((data[0]&0x60) == 0x60) } else if ((data[0]&0x60) == 0x60)
{ {
bandwidth = (data[0]&0x10) ? OPUS_BANDWIDTH_FULLBAND : OPUS_BANDWIDTH_SUPERWIDEBAND; bandwidth = (data[0]&0x10) ? OPUS_BANDWIDTH_FULLBAND :
} else { OPUS_BANDWIDTH_SUPERWIDEBAND;
} else {
bandwidth = OPUS_BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3); bandwidth = OPUS_BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3);
} }
return bandwidth; 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; int audiosize;
if (data[0]&0x80) if (data[0]&0x80)
{ {
audiosize = ((data[0]>>3)&0x3); audiosize = ((data[0]>>3)&0x3);
audiosize = (Fs<<audiosize)/400; audiosize = (Fs<<audiosize)/400;
} else if ((data[0]&0x60) == 0x60) } else if ((data[0]&0x60) == 0x60)
{ {
audiosize = (data[0]&0x08) ? Fs/50 : Fs/100; audiosize = (data[0]&0x08) ? Fs/50 : Fs/100;
} else { } else {
audiosize = ((data[0]>>3)&0x3);
audiosize = ((data[0]>>3)&0x3); if (audiosize == 3)
if (audiosize == 3) audiosize = Fs*60/1000;
audiosize = Fs*60/1000; else
else audiosize = (Fs<<audiosize)/100;
audiosize = (Fs<<audiosize)/100; }
} return audiosize;
return audiosize;
} }
int opus_packet_get_nb_channels(const unsigned char *data) 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 opus_packet_get_nb_frames(const unsigned char packet[], int len)
{ {
int count; int count;
if (len<1) if (len<1)
return OPUS_BAD_ARG; return OPUS_BAD_ARG;
count = packet[0]&0x3; count = packet[0]&0x3;
if (count==0) if (count==0)
return 1; return 1;
else if (count!=3) else if (count!=3)
return 2; return 2;
else if (len<2) else if (len<2)
return OPUS_INVALID_PACKET; return OPUS_INVALID_PACKET;
else else
return packet[1]&0x3F; 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 samples;
int count = opus_packet_get_nb_frames(packet, len); int count = opus_packet_get_nb_frames(packet, len);
samples = count*opus_packet_get_samples_per_frame(packet, dec->Fs); samples = count*opus_packet_get_samples_per_frame(packet, dec->Fs);
/* Can't have more than 120 ms */ /* Can't have more than 120 ms */
if (samples*25 > dec->Fs*3) if (samples*25 > dec->Fs*3)
return OPUS_INVALID_PACKET; return OPUS_INVALID_PACKET;
else else
return samples; return samples;
} }

View file

@ -169,11 +169,12 @@ int main(int argc, char *argv[])
args++; args++;
} }
if (sampling_rate != 8000 && sampling_rate != 12000 && sampling_rate != 16000 if (sampling_rate != 8000 && sampling_rate != 12000
&& sampling_rate != 24000 && sampling_rate != 48000) && sampling_rate != 16000 && sampling_rate != 24000
&& sampling_rate != 48000)
{ {
fprintf(stderr, "Supported sampling rates are 8000, 12000, 16000, " fprintf(stderr, "Supported sampling rates are 8000, 12000, "
"24000 and 48000.\n"); "16000, 24000 and 48000.\n");
return 1; return 1;
} }
frame_size = sampling_rate/50; frame_size = sampling_rate/50;
@ -207,7 +208,9 @@ int main(int argc, char *argv[])
else if (strcmp(argv[ args + 1 ], "FB")==0) else if (strcmp(argv[ args + 1 ], "FB")==0)
bandwidth = OPUS_BANDWIDTH_FULLBAND; bandwidth = OPUS_BANDWIDTH_FULLBAND;
else { 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; return 1;
} }
args += 2; args += 2;
@ -225,7 +228,9 @@ int main(int argc, char *argv[])
else if (strcmp(argv[ args + 1 ], "60")==0) else if (strcmp(argv[ args + 1 ], "60")==0)
frame_size = 3*sampling_rate/50; frame_size = 3*sampling_rate/50;
else { 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; return 1;
} }
args += 2; args += 2;
@ -339,9 +344,13 @@ int main(int argc, char *argv[])
} }
if (decode_only) 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 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)); in = (short*)malloc(frame_size*channels*sizeof(short));
out = (short*)malloc(max_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); err = fread(data[toggle], 1, len[toggle], fin);
if (err<len[toggle]) 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; break;
} }
} else { } else {
@ -428,7 +439,8 @@ int main(int argc, char *argv[])
fwrite(out+skip*channels, sizeof(short)*channels, output_samples-skip, fout); fwrite(out+skip*channels, sizeof(short)*channels, output_samples-skip, fout);
skip = 0; skip = 0;
} else { } 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) if (!encode_only)
opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range)); opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));
/* compare final range encoder rng values of encoder and decoder */ /* compare final range encoder rng values of encoder and decoder */
if( enc_final_range[toggle^use_inbandfec]!=0 && !encode_only && !lost && !lost_prev && if( enc_final_range[toggle^use_inbandfec]!=0 && !encode_only
dec_final_range != enc_final_range[toggle^use_inbandfec] ) { && !lost && !lost_prev
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); && 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; return 0;
} }
@ -459,17 +477,21 @@ int main(int argc, char *argv[])
bits_act += len[toggle]*8; bits_act += len[toggle]*8;
count_act++; count_act++;
} }
/* Variance */ /* Variance */
bits2 += len[toggle]*len[toggle]*64; bits2 += len[toggle]*len[toggle]*64;
} }
count++; count++;
toggle = (toggle + use_inbandfec) & 1; 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, "average bitrate: %7.3f kb/s\n",
fprintf (stderr, "maximum bitrate: %7.3f bkp/s\n", 1e-3*bits_max*sampling_rate/frame_size); 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) 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, "active bitrate: %7.3f kb/s\n",
fprintf (stderr, "bitrate standard deviation: %7.3f kb/s\n", 1e-3*sqrt(bits2/count - bits*bits/(count*(double)count))*sampling_rate/frame_size); 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 */ /* Close any files to which intermediate results were stored */
SILK_DEBUG_STORE_CLOSE_FILES SILK_DEBUG_STORE_CLOSE_FILES
silk_TimerSave("opus_timing.txt"); silk_TimerSave("opus_timing.txt");

View file

@ -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 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)
{ {
int coupled_size; int coupled_size;
int mono_size; int mono_size;
coupled_size = opus_encoder_get_size(2); coupled_size = opus_encoder_get_size(2);
mono_size = opus_encoder_get_size(1); mono_size = opus_encoder_get_size(1);
return align(sizeof(OpusMSEncoder)) return align(sizeof(OpusMSEncoder))
+ nb_coupled_streams * align(coupled_size) + nb_coupled_streams * align(coupled_size)
+ (nb_streams-nb_coupled_streams) * align(mono_size); + (nb_streams-nb_coupled_streams) * align(mono_size);
} }