Bug 1948436 - Update opus to c79a9bd1dd2898cd57bb793e037d58c937555c2c r=kinetik

Differential Revision: https://phabricator.services.mozilla.com/D238339
This commit is contained in:
Updatebot
2025-02-16 22:40:13 +00:00
parent c89afbb999
commit c8eb931250
48 changed files with 3013 additions and 1223 deletions

View File

@@ -54,8 +54,13 @@
#define SAMP_MIN -SAMP_MAX
#ifdef ENABLE_QEXT
# define S_MUL(a,b) MULT32_32_Q31(b, a)
# define S_MUL2(a,b) MULT32_32_Q31(b, a)
#else
# define S_MUL(a,b) MULT16_32_Q15(b, a)
# define S_MUL2(a,b) MULT16_32_Q16(b, a)
#endif
# define C_MUL(m,a,b) \
do{ (m).r = SUB32_ovflw(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
@@ -104,6 +109,7 @@
#else /* not FIXED_POINT*/
# define S_MUL(a,b) ( (a)*(b) )
# define S_MUL2(a,b) ( (a)*(b) )
#define C_MUL(m,a,b) \
do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
(m).i = (a).r*(b).i + (a).i*(b).r; }while(0)

View File

@@ -56,7 +56,7 @@
#define CELT_SIG_SCALE 32768.f
#define CELT_FATAL(str) celt_fatal(str, __FILE__, __LINE__);
#define CELT_FATAL(str) celt_fatal(str, __FILE__, __LINE__)
#if defined(ENABLE_ASSERTIONS) || defined(ENABLE_HARDENING)
#ifdef __GNUC__
@@ -105,6 +105,16 @@ void celt_fatal(const char *str, const char *file, int line)
#define IMAX(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum int value. */
#define UADD32(a,b) ((a)+(b))
#define USUB32(a,b) ((a)-(b))
#define MAXG(a,b) MAX32(a, b)
#define MING(a,b) MIN32(a, b)
/* Throughout the code, we use the following scaling for signals:
FLOAT: used for float API, normalized to +/-1.
INT16: used for 16-bit API, normalized to +/- 32768
RES: internal Opus resolution, defined as +/-1. in float builds, or either 16-bit or 24-bit int for fixed-point builds
SIG: internal CELT resolution: defined as +/- 32768. in float builds, or Q27 in fixed-point builds (int16 shifted by 12)
*/
/* Set this if opus_int64 is a native type of the CPU. */
/* Assume that all LP64 architectures have fast 64-bit types; also x86_64
@@ -126,10 +136,65 @@ typedef opus_int64 opus_val64;
typedef opus_val32 celt_sig;
typedef opus_val16 celt_norm;
typedef opus_val32 celt_ener;
typedef opus_val32 celt_glog;
#ifdef ENABLE_RES24
typedef opus_val32 opus_res;
#define RES_SHIFT 8
#define SIG2RES(a) PSHR32(a, SIG_SHIFT-RES_SHIFT)
#define RES2INT16(a) SAT16(PSHR32(a, RES_SHIFT))
#define RES2INT24(a) (a)
#define RES2FLOAT(a) ((1.f/32768.f/256.)*(a))
#define INT16TORES(a) SHL32(EXTEND32(a), RES_SHIFT)
#define INT24TORES(a) (a)
#define ADD_RES(a, b) ADD32(a, b)
#define FLOAT2RES(a) float2int(32768.f*256.f*(a))
#define RES2SIG(a) SHL32((a), SIG_SHIFT-RES_SHIFT)
#define MULT16_RES_Q15(a,b) MULT16_32_Q15(a,b)
#define MAX_ENCODING_DEPTH 24
#else
typedef opus_val16 opus_res;
#define RES_SHIFT 0
#define SIG2RES(a) SIG2WORD16(a)
#define RES2INT16(a) (a)
#define RES2INT24(a) SHL32(EXTEND32(a), 8)
#define RES2FLOAT(a) ((1.f/32768.f)*(a))
#define INT16TORES(a) (a)
#define INT24TORES(a) SAT16(PSHR32(a, 8))
#define ADD_RES(a, b) SAT16(ADD32((a), (b)));
#define FLOAT2RES(a) FLOAT2INT16(a)
#define RES2SIG(a) SHL32(EXTEND32(a), SIG_SHIFT)
#define MULT16_RES_Q15(a,b) MULT16_16_Q15(a,b)
#define MAX_ENCODING_DEPTH 16
#endif
#define RES2VAL16(a) RES2INT16(a)
#define FLOAT2SIG(a) float2int(((opus_int32)32768<<SIG_SHIFT)*(a))
#define INT16TOSIG(a) SHL32(EXTEND32(a), SIG_SHIFT)
#define INT24TOSIG(a) SHL32(a, SIG_SHIFT-8)
#ifdef ENABLE_QEXT
typedef opus_val32 celt_coef;
#define COEF_ONE Q31ONE
#define MULT_COEF_32(a, b) MULT32_32_Q31(a,b)
#define MAC_COEF_32_ARM(c, a, b) ADD32((c), MULT32_32_Q32(a,b))
#define MULT_COEF(a, b) MULT32_32_Q31(a,b)
#define MULT_COEF_TAPS(a, b) SHL32(MULT16_16(a,b), 1)
#define COEF2VAL16(x) EXTRACT16(SHR32(x, 16))
#else
typedef opus_val16 celt_coef;
#define COEF_ONE Q15ONE
#define MULT_COEF_32(a, b) MULT16_32_Q15(a,b)
#define MAC_COEF_32_ARM(a, b, c) MAC16_32_Q16(a,b,c)
#define MULT_COEF(a, b) MULT16_16_Q15(a,b)
#define MULT_COEF_TAPS(a, b) MULT16_16_P15(a,b)
#define COEF2VAL16(x) (x)
#endif
#define celt_isnan(x) 0
#define Q15ONE 32767
#define Q31ONE 2147483647
#define SIG_SHIFT 12
/* Safe saturation value for 32-bit signals. We need to make sure that we can
@@ -143,15 +208,13 @@ typedef opus_val32 celt_ener;
#define NORM_SCALING 16384
#define DB_SHIFT 10
#define DB_SHIFT 24
#define EPSILON 1
#define VERY_SMALL 0
#define VERY_LARGE16 ((opus_val16)32767)
#define Q15_ONE ((opus_val16)32767)
#define SCALEIN(a) (a)
#define SCALEOUT(a) (a)
#define ABS16(x) ((x) < 0 ? (-(x)) : (x))
#define ABS32(x) ((x) < 0 ? (-(x)) : (x))
@@ -191,6 +254,10 @@ typedef float opus_val64;
typedef float celt_sig;
typedef float celt_norm;
typedef float celt_ener;
typedef float celt_glog;
typedef float opus_res;
typedef float celt_coef;
#ifdef FLOAT_APPROX
/* This code should reliably detect NaN/inf even when -ffast-math is used.
@@ -209,6 +276,9 @@ static OPUS_INLINE int celt_isnan(float x)
#endif
#define Q15ONE 1.0f
#define Q31ONE 1.0f
#define COEF_ONE 1.0f
#define COEF2VAL16(x) (x)
#define NORM_SCALING 1.f
@@ -223,6 +293,7 @@ static OPUS_INLINE int celt_isnan(float x)
#define QCONST16(x,bits) (x)
#define QCONST32(x,bits) (x)
#define GCONST(x) (x)
#define NEG16(x) (-(x))
#define NEG32(x) (-(x))
@@ -264,6 +335,7 @@ static OPUS_INLINE int celt_isnan(float x)
#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b))
#define MAC16_32_Q16(c,a,b) ((c)+(a)*(b))
#define MAC_COEF_32_ARM(c,a,b) ((c)+(a)*(b))
#define MULT16_16_Q11_32(a,b) ((a)*(b))
#define MULT16_16_Q11(a,b) ((a)*(b))
@@ -275,13 +347,29 @@ static OPUS_INLINE int celt_isnan(float x)
#define MULT16_16_P14(a,b) ((a)*(b))
#define MULT16_32_P16(a,b) ((a)*(b))
#define MULT_COEF_32(a, b) ((a)*(b))
#define MULT_COEF(a, b) ((a)*(b))
#define MULT_COEF_TAPS(a, b) ((a)*(b))
#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 SIG2RES(a) ((1/CELT_SIG_SCALE)*(a))
#define RES2INT16(a) FLOAT2INT16(a)
#define RES2INT24(a) float2int(32768.f*256.f*(a))
#define RES2FLOAT(a) (a)
#define INT16TORES(a) ((a)*(1/CELT_SIG_SCALE))
#define INT24TORES(a) ((1.f/32768.f/256.)*(a))
#define ADD_RES(a, b) ADD32(a, b)
#define FLOAT2RES(a) (a)
#define RES2SIG(a) (CELT_SIG_SCALE*(a))
#define MULT16_RES_Q15(a,b) MULT16_16_Q15(a,b)
#define SIG2WORD16(x) (x)
#define RES2VAL16(a) (a)
#define FLOAT2SIG(a) ((a)*CELT_SIG_SCALE)
#define INT16TOSIG(a) ((float)(a))
#define INT24TOSIG(a) ((float)(a)*(1.f/256.f))
#define MAX_ENCODING_DEPTH 24
#endif /* !FIXED_POINT */

View File

@@ -108,20 +108,27 @@ void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *band
maxval = celt_maxabs32(&X[c*N+(eBands[i]<<LM)], (eBands[i+1]-eBands[i])<<LM);
if (maxval > 0)
{
int shift = celt_ilog2(maxval) - 14 + (((m->logN[i]>>BITRES)+LM+1)>>1);
int shift, shift2;
shift = celt_ilog2(maxval) - 14;
shift2 = (((m->logN[i]>>BITRES)+LM+1)>>1);
j=eBands[i]<<LM;
if (shift>0)
{
do {
sum = MAC16_16(sum, EXTRACT16(SHR32(X[j+c*N],shift)),
EXTRACT16(SHR32(X[j+c*N],shift)));
sum = ADD32(sum, SHR32(MULT16_16(EXTRACT16(SHR32(X[j+c*N],shift)),
EXTRACT16(SHR32(X[j+c*N],shift))), 2*shift2));
} while (++j<eBands[i+1]<<LM);
} else {
do {
sum = MAC16_16(sum, EXTRACT16(SHL32(X[j+c*N],-shift)),
EXTRACT16(SHL32(X[j+c*N],-shift)));
sum = ADD32(sum, SHR32(MULT16_16(EXTRACT16(SHL32(X[j+c*N],-shift)),
EXTRACT16(SHL32(X[j+c*N],-shift))), 2*shift2));
} while (++j<eBands[i+1]<<LM);
}
shift+=shift2;
while (sum < 1<<28) {
sum <<=2;
shift -= 1;
}
/* We're adding one here to ensure the normalized band isn't larger than unity norm */
bandE[i+c*m->nbEBands] = EPSILON+VSHR32(celt_sqrt(sum),-shift);
} else {
@@ -143,13 +150,19 @@ void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, cel
i=0; do {
opus_val16 g;
int j,shift;
opus_val16 E;
shift = celt_zlog2(bandE[i+c*m->nbEBands])-13;
E = VSHR32(bandE[i+c*m->nbEBands], shift);
g = EXTRACT16(celt_rcp(SHL32(E,3)));
opus_val32 E;
shift = celt_zlog2(bandE[i+c*m->nbEBands])-14;
E = VSHR32(bandE[i+c*m->nbEBands], shift-2);
g = EXTRACT16(celt_rcp(E));
if (shift > 0) {
j=M*eBands[i]; do {
X[j+c*N] = MULT16_16_Q15(VSHR32(freq[j+c*N],shift-1),g);
X[j+c*N] = PSHR32(MULT16_32_Q15(g, freq[j+c*N]),shift);
} while (++j<M*eBands[i+1]);
} else {
j=M*eBands[i]; do {
X[j+c*N] = SHL32(MULT16_32_Q15(g, freq[j+c*N]),-shift);
} while (++j<M*eBands[i+1]);
}
} while (++i<end);
} while (++c<C);
}
@@ -194,7 +207,7 @@ void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, cel
/* De-normalise the energy to produce the synthesis from the unit-energy bands */
void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
celt_sig * OPUS_RESTRICT freq, const opus_val16 *bandLogE, int start,
celt_sig * OPUS_RESTRICT freq, const celt_glog *bandLogE, int start,
int end, int M, int downsample, int silence)
{
int i, N;
@@ -218,26 +231,26 @@ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
for (i=start;i<end;i++)
{
int j, band_end;
opus_val16 g;
opus_val16 lg;
opus_val32 g;
celt_glog lg;
#ifdef FIXED_POINT
int shift;
#endif
j=M*eBands[i];
band_end = M*eBands[i+1];
lg = SATURATE16(ADD32(bandLogE[i], SHL32((opus_val32)eMeans[i],6)));
lg = ADD32(bandLogE[i], SHL32((opus_val32)eMeans[i],DB_SHIFT-4));
#ifndef FIXED_POINT
g = celt_exp2(MIN32(32.f, lg));
g = celt_exp2_db(MIN32(32.f, lg));
#else
/* Handle the integer part of the log energy */
shift = 16-(lg>>DB_SHIFT);
shift = 15-(lg>>DB_SHIFT);
if (shift>31)
{
shift=0;
g=0;
} else {
/* Handle the fractional part. */
g = celt_exp2_frac(lg&((1<<DB_SHIFT)-1));
g = celt_exp2_db_frac((lg&((1<<DB_SHIFT)-1)));
}
/* Handle extreme gains with negative shift. */
if (shift<0)
@@ -247,17 +260,17 @@ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
This shouldn't trigger unless the bitstream is already corrupted. */
if (shift <= -2)
{
g = 16384;
g = 16384*32768;
shift = -2;
}
do {
*f++ = SHL32(MULT16_16(*x++, g), -shift);
*f++ = SHL32(MULT16_32_Q15(*x++, g), -shift);
} while (++j<band_end);
} else
#endif
/* Be careful of the fixed-point "else" just above when changing this code */
do {
*f++ = SHR32(MULT16_16(*x++, g), shift);
*f++ = SHR32(MULT16_32_Q15(*x++, g), shift);
} while (++j<band_end);
}
celt_assert(start <= end);
@@ -266,8 +279,8 @@ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
/* This prevents energy collapse for transients with multiple short MDCTs */
void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_masks, int LM, int C, int size,
int start, int end, const opus_val16 *logE, const opus_val16 *prev1logE,
const opus_val16 *prev2logE, const int *pulses, opus_uint32 seed, int encode, int arch)
int start, int end, const celt_glog *logE, const celt_glog *prev1logE,
const celt_glog *prev2logE, const int *pulses, opus_uint32 seed, int encode, int arch)
{
int c, i, j, k;
for (i=start;i<end;i++)
@@ -303,8 +316,8 @@ void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_mas
c=0; do
{
celt_norm *X;
opus_val16 prev1;
opus_val16 prev2;
celt_glog prev1;
celt_glog prev2;
opus_val32 Ediff;
opus_val16 r;
int renormalize=0;
@@ -312,16 +325,16 @@ void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_mas
prev2 = prev2logE[c*m->nbEBands+i];
if (!encode && C==1)
{
prev1 = MAX16(prev1,prev1logE[m->nbEBands+i]);
prev2 = MAX16(prev2,prev2logE[m->nbEBands+i]);
prev1 = MAXG(prev1,prev1logE[m->nbEBands+i]);
prev2 = MAXG(prev2,prev2logE[m->nbEBands+i]);
}
Ediff = EXTEND32(logE[c*m->nbEBands+i])-EXTEND32(MIN16(prev1,prev2));
Ediff = logE[c*m->nbEBands+i]-MING(prev1,prev2);
Ediff = MAX32(0, Ediff);
#ifdef FIXED_POINT
if (Ediff < 16384)
if (Ediff < GCONST(16.f))
{
opus_val32 r32 = SHR32(celt_exp2(-EXTRACT16(Ediff)),1);
opus_val32 r32 = SHR32(celt_exp2_db(-Ediff),1);
r = 2*MIN16(16383,r32);
} else {
r = 0;
@@ -333,7 +346,7 @@ void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_mas
#else
/* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because
short blocks don't have the same energy as long */
r = 2.f*celt_exp2(-Ediff);
r = 2.f*celt_exp2_db(-Ediff);
if (LM==3)
r *= 1.41421356f;
r = MIN16(thresh, r);
@@ -356,7 +369,7 @@ void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_mas
}
/* We just added some energy, so we need to renormalise */
if (renormalize)
renormalise_vector(X, N0<<LM, Q15ONE, arch);
renormalise_vector(X, N0<<LM, Q31ONE, arch);
} while (++c<C);
}
}
@@ -423,12 +436,11 @@ static void stereo_split(celt_norm * OPUS_RESTRICT X, celt_norm * OPUS_RESTRICT
}
}
static void stereo_merge(celt_norm * OPUS_RESTRICT X, celt_norm * OPUS_RESTRICT Y, opus_val16 mid, int N, int arch)
static void stereo_merge(celt_norm * OPUS_RESTRICT X, celt_norm * OPUS_RESTRICT Y, opus_val32 mid, int N, int arch)
{
int j;
opus_val32 xp=0, side=0;
opus_val32 El, Er;
opus_val16 mid2;
#ifdef FIXED_POINT
int kl, kr;
#endif
@@ -437,11 +449,10 @@ static void stereo_merge(celt_norm * OPUS_RESTRICT X, celt_norm * OPUS_RESTRICT
/* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */
dual_inner_prod(Y, X, Y, N, &xp, &side, arch);
/* Compensating for the mid normalization */
xp = MULT16_32_Q15(mid, xp);
xp = MULT32_32_Q31(mid, xp);
/* mid and side are in Q15, not Q14 like X and Y */
mid2 = SHR16(mid, 1);
El = MULT16_16(mid2, mid2) + side - 2*xp;
Er = MULT16_16(mid2, mid2) + side + 2*xp;
El = SHR32(MULT32_32_Q31(mid, mid),3) + side - 2*xp;
Er = SHR32(MULT32_32_Q31(mid, mid),3) + side + 2*xp;
if (Er < QCONST32(6e-4f, 28) || El < QCONST32(6e-4f, 28))
{
OPUS_COPY(Y, X, N);
@@ -468,7 +479,7 @@ static void stereo_merge(celt_norm * OPUS_RESTRICT X, celt_norm * OPUS_RESTRICT
{
celt_norm r, l;
/* Apply mid scaling (side is already scaled) */
l = MULT16_16_P15(mid, X[j]);
l = MULT32_32_Q31(mid, X[j]);
r = Y[j];
X[j] = EXTRACT16(PSHR32(MULT16_16(lgain, SUB16(l,r)), kl+1));
Y[j] = EXTRACT16(PSHR32(MULT16_16(rgain, ADD16(l,r)), kr+1));
@@ -943,14 +954,14 @@ static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y,
static unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,
int N, int b, int B, celt_norm *lowband,
int LM,
opus_val16 gain, int fill)
opus_val32 gain, int fill)
{
const unsigned char *cache;
int q;
int curr_bits;
int imid=0, iside=0;
int B0=B;
opus_val16 mid=0, side=0;
opus_val32 mid=0, side=0;
unsigned cm=0;
celt_norm *Y=NULL;
int encode;
@@ -990,8 +1001,8 @@ static unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,
itheta = sctx.itheta;
qalloc = sctx.qalloc;
#ifdef FIXED_POINT
mid = imid;
side = iside;
mid = SHL32(EXTEND32(imid), 16);
side = SHL32(EXTEND32(iside), 16);
#else
mid = (1.f/32768)*imid;
side = (1.f/32768)*iside;
@@ -1018,20 +1029,20 @@ static unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,
if (mbits >= sbits)
{
cm = quant_partition(ctx, X, N, mbits, B, lowband, LM,
MULT16_16_P15(gain,mid), fill);
MULT32_32_Q31(gain,mid), fill);
rebalance = mbits - (rebalance-ctx->remaining_bits);
if (rebalance > 3<<BITRES && itheta!=0)
sbits += rebalance - (3<<BITRES);
cm |= quant_partition(ctx, Y, N, sbits, B, next_lowband2, LM,
MULT16_16_P15(gain,side), fill>>B)<<(B0>>1);
MULT32_32_Q31(gain,side), fill>>B)<<(B0>>1);
} else {
cm = quant_partition(ctx, Y, N, sbits, B, next_lowband2, LM,
MULT16_16_P15(gain,side), fill>>B)<<(B0>>1);
MULT32_32_Q31(gain,side), fill>>B)<<(B0>>1);
rebalance = sbits - (rebalance-ctx->remaining_bits);
if (rebalance > 3<<BITRES && itheta!=16384)
mbits += rebalance - (3<<BITRES);
cm |= quant_partition(ctx, X, N, mbits, B, lowband, LM,
MULT16_16_P15(gain,mid), fill);
MULT32_32_Q31(gain,mid), fill);
}
} else {
/* This is the basic no-split case */
@@ -1109,7 +1120,7 @@ static unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,
static unsigned quant_band(struct band_ctx *ctx, celt_norm *X,
int N, int b, int B, celt_norm *lowband,
int LM, celt_norm *lowband_out,
opus_val16 gain, celt_norm *lowband_scratch, int fill)
opus_val32 gain, celt_norm *lowband_scratch, int fill)
{
int N0=N;
int N_B=N;
@@ -1239,7 +1250,7 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
{
int imid=0, iside=0;
int inv = 0;
opus_val16 mid=0, side=0;
opus_val32 mid=0, side=0;
unsigned cm=0;
int mbits, sbits, delta;
int itheta;
@@ -1268,8 +1279,8 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
itheta = sctx.itheta;
qalloc = sctx.qalloc;
#ifdef FIXED_POINT
mid = imid;
side = iside;
mid = SHL32(EXTEND32(imid), 16);
side = SHL32(EXTEND32(iside), 16);
#else
mid = (1.f/32768)*imid;
side = (1.f/32768)*iside;
@@ -1308,7 +1319,7 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
sign = 1-2*sign;
/* We use orig_fill here because we want to fold the side, but if
itheta==16384, we'll have cleared the low bits of fill. */
cm = quant_band(ctx, x2, N, mbits, B, lowband, LM, lowband_out, Q15ONE,
cm = quant_band(ctx, x2, N, mbits, B, lowband, LM, lowband_out, Q31ONE,
lowband_scratch, orig_fill);
/* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse),
and there's no need to worry about mixing with the other channel. */
@@ -1317,10 +1328,10 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
if (ctx->resynth)
{
celt_norm tmp;
X[0] = MULT16_16_Q15(mid, X[0]);
X[1] = MULT16_16_Q15(mid, X[1]);
Y[0] = MULT16_16_Q15(side, Y[0]);
Y[1] = MULT16_16_Q15(side, Y[1]);
X[0] = MULT32_32_Q31(mid, X[0]);
X[1] = MULT32_32_Q31(mid, X[1]);
Y[0] = MULT32_32_Q31(side, Y[0]);
Y[1] = MULT32_32_Q31(side, Y[1]);
tmp = X[0];
X[0] = SUB16(tmp,Y[0]);
Y[0] = ADD16(tmp,Y[0]);
@@ -1341,7 +1352,7 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
{
/* In stereo mode, we do not apply a scaling to the mid because we need the normalized
mid for folding later. */
cm = quant_band(ctx, X, N, mbits, B, lowband, LM, lowband_out, Q15ONE,
cm = quant_band(ctx, X, N, mbits, B, lowband, LM, lowband_out, Q31ONE,
lowband_scratch, fill);
rebalance = mbits - (rebalance-ctx->remaining_bits);
if (rebalance > 3<<BITRES && itheta!=0)
@@ -1359,7 +1370,7 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
mbits += rebalance - (3<<BITRES);
/* In stereo mode, we do not apply a scaling to the mid because we need the normalized
mid for folding later. */
cm |= quant_band(ctx, X, N, mbits, B, lowband, LM, lowband_out, Q15ONE,
cm |= quant_band(ctx, X, N, mbits, B, lowband, LM, lowband_out, Q31ONE,
lowband_scratch, fill);
}
}
@@ -1573,10 +1584,10 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
{
x_cm = quant_band(&ctx, X, N, b/2, B,
effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm);
last?NULL:norm+M*eBands[i]-norm_offset, Q31ONE, lowband_scratch, x_cm);
y_cm = quant_band(&ctx, Y, N, b/2, B,
effective_lowband != -1 ? norm2+effective_lowband : NULL, LM,
last?NULL:norm2+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, y_cm);
last?NULL:norm2+M*eBands[i]-norm_offset, Q31ONE, lowband_scratch, y_cm);
} else {
if (Y!=NULL)
{
@@ -1652,7 +1663,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
} else {
x_cm = quant_band(&ctx, X, N, b, B,
effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm|y_cm);
last?NULL:norm+M*eBands[i]-norm_offset, Q31ONE, lowband_scratch, x_cm|y_cm);
}
y_cm = x_cm;
}

View File

@@ -62,7 +62,7 @@ void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, cel
* @param bandE Square root of the energy for each band
*/
void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
celt_sig * OPUS_RESTRICT freq, const opus_val16 *bandE, int start,
celt_sig * OPUS_RESTRICT freq, const celt_glog *bandE, int start,
int end, int M, int downsample, int silence);
#define SPREAD_NONE (0)
@@ -112,8 +112,8 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
void anti_collapse(const CELTMode *m, celt_norm *X_,
unsigned char *collapse_masks, int LM, int C, int size, int start,
int end, const opus_val16 *logE, const opus_val16 *prev1logE,
const opus_val16 *prev2logE, const int *pulses, opus_uint32 seed,
int end, const celt_glog *logE, const celt_glog *prev1logE,
const celt_glog *prev2logE, const int *pulses, opus_uint32 seed,
int encode, int arch);
opus_uint32 celt_lcg_rand(opus_uint32 seed);

View File

@@ -89,6 +89,7 @@ int resampling_factor(opus_int32 rate)
return ret;
}
#if !defined(OVERRIDE_COMB_FILTER_CONST) || defined(NON_STATIC_COMB_FILTER_CONST_C)
/* This version should be faster on ARM */
#ifdef OPUS_ARM_ASM
@@ -96,7 +97,7 @@ int resampling_factor(opus_int32 rate)
static
#endif
void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
opus_val16 g10, opus_val16 g11, opus_val16 g12)
celt_coef g10, celt_coef g11, celt_coef g12)
{
opus_val32 x0, x1, x2, x3, x4;
int i;
@@ -108,33 +109,33 @@ void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
{
opus_val32 t;
x0=SHL32(x[i-T+2],1);
t = MAC16_32_Q16(x[i], g10, x2);
t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
t = MAC_COEF_32_ARM(x[i], g10, x2);
t = MAC_COEF_32_ARM(t, g11, ADD32(x1,x3));
t = MAC_COEF_32_ARM(t, g12, ADD32(x0,x4));
t = SATURATE(t, SIG_SAT);
y[i] = t;
x4=SHL32(x[i-T+3],1);
t = MAC16_32_Q16(x[i+1], g10, x1);
t = MAC16_32_Q16(t, g11, ADD32(x0,x2));
t = MAC16_32_Q16(t, g12, ADD32(x4,x3));
t = MAC_COEF_32_ARM(x[i+1], g10, x1);
t = MAC_COEF_32_ARM(t, g11, ADD32(x0,x2));
t = MAC_COEF_32_ARM(t, g12, ADD32(x4,x3));
t = SATURATE(t, SIG_SAT);
y[i+1] = t;
x3=SHL32(x[i-T+4],1);
t = MAC16_32_Q16(x[i+2], g10, x0);
t = MAC16_32_Q16(t, g11, ADD32(x4,x1));
t = MAC16_32_Q16(t, g12, ADD32(x3,x2));
t = MAC_COEF_32_ARM(x[i+2], g10, x0);
t = MAC_COEF_32_ARM(t, g11, ADD32(x4,x1));
t = MAC_COEF_32_ARM(t, g12, ADD32(x3,x2));
t = SATURATE(t, SIG_SAT);
y[i+2] = t;
x2=SHL32(x[i-T+5],1);
t = MAC16_32_Q16(x[i+3], g10, x4);
t = MAC16_32_Q16(t, g11, ADD32(x3,x0));
t = MAC16_32_Q16(t, g12, ADD32(x2,x1));
t = MAC_COEF_32_ARM(x[i+3], g10, x4);
t = MAC_COEF_32_ARM(t, g11, ADD32(x3,x0));
t = MAC_COEF_32_ARM(t, g12, ADD32(x2,x1));
t = SATURATE(t, SIG_SAT);
y[i+3] = t;
x1=SHL32(x[i-T+6],1);
t = MAC16_32_Q16(x[i+4], g10, x3);
t = MAC16_32_Q16(t, g11, ADD32(x2,x4));
t = MAC16_32_Q16(t, g12, ADD32(x1,x0));
t = MAC_COEF_32_ARM(x[i+4], g10, x3);
t = MAC_COEF_32_ARM(t, g11, ADD32(x2,x4));
t = MAC_COEF_32_ARM(t, g12, ADD32(x1,x0));
t = SATURATE(t, SIG_SAT);
y[i+4] = t;
}
@@ -143,9 +144,9 @@ void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
{
opus_val32 t;
x0=SHL32(x[i-T+2],1);
t = MAC16_32_Q16(x[i], g10, x2);
t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
t = MAC_COEF_32_ARM(x[i], g10, x2);
t = MAC_COEF_32_ARM(t, g11, ADD32(x1,x3));
t = MAC_COEF_32_ARM(t, g12, ADD32(x0,x4));
t = SATURATE(t, SIG_SAT);
y[i] = t;
x4=x3;
@@ -160,7 +161,7 @@ void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
static
#endif
void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
opus_val16 g10, opus_val16 g11, opus_val16 g12)
celt_coef g10, celt_coef g11, celt_coef g12)
{
opus_val32 x0, x1, x2, x3, x4;
int i;
@@ -172,9 +173,9 @@ void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
{
x0=x[i-T+2];
y[i] = x[i]
+ MULT16_32_Q15(g10,x2)
+ MULT16_32_Q15(g11,ADD32(x1,x3))
+ MULT16_32_Q15(g12,ADD32(x0,x4));
+ MULT_COEF_32(g10,x2)
+ MULT_COEF_32(g11,ADD32(x1,x3))
+ MULT_COEF_32(g12,ADD32(x0,x4));
y[i] = SATURATE(y[i], SIG_SAT);
x4=x3;
x3=x2;
@@ -189,11 +190,11 @@ void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
#ifndef OVERRIDE_comb_filter
void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
const opus_val16 *window, int overlap, int arch)
const celt_coef *window, int overlap, int arch)
{
int i;
/* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
opus_val16 g00, g01, g02, g10, g11, g12;
celt_coef g00, g01, g02, g10, g11, g12;
opus_val32 x0, x1, x2, x3, x4;
static const opus_val16 gains[3][3] = {
{QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
@@ -211,12 +212,12 @@ void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
to have then be at least 2 to avoid processing garbage data. */
T0 = IMAX(T0, COMBFILTER_MINPERIOD);
T1 = IMAX(T1, COMBFILTER_MINPERIOD);
g00 = MULT16_16_P15(g0, gains[tapset0][0]);
g01 = MULT16_16_P15(g0, gains[tapset0][1]);
g02 = MULT16_16_P15(g0, gains[tapset0][2]);
g10 = MULT16_16_P15(g1, gains[tapset1][0]);
g11 = MULT16_16_P15(g1, gains[tapset1][1]);
g12 = MULT16_16_P15(g1, gains[tapset1][2]);
g00 = MULT_COEF_TAPS(g0, gains[tapset0][0]);
g01 = MULT_COEF_TAPS(g0, gains[tapset0][1]);
g02 = MULT_COEF_TAPS(g0, gains[tapset0][2]);
g10 = MULT_COEF_TAPS(g1, gains[tapset1][0]);
g11 = MULT_COEF_TAPS(g1, gains[tapset1][1]);
g12 = MULT_COEF_TAPS(g1, gains[tapset1][2]);
x1 = x[-T1+1];
x2 = x[-T1 ];
x3 = x[-T1-1];
@@ -226,16 +227,16 @@ void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
overlap=0;
for (i=0;i<overlap;i++)
{
opus_val16 f;
celt_coef f;
x0=x[i-T1+2];
f = MULT16_16_Q15(window[i],window[i]);
f = MULT_COEF(window[i],window[i]);
y[i] = x[i]
+ MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g00),x[i-T0])
+ MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
+ MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
+ MULT16_32_Q15(MULT16_16_Q15(f,g10),x2)
+ MULT16_32_Q15(MULT16_16_Q15(f,g11),ADD32(x1,x3))
+ MULT16_32_Q15(MULT16_16_Q15(f,g12),ADD32(x0,x4));
+ MULT_COEF_32(MULT_COEF((COEF_ONE-f),g00),x[i-T0])
+ MULT_COEF_32(MULT_COEF((COEF_ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
+ MULT_COEF_32(MULT_COEF((COEF_ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
+ MULT_COEF_32(MULT_COEF(f,g10),x2)
+ MULT_COEF_32(MULT_COEF(f,g11),ADD32(x1,x3))
+ MULT_COEF_32(MULT_COEF(f,g12),ADD32(x0,x4));
y[i] = SATURATE(y[i], SIG_SAT);
x4=x3;
x3=x2;

View File

@@ -41,6 +41,7 @@
#include "entenc.h"
#include "entdec.h"
#include "arch.h"
#include "kiss_fft.h"
#ifdef ENABLE_DEEP_PLC
#include "lpcnet.h"
@@ -83,6 +84,8 @@ typedef struct {
#define __celt_check_silkinfo_ptr(ptr) ((ptr) + ((ptr) - (const SILKInfo*)(ptr)))
#define __celt_check_glog_ptr(ptr) ((ptr) + ((ptr) - (celt_glog*)(ptr)))
/* Encoder/decoder Requests */
@@ -130,7 +133,7 @@ typedef struct {
#define OPUS_SET_LFE(x) OPUS_SET_LFE_REQUEST, __opus_check_int(x)
#define OPUS_SET_ENERGY_MASK_REQUEST 10026
#define OPUS_SET_ENERGY_MASK(x) OPUS_SET_ENERGY_MASK_REQUEST, __opus_check_val16_ptr(x)
#define OPUS_SET_ENERGY_MASK(x) OPUS_SET_ENERGY_MASK_REQUEST, __celt_check_glog_ptr(x)
#define CELT_SET_SILK_INFO_REQUEST 10028
#define CELT_SET_SILK_INFO(x) CELT_SET_SILK_INFO_REQUEST, __celt_check_silkinfo_ptr(x)
@@ -139,7 +142,7 @@ typedef struct {
int celt_encoder_get_size(int channels);
int celt_encode_with_ec(OpusCustomEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc);
int celt_encode_with_ec(OpusCustomEncoder * OPUS_RESTRICT st, const opus_res * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc);
int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels,
int arch);
@@ -154,14 +157,14 @@ int celt_decoder_get_size(int channels);
int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels);
int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data,
int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum
int len, opus_res * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum
#ifdef ENABLE_DEEP_PLC
,LPCNetPLCState *lpcnet
#endif
);
int celt_decode_with_ec(OpusCustomDecoder * OPUS_RESTRICT st, const unsigned char *data,
int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum);
int len, opus_res * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum);
#define celt_encoder_ctl opus_custom_encoder_ctl
#define celt_decoder_ctl opus_custom_decoder_ctl
@@ -229,19 +232,19 @@ void validate_celt_decoder(CELTDecoder *st);
int resampling_factor(opus_int32 rate);
void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp,
void celt_preemphasis(const opus_res * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp,
int N, int CC, int upsample, const opus_val16 *coef, celt_sig *mem, int clip);
void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
const opus_val16 *window, int overlap, int arch);
const celt_coef *window, int overlap, int arch);
void init_caps(const CELTMode *m,int *cap,int LM,int C);
#ifdef RESYNTH
void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem, int accum);
void deemphasis(celt_sig *in[], opus_res *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem, int accum);
void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
opus_val16 *oldBandE, int start, int effEnd, int C, int CC, int isTransient,
celt_glog *oldBandE, int start, int effEnd, int C, int CC, int isTransient,
int LM, int downsample, int silence, int arch);
#endif

View File

@@ -116,10 +116,10 @@ struct OpusCustomDecoder {
celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */
/* opus_val16 lpc[], Size = channels*CELT_LPC_ORDER */
/* opus_val16 oldEBands[], Size = 2*mode->nbEBands */
/* opus_val16 oldLogE[], Size = 2*mode->nbEBands */
/* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */
/* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */
/* celt_glog oldEBands[], Size = 2*mode->nbEBands */
/* celt_glog oldLogE[], Size = 2*mode->nbEBands */
/* celt_glog oldLogE2[], Size = 2*mode->nbEBands */
/* celt_glog backgroundLogE[], Size = 2*mode->nbEBands */
};
#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
@@ -171,7 +171,7 @@ OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_get_size(const CELTMode *mode, int
int size = sizeof(struct CELTDecoder)
+ (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig)
+ channels*CELT_LPC_ORDER*sizeof(opus_val16)
+ 4*2*mode->nbEBands*sizeof(opus_val16);
+ 4*2*mode->nbEBands*sizeof(celt_glog);
return size;
}
@@ -246,7 +246,7 @@ void opus_custom_decoder_destroy(CELTDecoder *st)
/* Special case for stereo with no downsampling and no accumulation. This is
quite common and we can make it faster by processing both channels in the
same loop, reducing overhead due to the dependency loop in the IIR filter. */
static void deemphasis_stereo_simple(celt_sig *in[], opus_val16 *pcm, int N, const opus_val16 coef0,
static void deemphasis_stereo_simple(celt_sig *in[], opus_res *pcm, int N, const opus_val16 coef0,
celt_sig *mem)
{
celt_sig * OPUS_RESTRICT x0;
@@ -265,8 +265,8 @@ static void deemphasis_stereo_simple(celt_sig *in[], opus_val16 *pcm, int N, con
tmp1 = SATURATE(x1[j] + VERY_SMALL + m1, SIG_SAT);
m0 = MULT16_32_Q15(coef0, tmp0);
m1 = MULT16_32_Q15(coef0, tmp1);
pcm[2*j ] = SCALEOUT(SIG2WORD16(tmp0));
pcm[2*j+1] = SCALEOUT(SIG2WORD16(tmp1));
pcm[2*j ] = SIG2RES(tmp0);
pcm[2*j+1] = SIG2RES(tmp1);
}
mem[0] = m0;
mem[1] = m1;
@@ -276,7 +276,7 @@ static void deemphasis_stereo_simple(celt_sig *in[], opus_val16 *pcm, int N, con
#ifndef RESYNTH
static
#endif
void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef,
void deemphasis(celt_sig *in[], opus_res *pcm, int N, int C, int downsample, const opus_val16 *coef,
celt_sig *mem, int accum)
{
int c;
@@ -292,10 +292,6 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
deemphasis_stereo_simple(in, pcm, N, coef[0], mem);
return;
}
#endif
#ifndef FIXED_POINT
(void)accum;
celt_assert(accum==0);
#endif
ALLOC(scratch, N, celt_sig);
coef0 = coef[0];
@@ -303,7 +299,7 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
c=0; do {
int j;
celt_sig * OPUS_RESTRICT x;
opus_val16 * OPUS_RESTRICT y;
opus_res * OPUS_RESTRICT y;
celt_sig m = mem[c];
x =in[c];
y = pcm+c;
@@ -335,23 +331,21 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
apply_downsampling=1;
} else {
/* Shortcut for the standard (non-custom modes) case */
#ifdef FIXED_POINT
if (accum)
{
for (j=0;j<N;j++)
{
celt_sig tmp = SATURATE(x[j] + m + VERY_SMALL, SIG_SAT);
m = MULT16_32_Q15(coef0, tmp);
y[j*C] = SAT16(ADD32(y[j*C], SCALEOUT(SIG2WORD16(tmp))));
y[j*C] = ADD_RES(y[j*C], SIG2RES(tmp));
}
} else
#endif
{
for (j=0;j<N;j++)
{
celt_sig tmp = SATURATE(x[j] + VERY_SMALL + m, SIG_SAT);
m = MULT16_32_Q15(coef0, tmp);
y[j*C] = SCALEOUT(SIG2WORD16(tmp));
y[j*C] = SIG2RES(tmp);
}
}
}
@@ -360,16 +354,14 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
if (apply_downsampling)
{
/* Perform down-sampling */
#ifdef FIXED_POINT
if (accum)
{
for (j=0;j<Nd;j++)
y[j*C] = SAT16(ADD32(y[j*C], SCALEOUT(SIG2WORD16(scratch[j*downsample]))));
y[j*C] = ADD_RES(y[j*C], SIG2RES(scratch[j*downsample]));
} else
#endif
{
for (j=0;j<Nd;j++)
y[j*C] = SCALEOUT(SIG2WORD16(scratch[j*downsample]));
y[j*C] = SIG2RES(scratch[j*downsample]);
}
}
} while (++c<C);
@@ -380,7 +372,7 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
static
#endif
void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
opus_val16 *oldBandE, int start, int effEnd, int C, int CC,
celt_glog *oldBandE, int start, int effEnd, int C, int CC,
int isTransient, int LM, int downsample,
int silence, int arch)
{
@@ -543,8 +535,8 @@ static void prefilter_and_fold(CELTDecoder * OPUS_RESTRICT st, int N)
for (i=0;i<overlap/2;i++)
{
decode_mem[c][DECODE_BUFFER_SIZE-N+i] =
MULT16_32_Q15(mode->window[i], etmp[overlap-1-i])
+ MULT16_32_Q15(mode->window[overlap-i-1], etmp[i]);
MULT16_32_Q15(COEF2VAL16(mode->window[i]), etmp[overlap-1-i])
+ MULT16_32_Q15 (COEF2VAL16(mode->window[overlap-i-1]), etmp[i]);
}
} while (++c<CC);
}
@@ -613,7 +605,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM
celt_sig *decode_mem[2];
celt_sig *out_syn[2];
opus_val16 *lpc;
opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
celt_glog *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
const OpusCustomMode *mode;
int nbEBands;
int overlap;
@@ -633,7 +625,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM
out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N;
} while (++c<C);
lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+overlap)*C);
oldBandE = lpc+C*CELT_LPC_ORDER;
oldBandE = (celt_glog*)(lpc+C*CELT_LPC_ORDER);
oldLogE = oldBandE + 2*nbEBands;
oldLogE2 = oldLogE + 2*nbEBands;
backgroundLogE = oldLogE2 + 2*nbEBands;
@@ -652,7 +644,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM
opus_uint32 seed;
int end;
int effEnd;
opus_val16 decay;
celt_glog decay;
end = st->end;
effEnd = IMAX(start, IMIN(end, mode->effEBands));
@@ -667,11 +659,11 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM
}
/* Energy decay */
decay = loss_duration==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT);
decay = loss_duration==0 ? GCONST(1.5f) : GCONST(.5f);
c=0; do
{
for (i=start;i<end;i++)
oldBandE[c*nbEBands+i] = MAX16(backgroundLogE[c*nbEBands+i], oldBandE[c*nbEBands+i] - decay);
oldBandE[c*nbEBands+i] = MAXG(backgroundLogE[c*nbEBands+i], oldBandE[c*nbEBands+i] - decay);
} while (++c<C);
seed = st->rng;
for (c=0;c<C;c++)
@@ -688,7 +680,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM
seed = celt_lcg_rand(seed);
X[boffs+j] = (celt_norm)((opus_int32)seed>>20);
}
renormalise_vector(X+boffs, blen, Q15ONE, st->arch);
renormalise_vector(X+boffs, blen, Q31ONE, st->arch);
}
}
st->rng = seed;
@@ -700,7 +692,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM
} else {
int exc_length;
/* Pitch-based PLC */
const opus_val16 *window;
const celt_coef *window;
opus_val16 *exc;
opus_val16 fade = Q15ONE;
int pitch_index;
@@ -888,7 +880,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM
for (i=0;i<overlap;i++)
{
opus_val16 tmp_g = Q15ONE
- MULT16_16_Q15(window[i], Q15ONE-ratio);
- MULT16_16_Q15(COEF2VAL16(window[i]), Q15ONE-ratio);
buf[DECODE_BUFFER_SIZE-N+i] =
MULT16_32_Q15(tmp_g, buf[DECODE_BUFFER_SIZE-N+i]);
}
@@ -968,7 +960,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM
}
int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data,
int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum
int len, opus_res * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum
#ifdef ENABLE_DEEP_PLC
,LPCNetPLCState *lpcnet
#endif
@@ -989,7 +981,7 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char
celt_sig *decode_mem[2];
celt_sig *out_syn[2];
opus_val16 *lpc;
opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
celt_glog *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
int shortBlocks;
int isTransient;
@@ -1018,7 +1010,7 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char
int nbEBands;
int overlap;
const opus_int16 *eBands;
opus_val16 max_background_increase;
celt_glog max_background_increase;
ALLOC_STACK;
VALIDATE_CELT_DECODER(st);
@@ -1031,7 +1023,7 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char
frame_size *= st->downsample;
lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+overlap)*CC);
oldBandE = lpc+CC*CELT_LPC_ORDER;
oldBandE = (celt_glog*)(lpc+CC*CELT_LPC_ORDER);
oldLogE = oldBandE + 2*nbEBands;
oldLogE2 = oldLogE + 2*nbEBands;
backgroundLogE = oldLogE2 + 2*nbEBands;
@@ -1114,7 +1106,7 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char
if (C==1)
{
for (i=0;i<nbEBands;i++)
oldBandE[i]=MAX16(oldBandE[i],oldBandE[nbEBands+i]);
oldBandE[i]=MAXG(oldBandE[i],oldBandE[nbEBands+i]);
}
total_bits = len*8;
@@ -1171,13 +1163,13 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char
if (!intra_ener && st->loss_duration != 0) {
c=0; do
{
opus_val16 safety = 0;
celt_glog safety = 0;
int missing = IMIN(10, st->loss_duration>>LM);
if (LM==0) safety = QCONST16(1.5f,DB_SHIFT);
else if (LM==1) safety = QCONST16(.5f,DB_SHIFT);
if (LM==0) safety = GCONST(1.5f);
else if (LM==1) safety = GCONST(.5f);
for (i=start;i<end;i++)
{
if (oldBandE[c*nbEBands+i] < MAX16(oldLogE[c*nbEBands+i], oldLogE2[c*nbEBands+i])) {
if (oldBandE[c*nbEBands+i] < MAXG(oldLogE[c*nbEBands+i], oldLogE2[c*nbEBands+i])) {
/* If energy is going down already, continue the trend. */
opus_val32 slope;
opus_val32 E0, E1, E2;
@@ -1185,11 +1177,12 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char
E1 = oldLogE[c*nbEBands+i];
E2 = oldLogE2[c*nbEBands+i];
slope = MAX32(E1 - E0, HALF32(E2 - E0));
slope = MING(slope, GCONST(2.f));
E0 -= MAX32(0, (1+missing)*slope);
oldBandE[c*nbEBands+i] = MAX32(-QCONST16(20.f,DB_SHIFT), E0);
oldBandE[c*nbEBands+i] = MAX32(-GCONST(20.f), E0);
} else {
/* Otherwise take the min of the last frames. */
oldBandE[c*nbEBands+i] = MIN16(MIN16(oldBandE[c*nbEBands+i], oldLogE[c*nbEBands+i]), oldLogE2[c*nbEBands+i]);
oldBandE[c*nbEBands+i] = MING(MING(oldBandE[c*nbEBands+i], oldLogE[c*nbEBands+i]), oldLogE2[c*nbEBands+i]);
}
/* Shorter frames have more natural fluctuations -- play it safe. */
oldBandE[c*nbEBands+i] -= safety;
@@ -1291,7 +1284,7 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char
if (silence)
{
for (i=0;i<C*nbEBands;i++)
oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
oldBandE[i] = -GCONST(28.f);
}
if (st->prefilter_and_fold) {
prefilter_and_fold(st, N);
@@ -1333,26 +1326,26 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char
OPUS_COPY(oldLogE, oldBandE, 2*nbEBands);
} else {
for (i=0;i<2*nbEBands;i++)
oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
oldLogE[i] = MING(oldLogE[i], oldBandE[i]);
}
/* In normal circumstances, we only allow the noise floor to increase by
up to 2.4 dB/second, but when we're in DTX we give the weight of
all missing packets to the update packet. */
max_background_increase = IMIN(160, st->loss_duration+M)*QCONST16(0.001f,DB_SHIFT);
max_background_increase = IMIN(160, st->loss_duration+M)*GCONST(0.001f);
for (i=0;i<2*nbEBands;i++)
backgroundLogE[i] = MIN16(backgroundLogE[i] + max_background_increase, oldBandE[i]);
backgroundLogE[i] = MING(backgroundLogE[i] + max_background_increase, oldBandE[i]);
/* In case start or end were to change */
c=0; do
{
for (i=0;i<start;i++)
{
oldBandE[c*nbEBands+i]=0;
oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-GCONST(28.f);
}
for (i=end;i<nbEBands;i++)
{
oldBandE[c*nbEBands+i]=0;
oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-GCONST(28.f);
}
} while (++c<2);
st->rng = dec->rng;
@@ -1369,7 +1362,7 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char
}
int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data,
int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum)
int len, opus_res * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum)
{
return celt_decode_with_ec_dred(st, data, len, pcm, frame_size, dec, accum
#ifdef ENABLE_DEEP_PLC
@@ -1380,47 +1373,77 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
#ifdef CUSTOM_MODES
#ifdef FIXED_POINT
#if defined(FIXED_POINT) && !defined(ENABLE_RES24)
int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size)
{
return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0);
}
#else
int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size)
{
int j, ret, C, N;
VARDECL(opus_res, out);
ALLOC_STACK;
if (pcm==NULL)
return OPUS_BAD_ARG;
C = st->channels;
N = frame_size;
ALLOC(out, C*N, opus_res);
ret = celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0);
if (ret>0)
for (j=0;j<C*ret;j++)
pcm[j]=RES2INT16(out[j]);
RESTORE_STACK;
return ret;
}
#endif
#if defined(FIXED_POINT) && defined(ENABLE_RES24)
int opus_custom_decode24(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int32 * OPUS_RESTRICT pcm, int frame_size)
{
return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0);
}
#else
int opus_custom_decode24(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int32 * OPUS_RESTRICT pcm, int frame_size)
{
int j, ret, C, N;
VARDECL(opus_res, out);
ALLOC_STACK;
if (pcm==NULL)
return OPUS_BAD_ARG;
C = st->channels;
N = frame_size;
ALLOC(out, C*N, opus_res);
ret = celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0);
if (ret>0)
for (j=0;j<C*ret;j++)
pcm[j]=RES2INT24(out[j]);
RESTORE_STACK;
return ret;
}
#endif
#ifndef DISABLE_FLOAT_API
int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size)
{
int j, ret, C, N;
VARDECL(opus_int16, out);
ALLOC_STACK;
if (pcm==NULL)
return OPUS_BAD_ARG;
C = st->channels;
N = frame_size;
ALLOC(out, C*N, opus_int16);
ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0);
if (ret>0)
for (j=0;j<C*ret;j++)
pcm[j]=out[j]*(1.f/32768.f);
RESTORE_STACK;
return ret;
}
#endif /* DISABLE_FLOAT_API */
#else
# if !defined(FIXED_POINT)
int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size)
{
return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0);
}
int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size)
# else
int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size)
{
int j, ret, C, N;
VARDECL(celt_sig, out);
VARDECL(opus_res, out);
ALLOC_STACK;
if (pcm==NULL)
@@ -1428,19 +1451,20 @@ int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data
C = st->channels;
N = frame_size;
ALLOC(out, C*N, celt_sig);
ALLOC(out, C*N, opus_res);
ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0);
if (ret>0)
for (j=0;j<C*ret;j++)
pcm[j] = FLOAT2INT16 (out[j]);
pcm[j]=RES2FLOAT(out[j]);
RESTORE_STACK;
return ret;
}
# endif
#endif
#endif /* CUSTOM_MODES */
int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
@@ -1514,16 +1538,17 @@ int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
case OPUS_RESET_STATE:
{
int i;
opus_val16 *lpc, *oldBandE, *oldLogE, *oldLogE2;
opus_val16 *lpc;
celt_glog *oldBandE, *oldLogE, *oldLogE2;
lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels);
oldBandE = lpc+st->channels*CELT_LPC_ORDER;
oldBandE = (celt_glog*)(lpc+st->channels*CELT_LPC_ORDER);
oldLogE = oldBandE + 2*st->mode->nbEBands;
oldLogE2 = oldLogE + 2*st->mode->nbEBands;
OPUS_CLEAR((char*)&st->DECODER_RESET_START,
opus_custom_decoder_get_size(st->mode, st->channels)-
((char*)&st->DECODER_RESET_START - (char*)st));
for (i=0;i<2*st->mode->nbEBands;i++)
oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT);
oldLogE[i]=oldLogE2[i]=-GCONST(28.f);
st->skip_plc = 1;
}
break;

File diff suppressed because it is too large Load Diff

View File

@@ -277,7 +277,7 @@ void celt_iir(const opus_val32 *_x,
int _celt_autocorr(
const opus_val16 *x, /* in: [0...n-1] samples x */
opus_val32 *ac, /* out: [0...lag-1] ac values */
const opus_val16 *window,
const celt_coef *window,
int overlap,
int lag,
int n,
@@ -302,8 +302,9 @@ int _celt_autocorr(
xx[i] = x[i];
for (i=0;i<overlap;i++)
{
xx[i] = MULT16_16_Q15(x[i],window[i]);
xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]);
opus_val16 w = COEF2VAL16(window[i]);
xx[i] = MULT16_16_Q15(x[i],w);
xx[n-i-1] = MULT16_16_Q15(x[n-i-1],w);
}
xptr = xx;
}

View File

@@ -61,6 +61,6 @@ void celt_iir(const opus_val32 *x,
int arch);
int _celt_autocorr(const opus_val16 *x, opus_val32 *ac,
const opus_val16 *window, int overlap, int lag, int n, int arch);
const celt_coef *window, int overlap, int lag, int n, int arch);
#endif /* PLC_H */

View File

@@ -43,6 +43,7 @@ extern opus_int64 celt_mips;
#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))
#define MULT32_32_Q31(a,b) ADD32(ADD32(SHL32(MULT16_16(SHR32((a),16),SHR((b),16)),1), SHR32(MULT16_16SU(SHR32((a),16),((b)&0x0000ffff)),15)), SHR32(MULT16_16SU(SHR32((b),16),((a)&0x0000ffff)),15))
#define MULT32_32_Q32(a,b) ADD32(ADD32(MULT16_16(SHR((a),16),SHR((b),16)), SHR(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),16)), SHR(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),16))
/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR32((b),16)), SHR32(MULT16_16SU((a),((b)&0x0000ffff)),16))
@@ -50,7 +51,9 @@ extern opus_int64 celt_mips;
#define MULT16_32_P16(a,b) MULT16_32_PX(a,b,16)
#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val64)1)<<(bits))))
#define GCONST2(x,bits) ((celt_glog)(.5+(x)*(((celt_glog)1)<<(bits))))
#define GCONST(x) GCONST2((x),DB_SHIFT)
#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)

View File

@@ -71,11 +71,24 @@
#define MULT32_32_Q31(a,b) ADD32(ADD32(SHL(MULT16_16(SHR((a),16),SHR((b),16)),1), SHR(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),15)), SHR(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),15))
#endif
/** 32x32 multiplication, followed by a 32-bit shift right. Results fits in 32 bits */
#if OPUS_FAST_INT64
#define MULT32_32_Q32(a,b) ((opus_val32)SHR((opus_int64)(a)*(opus_int64)(b),32))
#else
#define MULT32_32_Q32(a,b) ADD32(ADD32(MULT16_16(SHR((a),16),SHR((b),16)), SHR(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),16)), SHR(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),16))
#endif
/** Compile-time conversion of float constant to 16-bit value */
#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
/** Compile-time conversion of float constant to 32-bit value */
#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_int64)1)<<(bits))))
/** Compile-time conversion of float constant to log gain value */
#define GCONST2(x,bits) ((celt_glog)(.5+(x)*(((celt_glog)1)<<(bits))))
/** Compile-time conversion of float constant to DB_SHFIT log gain value */
#define GCONST(x) GCONST2((x),DB_SHIFT)
/** Negate a 16-bit value */
#define NEG16(x) (-(x))

View File

@@ -41,6 +41,10 @@
#include "mathops.h"
#include "stack_alloc.h"
#ifndef M_PI
#define M_PI 3.141592653
#endif
/* The guts header contains all the multiplication and addition macros that are defined for
complex numbers. It also delares the kf_ internal functions.
*/
@@ -70,8 +74,8 @@ static void kf_bfly2(
} else
#endif
{
opus_val16 tw;
tw = QCONST16(0.7071067812f, 15);
celt_coef tw;
tw = QCONST32(0.7071067812f, COEF_SHIFT-1);
/* We know that m==4 here because the radix-2 is just after a radix-4 */
celt_assert(m==4);
for (i=0;i<N;i++)
@@ -192,7 +196,7 @@ static void kf_bfly3(
kiss_fft_cpx * Fout_beg = Fout;
#ifdef FIXED_POINT
/*epi3.r = -16384;*/ /* Unused */
epi3.i = -28378;
epi3.i = -QCONST32(0.86602540f, COEF_SHIFT-1);
#else
epi3 = st->twiddles[fstride*m];
#endif
@@ -249,10 +253,10 @@ static void kf_bfly5(
kiss_fft_cpx * Fout_beg = Fout;
#ifdef FIXED_POINT
ya.r = 10126;
ya.i = -31164;
yb.r = -26510;
yb.i = -19261;
ya.r = QCONST32(0.30901699f, COEF_SHIFT-1);
ya.i = -QCONST32(0.95105652f, COEF_SHIFT-1);
yb.r = -QCONST32(0.80901699f, COEF_SHIFT-1);
yb.i = -QCONST32(0.58778525f, COEF_SHIFT-1);
#else
ya = st->twiddles[fstride*m];
yb = st->twiddles[fstride*2*m];
@@ -412,7 +416,12 @@ static void compute_twiddles(kiss_twiddle_cpx *twiddles, int nfft)
#ifdef FIXED_POINT
for (i=0;i<nfft;++i) {
opus_val32 phase = -i;
#ifdef ENABLE_QEXT
twiddles[i].r = floor(.5+2147483647*cos((2*M_PI/nfft)*phase));
twiddles[i].i = floor(.5+2147483647*sin((2*M_PI/nfft)*phase));
#else
kf_cexp2(twiddles+i, DIV32(SHL32(phase,17),nfft));
#endif
}
#else
for (i=0;i<nfft;++i) {
@@ -454,10 +463,17 @@ kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem,
st->nfft=nfft;
#ifdef FIXED_POINT
st->scale_shift = celt_ilog2(st->nfft);
# ifdef ENABLE_QEXT
if (st->nfft == 1<<st->scale_shift)
st->scale = QCONST32(1.0f, 30);
else
st->scale = (((opus_int64)1073741824<<st->scale_shift)+st->nfft/2)/st->nfft;
# else
if (st->nfft == 1<<st->scale_shift)
st->scale = Q15ONE;
else
st->scale = (1073741824+st->nfft/2)/st->nfft>>(15-st->scale_shift);
# endif
#else
st->scale = 1.f/nfft;
#endif
@@ -569,7 +585,7 @@ void opus_fft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout)
void opus_fft_c(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
{
int i;
opus_val16 scale;
celt_coef scale;
#ifdef FIXED_POINT
/* Allows us to scale with MULT16_32_Q16(), which is faster than
MULT16_32_Q15() on ARM. */
@@ -582,8 +598,8 @@ void opus_fft_c(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *f
for (i=0;i<st->nfft;i++)
{
kiss_fft_cpx x = fin[i];
fout[st->bitrev[i]].r = SHR32(MULT16_32_Q16(scale, x.r), scale_shift);
fout[st->bitrev[i]].i = SHR32(MULT16_32_Q16(scale, x.i), scale_shift);
fout[st->bitrev[i]].r = SHR32(S_MUL2(x.r, scale), scale_shift);
fout[st->bitrev[i]].i = SHR32(S_MUL2(x.i, scale), scale_shift);
}
opus_fft_impl(st, fout);
}

View File

@@ -50,7 +50,13 @@ extern "C" {
#include "arch.h"
# define kiss_fft_scalar opus_int32
# define kiss_twiddle_scalar opus_int16
# ifdef ENABLE_QEXT
# define COEF_SHIFT 32
# else
# define COEF_SHIFT 16
# endif
# define kiss_twiddle_scalar celt_coef
/* Some 32-bit CPUs would load/store a kiss_twiddle_cpx with a single memory
* access, and could benefit from additional alignment.
@@ -58,6 +64,7 @@ extern "C" {
# define KISS_TWIDDLE_CPX_ALIGNMENT (sizeof(opus_int32))
#else
# ifndef kiss_fft_scalar
/* default is float */
# define kiss_fft_scalar float
@@ -95,7 +102,7 @@ typedef struct arch_fft_state{
typedef struct kiss_fft_state{
int nfft;
opus_val16 scale;
celt_coef scale;
#ifdef FIXED_POINT
int scale_shift;
#endif

View File

@@ -67,7 +67,7 @@ unsigned isqrt32(opus_uint32 _val){
#ifdef FIXED_POINT
opus_val32 frac_div32(opus_val32 a, opus_val32 b)
opus_val32 frac_div32_q29(opus_val32 a, opus_val32 b)
{
opus_val16 rcp;
opus_val32 result, rem;
@@ -79,6 +79,11 @@ opus_val32 frac_div32(opus_val32 a, opus_val32 b)
result = MULT16_32_Q15(rcp, a);
rem = PSHR32(a,2)-MULT32_32_Q31(result, b);
result = ADD32(result, SHL32(MULT16_32_Q15(rcp, rem),2));
return result;
}
opus_val32 frac_div32(opus_val32 a, opus_val32 b) {
opus_val32 result = frac_div32_q29(a,b);
if (result >= 536870912) /* 2^29 */
return 2147483647; /* 2^31 - 1 */
else if (result <= -536870912) /* -2^29 */
@@ -121,7 +126,10 @@ opus_val32 celt_sqrt(opus_val32 x)
int k;
opus_val16 n;
opus_val32 rt;
static const opus_val16 C[5] = {23175, 11561, -3011, 1699, -664};
/* These coeffs are optimized in fixed-point to minimize both RMS and max error
of sqrt(x) over .25<x<1 without exceeding 32767.
The RMS error is 3.4e-5 and the max is 8.2e-5. */
static const opus_val16 C[6] = {23171, 11574, -2901, 1592, -1002, 336};
if (x==0)
return 0;
else if (x>=1073741824)
@@ -129,8 +137,8 @@ opus_val32 celt_sqrt(opus_val32 x)
k = (celt_ilog2(x)>>1)-7;
x = VSHR32(x, 2*k);
n = x-32768;
rt = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2],
MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, (C[4])))))))));
rt = ADD32(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2],
MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, ADD16(C[4], MULT16_16_Q15(n, (C[5])))))))))));
rt = VSHR32(rt,7-k);
return rt;
}

View File

@@ -1,7 +1,7 @@
/* Copyright (c) 2002-2008 Jean-Marc Valin
Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
Written by Jean-Marc Valin, and Yunho Huh */
/**
@file mathops.h
@brief Various math functions
@@ -91,6 +91,26 @@ static OPUS_INLINE opus_val32 celt_maxabs16(const opus_val16 *x, int len)
}
#endif
#ifdef ENABLE_RES24
static OPUS_INLINE opus_res celt_maxabs_res(const opus_res *x, int len)
{
int i;
opus_res maxval = 0;
opus_res minval = 0;
for (i=0;i<len;i++)
{
maxval = MAX32(maxval, x[i]);
minval = MIN32(minval, x[i]);
}
/* opus_res should never reach such amplitude, so we should be safe. */
celt_sig_assert(minval != -2147483648);
return MAX32(maxval,-minval);
}
#else
#define celt_maxabs_res celt_maxabs16
#endif
#ifndef OVERRIDE_CELT_MAXABS32
#ifdef FIXED_POINT
static OPUS_INLINE opus_val32 celt_maxabs32(const opus_val32 *x, int len)
@@ -120,17 +140,48 @@ static OPUS_INLINE opus_val32 celt_maxabs32(const opus_val32 *x, int len)
#define celt_rcp(x) (1.f/(x))
#define celt_div(a,b) ((a)/(b))
#define frac_div32(a,b) ((float)(a)/(b))
#define frac_div32_q29(a,b) frac_div32(a,b)
#ifdef FLOAT_APPROX
/* Calculates the base-2 logarithm (log2(x)) of a number. It is designed for
* systems using radix-2 floating-point representation, with the exponent
* located at bits 23 to 30 and an offset of 127. Note that special cases like
* denormalized numbers, positive/negative infinity, and NaN are not handled.
* log2(x) = log2(x^exponent * mantissa)
* = exponent + log2(mantissa) */
/* Note: This assumes radix-2 floating point with the exponent at bits 23..30 and an offset of 127
denorm, +/- inf and NaN are *not* handled */
/* Log2 x normalization single precision coefficients calculated by
* 1 / (1 + 0.125 * index).
* Coefficients in Double Precision
* double log2_x_norm_coeff[8] = {
* 1.0000000000000000000, 8.888888888888888e-01,
* 8.000000000000000e-01, 7.272727272727273e-01,
* 6.666666666666666e-01, 6.153846153846154e-01,
* 5.714285714285714e-01, 5.333333333333333e-01} */
static const float log2_x_norm_coeff[8] = {
1.000000000000000000000000000f, 8.88888895511627197265625e-01f,
8.00000000000000000000000e-01f, 7.27272748947143554687500e-01f,
6.66666686534881591796875e-01f, 6.15384638309478759765625e-01f,
5.71428596973419189453125e-01f, 5.33333361148834228515625e-01f};
/* Log2 y normalization single precision coefficients calculated by
* log2(1 + 0.125 * index).
* Coefficients in Double Precision
* double log2_y_norm_coeff[8] = {
* 0.0000000000000000000, 1.699250014423124e-01,
* 3.219280948873623e-01, 4.594316186372973e-01,
* 5.849625007211562e-01, 7.004397181410922e-01,
* 8.073549220576041e-01, 9.068905956085185e-01}; */
static const float log2_y_norm_coeff[8] = {
0.0000000000000000000000000000f, 1.699250042438507080078125e-01f,
3.219280838966369628906250e-01f, 4.594316184520721435546875e-01f,
5.849624872207641601562500e-01f, 7.004396915435791015625000e-01f,
8.073549270629882812500000e-01f, 9.068905711174011230468750e-01f};
/** Base-2 log approximation (log2(x)). */
static OPUS_INLINE float celt_log2(float x)
{
int integer;
float frac;
opus_int32 range_idx;
union {
float f;
opus_uint32 i;
@@ -138,13 +189,36 @@ static OPUS_INLINE float celt_log2(float x)
in.f = x;
integer = (in.i>>23)-127;
in.i -= (opus_uint32)integer<<23;
frac = in.f - 1.5f;
frac = -0.41445418f + frac*(0.95909232f
+ frac*(-0.33951290f + frac*0.16541097f));
return 1+integer+frac;
/* Normalize the mantissa range from [1, 2] to [1,1.125], and then shift x
* by 1.0625 to [-0.0625, 0.0625]. */
range_idx = (in.i >> 20) & 0x7;
in.f = in.f * log2_x_norm_coeff[range_idx] - 1.0625f;
/* Polynomial coefficients approximated in the [1, 1.125] range.
* Lolremez command: lolremez --degree 4 --range -0.0625:0.0625
* "log(x+1.0625)/log(2)"
* Coefficients in Double Precision
* A0: 8.7462840624502679e-2 A1: 1.3578296070972002
* A2: -6.3897703690210047e-1 A3: 4.0197125617419959e-1
* A4: -2.8415445877832832e-1 */
#define LOG2_COEFF_A0 8.74628424644470214843750000e-02f
#define LOG2_COEFF_A1 1.357829570770263671875000000000f
#define LOG2_COEFF_A2 -6.3897705078125000000000000e-01f
#define LOG2_COEFF_A3 4.01971250772476196289062500e-01f
#define LOG2_COEFF_A4 -2.8415444493293762207031250e-01f
in.f = LOG2_COEFF_A0 + in.f * (LOG2_COEFF_A1
+ in.f * (LOG2_COEFF_A2
+ in.f * (LOG2_COEFF_A3
+ in.f * (LOG2_COEFF_A4))));
return integer + in.f + log2_y_norm_coeff[range_idx];
}
/** Base-2 exponential approximation (2^x). */
/* Calculates an approximation of 2^x. The approximation was achieved by
* employing a base-2 exponential function and utilizing a Remez approximation
* of order 5, ensuring a controlled relative error.
* exp2(x) = exp2(integer + fraction)
* = exp2(integer) * exp2(fraction) */
static OPUS_INLINE float celt_exp2(float x)
{
int integer;
@@ -157,9 +231,22 @@ static OPUS_INLINE float celt_exp2(float x)
if (integer < -50)
return 0;
frac = x-integer;
/* K0 = 1, K1 = log(2), K2 = 3-4*log(2), K3 = 3*log(2) - 2 */
res.f = 0.99992522f + frac * (0.69583354f
+ frac * (0.22606716f + 0.078024523f*frac));
/* Polynomial coefficients approximated in the [0, 1] range.
* Lolremez command: lolremez --degree 5 --range 0:1
* "exp(x*0.693147180559945)" "exp(x*0.693147180559945)"
* NOTE: log(2) ~ 0.693147180559945 */
#define EXP2_COEFF_A0 9.999999403953552246093750000000e-01f
#define EXP2_COEFF_A1 6.931530833244323730468750000000e-01f
#define EXP2_COEFF_A2 2.401536107063293457031250000000e-01f
#define EXP2_COEFF_A3 5.582631751894950866699218750000e-02f
#define EXP2_COEFF_A4 8.989339694380760192871093750000e-03f
#define EXP2_COEFF_A5 1.877576694823801517486572265625e-03f
res.f = EXP2_COEFF_A0 + frac * (EXP2_COEFF_A1
+ frac * (EXP2_COEFF_A2
+ frac * (EXP2_COEFF_A3
+ frac * (EXP2_COEFF_A4
+ frac * (EXP2_COEFF_A5)))));
res.i = (res.i + ((opus_uint32)integer<<23)) & 0x7fffffff;
return res.f;
}
@@ -169,6 +256,9 @@ static OPUS_INLINE float celt_exp2(float x)
#define celt_exp2(x) ((float)exp(0.6931471805599453094*(x)))
#endif
#define celt_exp2_db celt_exp2
#define celt_log2_db celt_log2
#endif
#ifdef FIXED_POINT
@@ -204,13 +294,13 @@ static OPUS_INLINE opus_val16 celt_log2(opus_val32 x)
opus_val16 n, frac;
/* -0.41509302963303146, 0.9609890551383969, -0.31836011537636605,
0.15530808010959576, -0.08556153059057618 */
static const opus_val16 C[5] = {-6801+(1<<(13-DB_SHIFT)), 15746, -5217, 2545, -1401};
static const opus_val16 C[5] = {-6801+(1<<(13-10)), 15746, -5217, 2545, -1401};
if (x==0)
return -32767;
i = celt_ilog2(x);
n = VSHR32(x,i-15)-32768-16384;
frac = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2], MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, C[4]))))))));
return SHL16(i-13,DB_SHIFT)+SHR16(frac,14-DB_SHIFT);
return SHL32(i-13,10)+SHR32(frac,14-10);
}
/*
@@ -250,10 +340,103 @@ static OPUS_INLINE opus_val32 celt_exp2(opus_val16 x)
return VSHR32(EXTEND32(frac), -integer-2);
}
#ifdef ENABLE_QEXT
/* Calculates the base-2 logarithm of a Q14 input value. The result is returned
* in Q(DB_SHIFT). If the input value is 0, the function will output -32.0f. */
static OPUS_INLINE opus_val32 celt_log2_db(opus_val32 x) {
/* Q30 */
static const opus_val32 log2_x_norm_coeff[8] = {
1073741824, 954437184, 858993472, 780903168,
715827904, 660764224, 613566784, 572662336};
/* Q24 */
static const opus_val32 log2_y_norm_coeff[8] = {
0, 2850868, 5401057, 7707983,
9814042, 11751428, 13545168, 15215099};
static const opus_val32 LOG2_COEFF_A0 = 1467383; /* Q24 */
static const opus_val32 LOG2_COEFF_A1 = 182244800; /* Q27 */
static const opus_val32 LOG2_COEFF_A2 = -21440512; /* Q25 */
static const opus_val32 LOG2_COEFF_A3 = 107903336; /* Q28 */
static const opus_val32 LOG2_COEFF_A4 = -610217024; /* Q31 */
opus_int32 integer, norm_coeff_idx, tmp;
opus_val32 mantissa;
if (x==0) {
return -536870912; /* -32.0f */
}
integer = SUB32(celt_ilog2(x), 14); /* Q0 */
mantissa = VSHR32(x, integer + 14 - 29); /* Q29 */
norm_coeff_idx = SHR32(mantissa, 29 - 3) & 0x7;
/* mantissa is in Q28 (29 + Q_NORM_CONST - 31 where Q_NORM_CONST is Q30)
* 285212672 (Q28) is 1.0625f. */
mantissa = SUB32(MULT32_32_Q31(mantissa, log2_x_norm_coeff[norm_coeff_idx]),
285212672);
/* q_a3(Q28): q_mantissa + q_a4 - 31
* q_a2(Q25): q_mantissa + q_a3 - 31
* q_a1(Q27): q_mantissa + q_a2 - 31 + 5
* q_a0(Q24): q_mantissa + q_a1 - 31
* where q_mantissa is Q28 */
/* Split evaluation in steps to avoid exploding macro expansion. */
tmp = MULT32_32_Q31(mantissa, LOG2_COEFF_A4);
tmp = MULT32_32_Q31(mantissa, ADD32(LOG2_COEFF_A3, tmp));
tmp = SHL32(MULT32_32_Q31(mantissa, ADD32(LOG2_COEFF_A2, tmp)), 5 /* SHL32 for LOG2_COEFF_A1 */);
tmp = MULT32_32_Q31(mantissa, ADD32(LOG2_COEFF_A1, tmp));
return ADD32(log2_y_norm_coeff[norm_coeff_idx],
ADD32(SHL32(integer, DB_SHIFT),
ADD32(LOG2_COEFF_A0, tmp)));
}
/* Calculates exp2 for Q28 within a specific range (0 to 1.0) using fixed-point
* arithmetic. The input number must be adjusted for Q DB_SHIFT. */
static OPUS_INLINE opus_val32 celt_exp2_db_frac(opus_val32 x)
{
/* Approximation constants. */
static const opus_int32 EXP2_COEFF_A0 = 268435440; /* Q28 */
static const opus_int32 EXP2_COEFF_A1 = 744267456; /* Q30 */
static const opus_int32 EXP2_COEFF_A2 = 1031451904; /* Q32 */
static const opus_int32 EXP2_COEFF_A3 = 959088832; /* Q34 */
static const opus_int32 EXP2_COEFF_A4 = 617742720; /* Q36 */
static const opus_int32 EXP2_COEFF_A5 = 516104352; /* Q38 */
opus_int32 tmp;
/* Converts input value from Q24 to Q29. */
opus_val32 x_q29 = SHL32(x, 29 - 24);
/* Split evaluation in steps to avoid exploding macro expansion. */
tmp = ADD32(EXP2_COEFF_A4, MULT32_32_Q31(x_q29, EXP2_COEFF_A5));
tmp = ADD32(EXP2_COEFF_A3, MULT32_32_Q31(x_q29, tmp));
tmp = ADD32(EXP2_COEFF_A2, MULT32_32_Q31(x_q29, tmp));
tmp = ADD32(EXP2_COEFF_A1, MULT32_32_Q31(x_q29, tmp));
return ADD32(EXP2_COEFF_A0, MULT32_32_Q31(x_q29, tmp));
}
/* Calculates exp2 for Q16 using fixed-point arithmetic. The input number must
* be adjusted for Q DB_SHIFT. */
static OPUS_INLINE opus_val32 celt_exp2_db(opus_val32 x)
{
int integer;
opus_val32 frac;
integer = SHR32(x,DB_SHIFT);
if (integer>14)
return 0x7f000000;
else if (integer <= -17)
return 0;
frac = celt_exp2_db_frac(x-SHL32(integer, DB_SHIFT)); /* Q28 */
return VSHR32(frac, -integer + 28 - 16); /* Q16 */
}
#else
#define celt_log2_db(x) SHL32(EXTEND32(celt_log2(x)), DB_SHIFT-10)
#define celt_exp2_db_frac(x) SHL32(celt_exp2_frac(PSHR32(x, DB_SHIFT-10)), 14)
#define celt_exp2_db(x) celt_exp2(PSHR32(x, DB_SHIFT-10))
#endif
opus_val32 celt_rcp(opus_val32 x);
#define celt_div(a,b) MULT32_32_Q31((opus_val32)(a),celt_rcp(b))
opus_val32 frac_div32_q29(opus_val32 a, opus_val32 b);
opus_val32 frac_div32(opus_val32 a, opus_val32 b);
#define M1 32767

View File

@@ -57,6 +57,9 @@
#include "mips/mdct_mipsr1.h"
#endif
#ifndef M_PI
#define M_PI 3.141592653
#endif
#ifdef CUSTOM_MODES
@@ -86,12 +89,12 @@ int clt_mdct_init(mdct_lookup *l,int N, int maxshift, int arch)
{
/* We have enough points that sine isn't necessary */
#if defined(FIXED_POINT)
#if 1
#ifndef ENABLE_QEXT
for (i=0;i<N2;i++)
trig[i] = TRIG_UPSCALE*celt_cos_norm(DIV32(ADD32(SHL32(EXTEND32(i),17),N2+16384),N));
#else
for (i=0;i<N2;i++)
trig[i] = (kiss_twiddle_scalar)MAX32(-32767,MIN32(32767,floor(.5+32768*cos(2*M_PI*(i+.125)/N))));
trig[i] = (kiss_twiddle_scalar)MAX32(-2147483647,MIN32(2147483647,floor(.5+2147483648*cos(2*M_PI*(i+.125)/N))));
#endif
#else
for (i=0;i<N2;i++)
@@ -117,7 +120,7 @@ void clt_mdct_clear(mdct_lookup *l, int arch)
/* Forward MDCT trashes the input array */
#ifndef OVERRIDE_clt_mdct_forward
void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
const opus_val16 *window, int overlap, int shift, int stride, int arch)
const celt_coef *window, int overlap, int shift, int stride, int arch)
{
int i;
int N, N2, N4;
@@ -125,11 +128,12 @@ void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scal
VARDECL(kiss_fft_cpx, f2);
const kiss_fft_state *st = l->kfft[shift];
const kiss_twiddle_scalar *trig;
opus_val16 scale;
celt_coef scale;
#ifdef FIXED_POINT
/* Allows us to scale with MULT16_32_Q16(), which is faster than
MULT16_32_Q15() on ARM. */
int scale_shift = st->scale_shift-1;
int headroom;
#endif
SAVE_STACK;
(void)arch;
@@ -155,13 +159,13 @@ void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scal
const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);
const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);
kiss_fft_scalar * OPUS_RESTRICT yp = f;
const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1);
const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
const celt_coef * OPUS_RESTRICT wp1 = window+(overlap>>1);
const celt_coef * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
for(i=0;i<((overlap+3)>>2);i++)
{
/* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
*yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2);
*yp++ = MULT16_32_Q15(*wp1, *xp1) - MULT16_32_Q15(*wp2, xp2[-N2]);
*yp++ = S_MUL(xp1[N2], *wp2) + S_MUL(*xp2, *wp1);
*yp++ = S_MUL(*xp1, *wp1) - S_MUL(xp2[-N2], *wp2);
xp1+=2;
xp2-=2;
wp1+=2;
@@ -180,8 +184,8 @@ void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scal
for(;i<N4;i++)
{
/* Real part arranged as a-bR, Imag part arranged as -c-dR */
*yp++ = -MULT16_32_Q15(*wp1, xp1[-N2]) + MULT16_32_Q15(*wp2, *xp2);
*yp++ = MULT16_32_Q15(*wp2, *xp1) + MULT16_32_Q15(*wp1, xp2[N2]);
*yp++ = -S_MUL(xp1[-N2], *wp1) + S_MUL(*xp2, *wp2);
*yp++ = S_MUL(*xp1, *wp2) + S_MUL(xp2[N2], *wp1);
xp1+=2;
xp2-=2;
wp1+=2;
@@ -192,6 +196,9 @@ void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scal
{
kiss_fft_scalar * OPUS_RESTRICT yp = f;
const kiss_twiddle_scalar *t = &trig[0];
#ifdef FIXED_POINT
opus_val32 maxval=1;
#endif
for(i=0;i<N4;i++)
{
kiss_fft_cpx yc;
@@ -205,10 +212,21 @@ void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scal
yi = S_MUL(im,t0) + S_MUL(re,t1);
yc.r = yr;
yc.i = yi;
yc.r = PSHR32(MULT16_32_Q16(scale, yc.r), scale_shift);
yc.i = PSHR32(MULT16_32_Q16(scale, yc.i), scale_shift);
yc.r = S_MUL2(yc.r, scale);
yc.i = S_MUL2(yc.i, scale);
#ifdef FIXED_POINT
maxval = MAX32(maxval, MAX32(yc.r, yc.i));
#endif
f2[st->bitrev[i]] = yc;
}
#ifdef FIXED_POINT
headroom = IMAX(0, IMIN(scale_shift-1, 28-celt_ilog2(maxval)));
for(i=0;i<N4;i++)
{
f2[i].r = PSHR32(f2[i].r, scale_shift-headroom);
f2[i].i = PSHR32(f2[i].i, scale_shift-headroom);
}
#endif
}
/* N/4 complex FFT, does not downscale anymore */
@@ -225,8 +243,8 @@ void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scal
for(i=0;i<N4;i++)
{
kiss_fft_scalar yr, yi;
yr = S_MUL(fp->i,t[N4+i]) - S_MUL(fp->r,t[i]);
yi = S_MUL(fp->r,t[N4+i]) + S_MUL(fp->i,t[i]);
yr = PSHR32(S_MUL(fp->i,t[N4+i]) - S_MUL(fp->r,t[i]), headroom);
yi = PSHR32(S_MUL(fp->r,t[N4+i]) + S_MUL(fp->i,t[i]), headroom);
*yp1 = yr;
*yp2 = yi;
fp++;
@@ -240,7 +258,7 @@ void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scal
#ifndef OVERRIDE_clt_mdct_backward
void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride, int arch)
const celt_coef * OPUS_RESTRICT window, int overlap, int shift, int stride, int arch)
{
int i;
int N, N2, N4;
@@ -269,9 +287,12 @@ void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_sca
{
int rev;
kiss_fft_scalar yr, yi;
opus_val32 x1, x2;
rev = *bitrev++;
yr = ADD32_ovflw(S_MUL(*xp2, t[i]), S_MUL(*xp1, t[N4+i]));
yi = SUB32_ovflw(S_MUL(*xp1, t[i]), S_MUL(*xp2, t[N4+i]));
x1 = SHL32(*xp1, IMDCT_HEADROOM);
x2 = SHL32(*xp2, IMDCT_HEADROOM);
yr = ADD32_ovflw(S_MUL(x2, t[i]), S_MUL(x1, t[N4+i]));
yi = SUB32_ovflw(S_MUL(x1, t[i]), S_MUL(x2, t[N4+i]));
/* We swap real and imag because we use an FFT instead of an IFFT. */
yp[2*rev+1] = yr;
yp[2*rev] = yi;
@@ -301,8 +322,8 @@ void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_sca
t0 = t[i];
t1 = t[N4+i];
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
yr = ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1));
yi = SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0));
yr = PSHR32(ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1)), IMDCT_HEADROOM);
yi = PSHR32(SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0)), IMDCT_HEADROOM);
/* We swap real and imag because we're using an FFT instead of an IFFT. */
re = yp1[1];
im = yp1[0];
@@ -312,8 +333,8 @@ void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_sca
t0 = t[(N4-i-1)];
t1 = t[(N2-i-1)];
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
yr = ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1));
yi = SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0));
yr = PSHR32(ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1)), IMDCT_HEADROOM);
yi = PSHR32(SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0)), IMDCT_HEADROOM);
yp1[0] = yr;
yp0[1] = yi;
yp0 += 2;
@@ -325,16 +346,16 @@ void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_sca
{
kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1;
kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
const opus_val16 * OPUS_RESTRICT wp1 = window;
const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;
const celt_coef * OPUS_RESTRICT wp1 = window;
const celt_coef * OPUS_RESTRICT wp2 = window+overlap-1;
for(i = 0; i < overlap/2; i++)
{
kiss_fft_scalar x1, x2;
x1 = *xp1;
x2 = *yp1;
*yp1++ = SUB32_ovflw(MULT16_32_Q15(*wp2, x2), MULT16_32_Q15(*wp1, x1));
*xp1-- = ADD32_ovflw(MULT16_32_Q15(*wp1, x2), MULT16_32_Q15(*wp2, x1));
*yp1++ = SUB32_ovflw(S_MUL(x2, *wp2), S_MUL(x1, *wp1));
*xp1-- = ADD32_ovflw(S_MUL(x2, *wp1), S_MUL(x1, *wp2));
wp1++;
wp2--;
}

View File

@@ -57,6 +57,9 @@ typedef struct {
#include "arm/mdct_arm.h"
#endif
/* There should be 2 bits of headroom in the IMDCT which we can take
advantage of to maximize accuracy. */
#define IMDCT_HEADROOM 2
int clt_mdct_init(mdct_lookup *l,int N, int maxshift, int arch);
void clt_mdct_clear(mdct_lookup *l, int arch);
@@ -64,14 +67,14 @@ void clt_mdct_clear(mdct_lookup *l, int arch);
/** Compute a forward MDCT and scale by 4/N, trashes the input array */
void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in,
kiss_fft_scalar * OPUS_RESTRICT out,
const opus_val16 *window, int overlap,
const celt_coef *window, int overlap,
int shift, int stride, int arch);
/** Compute a backward MDCT (no scaling) and performs weighted overlap-add
(scales implicitly by 1/2) */
void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in,
kiss_fft_scalar * OPUS_RESTRICT out,
const opus_val16 * OPUS_RESTRICT window,
const celt_coef * OPUS_RESTRICT window,
int overlap, int shift, int stride, int arch);
#if !defined(OVERRIDE_OPUS_MDCT)
@@ -80,7 +83,7 @@ void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in,
extern void (*const CLT_MDCT_FORWARD_IMPL[OPUS_ARCHMASK+1])(
const mdct_lookup *l, kiss_fft_scalar *in,
kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window,
kiss_fft_scalar * OPUS_RESTRICT out, const celt_coef *window,
int overlap, int shift, int stride, int arch);
#define clt_mdct_forward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \
@@ -90,7 +93,7 @@ extern void (*const CLT_MDCT_FORWARD_IMPL[OPUS_ARCHMASK+1])(
extern void (*const CLT_MDCT_BACKWARD_IMPL[OPUS_ARCHMASK+1])(
const mdct_lookup *l, kiss_fft_scalar *in,
kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window,
kiss_fft_scalar * OPUS_RESTRICT out, const celt_coef *window,
int overlap, int shift, int stride, int arch);
#define clt_mdct_backward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \

View File

@@ -230,7 +230,7 @@ CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error)
#ifdef CUSTOM_MODES
CELTMode *mode=NULL;
int res;
opus_val16 *window;
celt_coef *window;
opus_int16 *logN;
int LM;
int arch = opus_select_arch();
@@ -370,16 +370,21 @@ CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error)
if (mode->allocVectors==NULL)
goto failure;
window = (opus_val16*)opus_alloc(mode->overlap*sizeof(opus_val16));
window = (celt_coef*)opus_alloc(mode->overlap*sizeof(*window));
if (window==NULL)
goto failure;
#ifndef FIXED_POINT
for (i=0;i<mode->overlap;i++)
window[i] = Q15ONE*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap));
#else
# ifdef ENABLE_QEXT
for (i=0;i<mode->overlap;i++)
window[i] = 2147483647*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap));
# else
for (i=0;i<mode->overlap;i++)
window[i] = MIN32(32767,floor(.5+32768.*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap))));
# endif
#endif
mode->window = window;

View File

@@ -66,7 +66,7 @@ struct OpusCustomMode {
const unsigned char *allocVectors; /**< Number of bits in each band for several rates */
const opus_int16 *logN;
const opus_val16 *window;
const celt_coef *window;
mdct_lookup mdct;
PulseCache cache;
};

View File

@@ -436,7 +436,7 @@ static opus_val16 compute_pitch_gain(opus_val32 xy, opus_val32 xx, opus_val32 yy
den = celt_rsqrt_norm(x2y2);
g = MULT16_32_Q15(den, xy);
g = VSHR32(g, (shift>>1)-1);
return EXTRACT16(MIN32(g, Q15ONE));
return EXTRACT16(MAX32(-Q15ONE, MIN32(g, Q15ONE)));
}
#else
static opus_val16 compute_pitch_gain(opus_val32 xy, opus_val32 xx, opus_val32 yy)

View File

@@ -139,25 +139,25 @@ static const unsigned char e_prob_model[4][2][42] = {
static const unsigned char small_energy_icdf[3]={2,1,0};
static opus_val32 loss_distortion(const opus_val16 *eBands, opus_val16 *oldEBands, int start, int end, int len, int C)
static opus_val32 loss_distortion(const celt_glog *eBands, celt_glog *oldEBands, int start, int end, int len, int C)
{
int c, i;
opus_val32 dist = 0;
c=0; do {
for (i=start;i<end;i++)
{
opus_val16 d = SUB16(SHR16(eBands[i+c*len], 3), SHR16(oldEBands[i+c*len], 3));
celt_glog d = PSHR32(SUB32(eBands[i+c*len], oldEBands[i+c*len]), DB_SHIFT-7);
dist = MAC16_16(dist, d,d);
}
} while (++c<C);
return MIN32(200,SHR32(dist,2*DB_SHIFT-6));
return MIN32(200,SHR32(dist,14));
}
static int quant_coarse_energy_impl(const CELTMode *m, int start, int end,
const opus_val16 *eBands, opus_val16 *oldEBands,
const celt_glog *eBands, celt_glog *oldEBands,
opus_int32 budget, opus_int32 tell,
const unsigned char *prob_model, opus_val16 *error, ec_enc *enc,
int C, int LM, int intra, opus_val16 max_decay, int lfe)
const unsigned char *prob_model, celt_glog *error, ec_enc *enc,
int C, int LM, int intra, celt_glog max_decay, int lfe)
{
int i, c;
int badness = 0;
@@ -184,29 +184,28 @@ static int quant_coarse_energy_impl(const CELTMode *m, int start, int end,
int bits_left;
int qi, qi0;
opus_val32 q;
opus_val16 x;
celt_glog x;
opus_val32 f, tmp;
opus_val16 oldE;
opus_val16 decay_bound;
celt_glog oldE;
celt_glog decay_bound;
x = eBands[i+c*m->nbEBands];
oldE = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]);
oldE = MAXG(-GCONST(9.f), oldEBands[i+c*m->nbEBands]);
#ifdef FIXED_POINT
f = SHL32(EXTEND32(x),7) - PSHR32(MULT16_16(coef,oldE), 8) - prev[c];
f = x - MULT16_32_Q15(coef,oldE) - prev[c];
/* Rounding to nearest integer here is really important! */
qi = (f+QCONST32(.5f,DB_SHIFT+7))>>(DB_SHIFT+7);
decay_bound = EXTRACT16(MAX32(-QCONST16(28.f,DB_SHIFT),
SUB32((opus_val32)oldEBands[i+c*m->nbEBands],max_decay)));
qi = (f+QCONST32(.5f,DB_SHIFT))>>DB_SHIFT;
decay_bound = MAXG(-GCONST(28.f), SUB32((opus_val32)oldEBands[i+c*m->nbEBands],max_decay));
#else
f = x-coef*oldE-prev[c];
/* Rounding to nearest integer here is really important! */
qi = (int)floor(.5f+f);
decay_bound = MAX16(-QCONST16(28.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]) - max_decay;
decay_bound = MAXG(-GCONST(28.f), oldEBands[i+c*m->nbEBands]) - max_decay;
#endif
/* Prevent the energy from going down too quickly (e.g. for bands
that have just one bin) */
if (qi < 0 && x < decay_bound)
{
qi += (int)SHR16(SUB16(decay_bound,x), DB_SHIFT);
qi += (int)SHR32(SUB32(decay_bound,x), DB_SHIFT);
if (qi > 0)
qi = 0;
}
@@ -243,30 +242,30 @@ static int quant_coarse_energy_impl(const CELTMode *m, int start, int end,
}
else
qi = -1;
error[i+c*m->nbEBands] = PSHR32(f,7) - SHL16(qi,DB_SHIFT);
error[i+c*m->nbEBands] = f - SHL32(qi,DB_SHIFT);
badness += abs(qi0-qi);
q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT);
tmp = PSHR32(MULT16_16(coef,oldE),8) + prev[c] + SHL32(q,7);
tmp = MULT16_32_Q15(coef,oldE) + prev[c] + q;
#ifdef FIXED_POINT
tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp);
tmp = MAX32(-GCONST(28.f), tmp);
#endif
oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7);
prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8));
oldEBands[i+c*m->nbEBands] = tmp;
prev[c] = prev[c] + q - MULT16_32_Q15(beta,q);
} while (++c < C);
}
return lfe ? 0 : badness;
}
void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget,
opus_val16 *error, ec_enc *enc, int C, int LM, int nbAvailableBytes,
const celt_glog *eBands, celt_glog *oldEBands, opus_uint32 budget,
celt_glog *error, ec_enc *enc, int C, int LM, int nbAvailableBytes,
int force_intra, opus_val32 *delayedIntra, int two_pass, int loss_rate, int lfe)
{
int intra;
opus_val16 max_decay;
VARDECL(opus_val16, oldEBands_intra);
VARDECL(opus_val16, error_intra);
celt_glog max_decay;
VARDECL(celt_glog, oldEBands_intra);
VARDECL(celt_glog, error_intra);
ec_enc enc_start_state;
opus_uint32 tell;
int badness1=0;
@@ -282,21 +281,21 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
if (tell+3 > budget)
two_pass = intra = 0;
max_decay = QCONST16(16.f,DB_SHIFT);
max_decay = GCONST(16.f);
if (end-start>10)
{
#ifdef FIXED_POINT
max_decay = MIN32(max_decay, SHL32(EXTEND32(nbAvailableBytes),DB_SHIFT-3));
max_decay = SHL32(MIN32(SHR32(max_decay,DB_SHIFT-3), EXTEND32(nbAvailableBytes)),DB_SHIFT-3);
#else
max_decay = MIN32(max_decay, .125f*nbAvailableBytes);
#endif
}
if (lfe)
max_decay = QCONST16(3.f,DB_SHIFT);
max_decay = GCONST(3.f);
enc_start_state = *enc;
ALLOC(oldEBands_intra, C*m->nbEBands, opus_val16);
ALLOC(error_intra, C*m->nbEBands, opus_val16);
ALLOC(oldEBands_intra, C*m->nbEBands, celt_glog);
ALLOC(error_intra, C*m->nbEBands, celt_glog);
OPUS_COPY(oldEBands_intra, oldEBands, C*m->nbEBands);
if (two_pass || intra)
@@ -358,7 +357,7 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
RESTORE_STACK;
}
void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C)
void quant_fine_energy(const CELTMode *m, int start, int end, celt_glog *oldEBands, celt_glog *error, int *fine_quant, ec_enc *enc, int C)
{
int i, c;
@@ -371,10 +370,10 @@ void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBa
c=0;
do {
int q2;
opus_val16 offset;
celt_glog offset;
#ifdef FIXED_POINT
/* Has to be without rounding */
q2 = (error[i+c*m->nbEBands]+QCONST16(.5f,DB_SHIFT))>>(DB_SHIFT-fine_quant[i]);
q2 = (error[i+c*m->nbEBands]+GCONST(.5f))>>(DB_SHIFT-fine_quant[i]);
#else
q2 = (int)floor((error[i+c*m->nbEBands]+.5f)*frac);
#endif
@@ -384,7 +383,7 @@ void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBa
q2 = 0;
ec_enc_bits(enc, q2, fine_quant[i]);
#ifdef FIXED_POINT
offset = SUB16(SHR32(SHL32(EXTEND32(q2),DB_SHIFT)+QCONST16(.5f,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT));
offset = SUB32(VSHR32(2*q2+1, fine_quant[i]-DB_SHIFT+1), GCONST(.5f));
#else
offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
#endif
@@ -395,7 +394,7 @@ void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBa
}
}
void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C)
void quant_energy_finalise(const CELTMode *m, int start, int end, celt_glog *oldEBands, celt_glog *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C)
{
int i, prio, c;
@@ -409,11 +408,11 @@ void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *ol
c=0;
do {
int q2;
opus_val16 offset;
celt_glog offset;
q2 = error[i+c*m->nbEBands]<0 ? 0 : 1;
ec_enc_bits(enc, q2, 1);
#ifdef FIXED_POINT
offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1);
offset = SHR32(SHL32(q2,DB_SHIFT)-GCONST(.5f),fine_quant[i]+1);
#else
offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
#endif
@@ -425,7 +424,7 @@ void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *ol
}
}
void unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int intra, ec_dec *dec, int C, int LM)
void unquant_coarse_energy(const CELTMode *m, int start, int end, celt_glog *oldEBands, int intra, ec_dec *dec, int C, int LM)
{
const unsigned char *prob_model = e_prob_model[LM][intra];
int i, c;
@@ -479,18 +478,18 @@ void unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *ol
qi = -1;
q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT);
oldEBands[i+c*m->nbEBands] = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]);
tmp = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]),8) + prev[c] + SHL32(q,7);
oldEBands[i+c*m->nbEBands] = MAXG(-GCONST(9.f), oldEBands[i+c*m->nbEBands]);
tmp = MULT16_32_Q15(coef,oldEBands[i+c*m->nbEBands]) + prev[c] + q;
#ifdef FIXED_POINT
tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp);
tmp = MAX32(-GCONST(28.f), tmp);
#endif
oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7);
prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8));
oldEBands[i+c*m->nbEBands] = tmp;
prev[c] = prev[c] + q - MULT16_32_Q15(beta,q);
} while (++c < C);
}
}
void unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, ec_dec *dec, int C)
void unquant_fine_energy(const CELTMode *m, int start, int end, celt_glog *oldEBands, int *fine_quant, ec_dec *dec, int C)
{
int i, c;
/* Decode finer resolution */
@@ -501,10 +500,10 @@ void unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldE
c=0;
do {
int q2;
opus_val16 offset;
celt_glog offset;
q2 = ec_dec_bits(dec, fine_quant[i]);
#ifdef FIXED_POINT
offset = SUB16(SHR32(SHL32(EXTEND32(q2),DB_SHIFT)+QCONST16(.5f,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT));
offset = SUB32(VSHR32(2*q2+1, fine_quant[i]-DB_SHIFT+1), GCONST(.5f));
#else
offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
#endif
@@ -513,7 +512,7 @@ void unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldE
}
}
void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int C)
void unquant_energy_finalise(const CELTMode *m, int start, int end, celt_glog *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int C)
{
int i, prio, c;
@@ -527,10 +526,10 @@ void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *
c=0;
do {
int q2;
opus_val16 offset;
celt_glog offset;
q2 = ec_dec_bits(dec, 1);
#ifdef FIXED_POINT
offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1);
offset = SHR32(SHL32(q2,DB_SHIFT)-GCONST(.5f),fine_quant[i]+1);
#else
offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
#endif
@@ -542,7 +541,7 @@ void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *
}
void amp2Log2(const CELTMode *m, int effEnd, int end,
celt_ener *bandE, opus_val16 *bandLogE, int C)
celt_ener *bandE, celt_glog *bandLogE, int C)
{
int c, i;
c=0;
@@ -550,14 +549,14 @@ void amp2Log2(const CELTMode *m, int effEnd, int end,
for (i=0;i<effEnd;i++)
{
bandLogE[i+c*m->nbEBands] =
celt_log2(bandE[i+c*m->nbEBands])
- SHL16((opus_val16)eMeans[i],6);
celt_log2_db(bandE[i+c*m->nbEBands])
- SHL32((celt_glog)eMeans[i],DB_SHIFT-4);
#ifdef FIXED_POINT
/* Compensate for bandE[] being Q12 but celt_log2() taking a Q14 input. */
bandLogE[i+c*m->nbEBands] += QCONST16(2.f, DB_SHIFT);
bandLogE[i+c*m->nbEBands] += GCONST(2.f);
#endif
}
for (i=effEnd;i<end;i++)
bandLogE[c*m->nbEBands+i] = -QCONST16(14.f,DB_SHIFT);
bandLogE[c*m->nbEBands+i] = -GCONST(14.f);
} while (++c < C);
}

View File

@@ -42,25 +42,25 @@ extern const opus_val16 eMeans[25];
#endif
void amp2Log2(const CELTMode *m, int effEnd, int end,
celt_ener *bandE, opus_val16 *bandLogE, int C);
celt_ener *bandE, celt_glog *bandLogE, int C);
void log2Amp(const CELTMode *m, int start, int end,
celt_ener *eBands, const opus_val16 *oldEBands, int C);
celt_ener *eBands, const celt_glog *oldEBands, int C);
void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget,
opus_val16 *error, ec_enc *enc, int C, int LM,
const celt_glog *eBands, celt_glog *oldEBands, opus_uint32 budget,
celt_glog *error, ec_enc *enc, int C, int LM,
int nbAvailableBytes, int force_intra, opus_val32 *delayedIntra,
int two_pass, int loss_rate, int lfe);
void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C);
void quant_fine_energy(const CELTMode *m, int start, int end, celt_glog *oldEBands, celt_glog *error, int *fine_quant, ec_enc *enc, int C);
void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C);
void quant_energy_finalise(const CELTMode *m, int start, int end, celt_glog *oldEBands, celt_glog *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C);
void unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int intra, ec_dec *dec, int C, int LM);
void unquant_coarse_energy(const CELTMode *m, int start, int end, celt_glog *oldEBands, int intra, ec_dec *dec, int C, int LM);
void unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, ec_dec *dec, int C);
void unquant_fine_energy(const CELTMode *m, int start, int end, celt_glog *oldEBands, int *fine_quant, ec_dec *dec, int C);
void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int C);
void unquant_energy_finalise(const CELTMode *m, int start, int end, celt_glog *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int C);
#endif /* QUANT_BANDS */

View File

@@ -140,8 +140,9 @@ extern char *global_stack_top;
#else
#include "arch.h"
#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)/(sizeof(char))),(stack)+=(size)*(sizeof(type)/(sizeof(char))),(type*)((stack)-(size)*(sizeof(type)/(sizeof(char)))))
#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)/(sizeof(char))),(void)(((int)((size)*(sizeof(type)/(sizeof(char)))) <= (scratch_ptr)+GLOBAL_STACK_SIZE-(stack))?0:CELT_FATAL("pseudostack overflow")),(stack)+=(size)*(sizeof(type)/(sizeof(char))),(type*)((stack)-(size)*(sizeof(type)/(sizeof(char)))))
#if 0 /* Set this to 1 to instrument pseudostack usage */
#define RESTORE_STACK (printf("%ld %s:%d\n", global_stack-scratch_ptr, __FILE__, __LINE__),global_stack = _saved_stack)
#else

File diff suppressed because it is too large Load Diff

View File

@@ -119,7 +119,7 @@ void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread)
/** Takes the pitch vector and the decoded residual vector, computes the gain
that will give ||p+g*y||=1 and mixes the residual with the pitch. */
static void normalise_residual(int * OPUS_RESTRICT iy, celt_norm * OPUS_RESTRICT X,
int N, opus_val32 Ryy, opus_val16 gain)
int N, opus_val32 Ryy, opus_val32 gain)
{
int i;
#ifdef FIXED_POINT
@@ -132,7 +132,7 @@ static void normalise_residual(int * OPUS_RESTRICT iy, celt_norm * OPUS_RESTRICT
k = celt_ilog2(Ryy)>>1;
#endif
t = VSHR32(Ryy, 2*(k-7));
g = MULT16_16_P15(celt_rsqrt_norm(t),gain);
g = MULT32_32_Q31(celt_rsqrt_norm(t),gain);
i=0;
do
@@ -328,7 +328,7 @@ opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch)
}
unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc,
opus_val16 gain, int resynth, int arch)
opus_val32 gain, int resynth, int arch)
{
VARDECL(int, iy);
opus_val16 yy;
@@ -361,7 +361,7 @@ unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc,
/** Decode pulse vector and combine the result with the pitch vector to produce
the final normalised signal in the current band. */
unsigned alg_unquant(celt_norm *X, int N, int K, int spread, int B,
ec_dec *dec, opus_val16 gain)
ec_dec *dec, opus_val32 gain)
{
opus_val32 Ryy;
unsigned collapse_mask;
@@ -380,7 +380,7 @@ unsigned alg_unquant(celt_norm *X, int N, int K, int spread, int B,
}
#ifndef OVERRIDE_renormalise_vector
void renormalise_vector(celt_norm *X, int N, opus_val16 gain, int arch)
void renormalise_vector(celt_norm *X, int N, opus_val32 gain, int arch)
{
int i;
#ifdef FIXED_POINT
@@ -395,7 +395,7 @@ void renormalise_vector(celt_norm *X, int N, opus_val16 gain, int arch)
k = celt_ilog2(E)>>1;
#endif
t = VSHR32(E, 2*(k-7));
g = MULT16_16_P15(celt_rsqrt_norm(t),gain);
g = MULT32_32_Q31(celt_rsqrt_norm(t),gain);
xptr = X;
for (i=0;i<N;i++)

View File

@@ -60,7 +60,7 @@ opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch);
* @ret A mask indicating which blocks in the band received pulses
*/
unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc,
opus_val16 gain, int resynth, int arch);
opus_val32 gain, int resynth, int arch);
/** Algebraic pulse decoder
* @param X Decoded normalised spectrum (returned)
@@ -70,9 +70,9 @@ unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc,
* @ret A mask indicating which blocks in the band received pulses
*/
unsigned alg_unquant(celt_norm *X, int N, int K, int spread, int B,
ec_dec *dec, opus_val16 gain);
ec_dec *dec, opus_val32 gain);
void renormalise_vector(celt_norm *X, int N, opus_val16 gain, int arch);
void renormalise_vector(celt_norm *X, int N, opus_val32 gain, int arch);
int stereo_itheta(const celt_norm *X, const celt_norm *Y, int stereo, int N, int arch);

View File

@@ -268,6 +268,42 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode(
opus_int32 max_data_bytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
/** Encodes an Opus frame.
* @param [in] st <tt>OpusEncoder*</tt>: Encoder state
* @param [in] pcm <tt>opus_int32*</tt>: Input signal (interleaved if 2 channels) representing (or slightly exceeding) 24-bit values. length is frame_size*channels*sizeof(opus_int32)
* @param [in] frame_size <tt>int</tt>: Number of samples per channel in the
* input signal.
* This must be an Opus frame size for
* the encoder's sampling rate.
* For example, at 48 kHz the permitted
* values are 120, 240, 480, 960, 1920,
* and 2880.
* Passing in a duration of less than
* 10 ms (480 samples at 48 kHz) will
* prevent the encoder from using the LPC
* or hybrid modes.
* @param [out] data <tt>unsigned char*</tt>: Output payload.
* This must contain storage for at
* least \a max_data_bytes.
* @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
* memory for the output
* payload. This may be
* used to impose an upper limit on
* the instant bitrate, but should
* not be used as the only bitrate
* control. Use #OPUS_SET_BITRATE to
* control the bitrate.
* @returns The length of the encoded packet (in bytes) on success or a
* negative error code (see @ref opus_errorcodes) on failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode24(
OpusEncoder *st,
const opus_int32 *pcm,
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
/** Encodes an Opus frame from floating point input.
* @param [in] st <tt>OpusEncoder*</tt>: Encoder state
* @param [in] pcm <tt>float*</tt>: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0.
@@ -483,6 +519,31 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode(
int decode_fec
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Decode an Opus packet.
* @param [in] st <tt>OpusDecoder*</tt>: Decoder state
* @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
* @param [in] len <tt>opus_int32</tt>: Number of bytes in payload*
* @param [out] pcm <tt>opus_int32*</tt>: Output signal (interleaved if 2 channels) representing (or slightly exceeding) 24-bit values. length
* is frame_size*channels*sizeof(opus_int32)
* @param [in] frame_size Number of samples per channel of available space in \a pcm.
* If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will
* not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1),
* then frame_size needs to be exactly the duration of audio that is missing, otherwise the
* decoder will not be in the optimal state to decode the next incoming packet. For the PLC and
* FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms.
* @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be
* decoded. If no such data is available, the frame is decoded as if it were lost.
* @returns Number of decoded samples or @ref opus_errorcodes
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode24(
OpusDecoder *st,
const unsigned char *data,
opus_int32 len,
opus_int32 *pcm,
int frame_size,
int decode_fec
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Decode an Opus packet with floating point output.
* @param [in] st <tt>OpusDecoder*</tt>: Decoder state
* @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
@@ -596,7 +657,7 @@ OPUS_EXPORT int opus_dred_parse(OpusDREDDecoder *dred_dec, OpusDRED *dred, const
*/
OPUS_EXPORT int opus_dred_process(OpusDREDDecoder *dred_dec, const OpusDRED *src, OpusDRED *dst);
/** Decode audio from an Opus DRED packet with floating point output.
/** Decode audio from an Opus DRED packet with 16-bit output.
* @param [in] st <tt>OpusDecoder*</tt>: Decoder state
* @param [in] dred <tt>OpusDRED*</tt>: DRED state
* @param [in] dred_offset <tt>opus_int32</tt>: position of the redundancy to decode (in samples before the beginning of the real audio data in the packet).
@@ -608,6 +669,18 @@ OPUS_EXPORT int opus_dred_process(OpusDREDDecoder *dred_dec, const OpusDRED *src
*/
OPUS_EXPORT int opus_decoder_dred_decode(OpusDecoder *st, const OpusDRED *dred, opus_int32 dred_offset, opus_int16 *pcm, opus_int32 frame_size);
/** Decode audio from an Opus DRED packet with 24-bit output.
* @param [in] st <tt>OpusDecoder*</tt>: Decoder state
* @param [in] dred <tt>OpusDRED*</tt>: DRED state
* @param [in] dred_offset <tt>opus_int32</tt>: position of the redundancy to decode (in samples before the beginning of the real audio data in the packet).
* @param [out] pcm <tt>opus_int32*</tt>: Output signal (interleaved if 2 channels). length
* is frame_size*channels*sizeof(opus_int16)
* @param [in] frame_size Number of samples per channel to decode in \a pcm.
* frame_size <b>must</b> be a multiple of 2.5 ms.
* @returns Number of decoded samples or @ref opus_errorcodes
*/
OPUS_EXPORT int opus_decoder_dred_decode24(OpusDecoder *st, const OpusDRED *dred, opus_int32 dred_offset, opus_int32 *pcm, opus_int32 frame_size);
/** Decode audio from an Opus DRED packet with floating point output.
* @param [in] st <tt>OpusDecoder*</tt>: Decoder state
* @param [in] dred <tt>OpusDRED*</tt>: DRED state

View File

@@ -230,6 +230,27 @@ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode(
int maxCompressedBytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
/** Encodes a frame of audio.
* @param [in] st <tt>OpusCustomEncoder*</tt>: Encoder state
* @param [in] pcm <tt>opus_int32*</tt>: PCM audio in signed 32-bit format (native endian) representing (or slightly exceeding) 24-bit values.
* There must be exactly frame_size samples per channel.
* @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal
* @param [out] compressed <tt>char *</tt>: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long.
* @param [in] maxCompressedBytes <tt>int</tt>: Maximum number of bytes to use for compressing the frame
* (can change from one frame to another)
* @return Number of bytes written to "compressed".
* If negative, an error has occurred (see error codes). It is IMPORTANT that
* the length returned be somehow transmitted to the decoder. Otherwise, no
* decoding is possible.
*/
OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode24(
OpusCustomEncoder *st,
const opus_int32 *pcm,
int frame_size,
unsigned char *compressed,
int maxCompressedBytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
/** Perform a CTL function on an Opus custom encoder.
*
* Generally the request and subsequent arguments are generated
@@ -326,6 +347,23 @@ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode(
int frame_size
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Decode an opus custom frame
* @param [in] st <tt>OpusCustomDecoder*</tt>: Decoder state
* @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
* @param [in] len <tt>int</tt>: Number of bytes in payload
* @param [out] pcm <tt>opus_int32*</tt>: Output signal (interleaved if 2 channels) representing (or slightly exceeding) 24-bit values. length
* is frame_size*channels*sizeof(opus_int32)
* @param [in] frame_size Number of samples per channel of available space in *pcm.
* @returns Number of decoded samples or @ref opus_errorcodes
*/
OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode24(
OpusCustomDecoder *st,
const unsigned char *data,
int len,
opus_int32 *pcm,
int frame_size
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Perform a CTL function on an Opus custom decoder.
*
* Generally the request and subsequent arguments are generated

View File

@@ -382,6 +382,44 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode(
opus_int32 max_data_bytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
/** Encodes a multistream Opus frame.
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
* @param[in] pcm <tt>const opus_int32*</tt>: The input signal as interleaved
* samples representing (or slightly exceeding) 24-bit values.
* This must contain
* <code>frame_size*channels</code>
* samples.
* @param frame_size <tt>int</tt>: Number of samples per channel in the input
* signal.
* This must be an Opus frame size for the
* encoder's sampling rate.
* For example, at 48 kHz the permitted values
* are 120, 240, 480, 960, 1920, and 2880.
* Passing in a duration of less than 10 ms
* (480 samples at 48 kHz) will prevent the
* encoder from using the LPC or hybrid modes.
* @param[out] data <tt>unsigned char*</tt>: Output payload.
* This must contain storage for at
* least \a max_data_bytes.
* @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
* memory for the output
* payload. This may be
* used to impose an upper limit on
* the instant bitrate, but should
* not be used as the only bitrate
* control. Use #OPUS_SET_BITRATE to
* control the bitrate.
* @returns The length of the encoded packet (in bytes) on success or a
* negative error code (see @ref opus_errorcodes) on failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode24(
OpusMSEncoder *st,
const opus_int32 *pcm,
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
/** Encodes a multistream Opus frame from floating point input.
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
* @param[in] pcm <tt>const float*</tt>: The input signal as interleaved
@@ -591,6 +629,44 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode(
int decode_fec
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Decode a multistream Opus packet.
* @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
* @param[in] data <tt>const unsigned char*</tt>: Input payload.
* Use a <code>NULL</code>
* pointer to indicate packet
* loss.
* @param len <tt>opus_int32</tt>: Number of bytes in payload.
* @param[out] pcm <tt>opus_int32*</tt>: Output signal, with interleaved
* samples representing (or slightly exceeding) 24-bit values.
* This must contain room for
* <code>frame_size*channels</code>
* samples.
* @param frame_size <tt>int</tt>: The number of samples per channel of
* available space in \a pcm.
* If this is less than the maximum packet duration
* (120 ms; 5760 for 48kHz), this function will not be capable
* of decoding some packets. In the case of PLC (data==NULL)
* or FEC (decode_fec=1), then frame_size needs to be exactly
* the duration of audio that is missing, otherwise the
* decoder will not be in the optimal state to decode the
* next incoming packet. For the PLC and FEC cases, frame_size
* <b>must</b> be a multiple of 2.5 ms.
* @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
* forward error correction data be decoded.
* If no such data is available, the frame is
* decoded as if it were lost.
* @returns Number of samples decoded on success or a negative error code
* (see @ref opus_errorcodes) on failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode24(
OpusMSDecoder *st,
const unsigned char *data,
opus_int32 len,
opus_int32 *pcm,
int frame_size,
int decode_fec
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Decode a multistream Opus packet with floating point output.
* @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
* @param[in] data <tt>const unsigned char*</tt>: Input payload.

View File

@@ -260,6 +260,44 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode(
opus_int32 max_data_bytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
/** Encodes a projection Opus frame.
* @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state.
* @param[in] pcm <tt>const opus_int32*</tt>: The input signal as interleaved
* samples representing (or slightly exceeding) 24-bit values.
* This must contain
* <code>frame_size*channels</code>
* samples.
* @param frame_size <tt>int</tt>: Number of samples per channel in the input
* signal.
* This must be an Opus frame size for the
* encoder's sampling rate.
* For example, at 48 kHz the permitted values
* are 120, 240, 480, 960, 1920, and 2880.
* Passing in a duration of less than 10 ms
* (480 samples at 48 kHz) will prevent the
* encoder from using the LPC or hybrid modes.
* @param[out] data <tt>unsigned char*</tt>: Output payload.
* This must contain storage for at
* least \a max_data_bytes.
* @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
* memory for the output
* payload. This may be
* used to impose an upper limit on
* the instant bitrate, but should
* not be used as the only bitrate
* control. Use #OPUS_SET_BITRATE to
* control the bitrate.
* @returns The length of the encoded packet (in bytes) on success or a
* negative error code (see @ref opus_errorcodes) on failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode24(
OpusProjectionEncoder *st,
const opus_int32 *pcm,
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
/** Encodes a projection Opus frame from floating point input.
* @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state.
@@ -493,6 +531,43 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode(
int decode_fec
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Decode a projection Opus packet.
* @param st <tt>OpusProjectionDecoder*</tt>: Projection decoder state.
* @param[in] data <tt>const unsigned char*</tt>: Input payload.
* Use a <code>NULL</code>
* pointer to indicate packet
* loss.
* @param len <tt>opus_int32</tt>: Number of bytes in payload.
* @param[out] pcm <tt>opus_int32*</tt>: Output signal, with interleaved
* samples representing (or slightly exceeding) 24-bit values.
* This must contain room for
* <code>frame_size*channels</code>
* samples.
* @param frame_size <tt>int</tt>: The number of samples per channel of
* available space in \a pcm.
* If this is less than the maximum packet duration
* (120 ms; 5760 for 48kHz), this function will not be capable
* of decoding some packets. In the case of PLC (data==NULL)
* or FEC (decode_fec=1), then frame_size needs to be exactly
* the duration of audio that is missing, otherwise the
* decoder will not be in the optimal state to decode the
* next incoming packet. For the PLC and FEC cases, frame_size
* <b>must</b> be a multiple of 2.5 ms.
* @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
* forward error correction data be decoded.
* If no such data is available, the frame is
* decoded as if it were lost.
* @returns Number of samples decoded on success or a negative error code
* (see @ref opus_errorcodes) on failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode24(
OpusProjectionDecoder *st,
const unsigned char *data,
opus_int32 len,
opus_int32 *pcm,
int frame_size,
int decode_fec
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Decode a projection Opus packet with floating point output.
* @param st <tt>OpusProjectionDecoder*</tt>: Projection decoder state.

View File

@@ -21,7 +21,7 @@ FINAL_LIBRARY = "gkcodecs"
NoVisibilityFlags()
DEFINES["OPUS_BUILD"] = True
DEFINES["OPUS_VERSION"] = "734aed05d09af3d2690f8cb5aafa97f052746daf"
DEFINES["OPUS_VERSION"] = "c79a9bd1dd2898cd57bb793e037d58c937555c2c"
DEFINES["USE_ALLOCA"] = True
DEFINES["ENABLE_HARDENING"] = True

View File

@@ -20,11 +20,11 @@ origin:
# Human-readable identifier for this version/release
# Generally "version NNN", "tag SSS", "bookmark SSS"
release: 734aed05d09af3d2690f8cb5aafa97f052746daf (2025-02-10T14:18:25.000-05:00).
release: c79a9bd1dd2898cd57bb793e037d58c937555c2c (2025-02-13T12:50:05.000-05:00).
# Revision to pull in
# Must be a long or short commit SHA (long preferred)
revision: 734aed05d09af3d2690f8cb5aafa97f052746daf
revision: c79a9bd1dd2898cd57bb793e037d58c937555c2c
# The package's license, where possible using the mnemonic from
# https://spdx.org/licenses/

View File

@@ -80,7 +80,7 @@ opus_int silk_InitEncoder( /* O Returns error co
opus_int silk_Encode( /* O Returns error code */
void *encState, /* I/O State */
silk_EncControlStruct *encControl, /* I Control status */
const opus_int16 *samplesIn, /* I Speech sample input vector */
const opus_res *samplesIn, /* I Speech sample input vector */
opus_int nSamplesIn, /* I Number of samples in input vector */
ec_enc *psRangeEnc, /* I/O Compressor data structure */
opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */
@@ -129,7 +129,7 @@ opus_int silk_Decode( /* O Returns error co
opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */
opus_int newPacketFlag, /* I Indicates first decoder call for this packet */
ec_dec *psRangeDec, /* I/O Compressor data structure */
opus_int16 *samplesOut, /* O Decoded output speech vector */
opus_res *samplesOut, /* O Decoded output speech vector */
opus_int32 *nSamplesOut, /* O Number of samples decoded */
#ifdef ENABLE_DEEP_PLC
LPCNetPLCState *lpcnet,

View File

@@ -135,7 +135,7 @@ opus_int silk_Decode( /* O Returns error co
opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */
opus_int newPacketFlag, /* I Indicates first decoder call for this packet */
ec_dec *psRangeDec, /* I/O Compressor data structure */
opus_int16 *samplesOut, /* O Decoded output speech vector */
opus_res *samplesOut, /* O Decoded output speech vector */
opus_int32 *nSamplesOut, /* O Number of samples decoded */
#ifdef ENABLE_DEEP_PLC
LPCNetPLCState *lpcnet,
@@ -147,7 +147,6 @@ opus_int silk_Decode( /* O Returns error co
opus_int32 nSamplesOutDec, LBRR_symbol;
opus_int16 *samplesOut1_tmp[ 2 ];
VARDECL( opus_int16, samplesOut1_tmp_storage1 );
VARDECL( opus_int16, samplesOut1_tmp_storage2 );
VARDECL( opus_int16, samplesOut2_tmp );
opus_int32 MS_pred_Q13[ 2 ] = { 0 };
opus_int16 *resample_out_ptr;
@@ -155,7 +154,6 @@ opus_int silk_Decode( /* O Returns error co
silk_decoder_state *channel_state = psDec->channel_state;
opus_int has_side;
opus_int stereo_to_mono;
int delay_stack_alloc;
SAVE_STACK;
celt_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 );
@@ -312,19 +310,10 @@ opus_int silk_Decode( /* O Returns error co
/* Check if the temp buffer fits into the output PCM buffer. If it fits,
we can delay allocating the temp buffer until after the SILK peak stack
usage. We need to use a < and not a <= because of the two extra samples. */
delay_stack_alloc = decControl->internalSampleRate*decControl->nChannelsInternal
< decControl->API_sampleRate*decControl->nChannelsAPI;
ALLOC( samplesOut1_tmp_storage1, delay_stack_alloc ? ALLOC_NONE
: decControl->nChannelsInternal*(channel_state[ 0 ].frame_length + 2 ),
ALLOC( samplesOut1_tmp_storage1, decControl->nChannelsInternal*(channel_state[ 0 ].frame_length + 2 ),
opus_int16 );
if ( delay_stack_alloc )
{
samplesOut1_tmp[ 0 ] = samplesOut;
samplesOut1_tmp[ 1 ] = samplesOut + channel_state[ 0 ].frame_length + 2;
} else {
samplesOut1_tmp[ 0 ] = samplesOut1_tmp_storage1;
samplesOut1_tmp[ 1 ] = samplesOut1_tmp_storage1 + channel_state[ 0 ].frame_length + 2;
}
if( lostFlag == FLAG_DECODE_NORMAL ) {
has_side = !decode_only_middle;
@@ -384,23 +373,9 @@ opus_int silk_Decode( /* O Returns error co
*nSamplesOut = silk_DIV32( nSamplesOutDec * decControl->API_sampleRate, silk_SMULBB( channel_state[ 0 ].fs_kHz, 1000 ) );
/* Set up pointers to temp buffers */
ALLOC( samplesOut2_tmp,
decControl->nChannelsAPI == 2 ? *nSamplesOut : ALLOC_NONE, opus_int16 );
if( decControl->nChannelsAPI == 2 ) {
ALLOC( samplesOut2_tmp, *nSamplesOut, opus_int16 );
resample_out_ptr = samplesOut2_tmp;
} else {
resample_out_ptr = samplesOut;
}
ALLOC( samplesOut1_tmp_storage2, delay_stack_alloc
? decControl->nChannelsInternal*(channel_state[ 0 ].frame_length + 2 )
: ALLOC_NONE,
opus_int16 );
if ( delay_stack_alloc ) {
OPUS_COPY(samplesOut1_tmp_storage2, samplesOut, decControl->nChannelsInternal*(channel_state[ 0 ].frame_length + 2));
samplesOut1_tmp[ 0 ] = samplesOut1_tmp_storage2;
samplesOut1_tmp[ 1 ] = samplesOut1_tmp_storage2 + channel_state[ 0 ].frame_length + 2;
}
for( n = 0; n < silk_min( decControl->nChannelsAPI, decControl->nChannelsInternal ); n++ ) {
/* Resample decoded signal to API_sampleRate */
@@ -409,7 +384,11 @@ opus_int silk_Decode( /* O Returns error co
/* Interleave if stereo output and stereo stream */
if( decControl->nChannelsAPI == 2 ) {
for( i = 0; i < *nSamplesOut; i++ ) {
samplesOut[ n + 2 * i ] = resample_out_ptr[ i ];
samplesOut[ n + 2 * i ] = INT16TORES(resample_out_ptr[ i ]);
}
} else {
for( i = 0; i < *nSamplesOut; i++ ) {
samplesOut[ i ] = INT16TORES(resample_out_ptr[ i ]);
}
}
}
@@ -422,7 +401,7 @@ opus_int silk_Decode( /* O Returns error co
ret += silk_resampler( &channel_state[ 1 ].resampler_state, resample_out_ptr, &samplesOut1_tmp[ 0 ][ 1 ], nSamplesOutDec );
for( i = 0; i < *nSamplesOut; i++ ) {
samplesOut[ 1 + 2 * i ] = resample_out_ptr[ i ];
samplesOut[ 1 + 2 * i ] = INT16TORES(resample_out_ptr[ i ]);
}
} else {
for( i = 0; i < *nSamplesOut; i++ ) {

View File

@@ -144,7 +144,7 @@ static opus_int silk_QueryEncoder( /* O Returns error co
opus_int silk_Encode( /* O Returns error code */
void *encState, /* I/O State */
silk_EncControlStruct *encControl, /* I Control status */
const opus_int16 *samplesIn, /* I Speech sample input vector */
const opus_res *samplesIn, /* I Speech sample input vector */
opus_int nSamplesIn, /* I Number of samples in input vector */
ec_enc *psRangeEnc, /* I/O Compressor data structure */
opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */
@@ -282,7 +282,7 @@ opus_int silk_Encode( /* O Returns error co
if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) {
opus_int id = psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;
for( n = 0; n < nSamplesFromInput; n++ ) {
buf[ n ] = samplesIn[ 2 * n ];
buf[ n ] = RES2INT16(samplesIn[ 2 * n ]);
}
/* Making sure to start both resamplers from the same state when switching from mono to stereo */
if( psEnc->nPrevChannelsInternal == 1 && id==0 ) {
@@ -296,7 +296,7 @@ opus_int silk_Encode( /* O Returns error co
nSamplesToBuffer = psEnc->state_Fxx[ 1 ].sCmn.frame_length - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx;
nSamplesToBuffer = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
for( n = 0; n < nSamplesFromInput; n++ ) {
buf[ n ] = samplesIn[ 2 * n + 1 ];
buf[ n ] = RES2INT16(samplesIn[ 2 * n + 1 ]);
}
ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,
&psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
@@ -305,7 +305,7 @@ opus_int silk_Encode( /* O Returns error co
} else if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 1 ) {
/* Combine left and right channels before resampling */
for( n = 0; n < nSamplesFromInput; n++ ) {
sum = samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ];
sum = RES2INT16(samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ]);
buf[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 );
}
ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
@@ -323,7 +323,9 @@ opus_int silk_Encode( /* O Returns error co
psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
} else {
celt_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 );
silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16));
for( n = 0; n < nSamplesFromInput; n++ ) {
buf[n] = RES2INT16(samplesIn[n]);
}
ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
&psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;

View File

@@ -106,13 +106,14 @@ static OPUS_INLINE opus_int32 silk_sar_round_32(opus_int32 a, int bits)
static OPUS_INLINE opus_int64 silk_sar_round_smulww(opus_int32 a, opus_int32 b, int bits)
{
opus_int64 t;
silk_assert(bits > 0 && bits < 63);
#ifdef OPUS_CHECK_ASM
return silk_RSHIFT_ROUND(silk_SMULWW(a, b), bits);
#else
/* This code is more correct, but it won't overflow like the C code in some rare cases. */
silk_assert(bits > 0 && bits < 63);
opus_int64 t = ((opus_int64)a) * ((opus_int64)b);
t = ((opus_int64)a) * ((opus_int64)b);
bits += 16;
t += 1ull << (bits-1);
return t >> bits;

View File

@@ -163,7 +163,6 @@ static opus_val32 silk_resampler_down2_hp(
static opus_val32 downmix_and_resample(downmix_func downmix, const void *_x, opus_val32 *y, opus_val32 S[3], int subframe, int offset, int c1, int c2, int C, int Fs)
{
VARDECL(opus_val32, tmp);
opus_val32 scale;
int j;
opus_val32 ret = 0;
SAVE_STACK;
@@ -180,17 +179,11 @@ static opus_val32 downmix_and_resample(downmix_func downmix, const void *_x, opu
ALLOC(tmp, subframe, opus_val32);
downmix(_x, tmp, subframe, offset, c1, c2, C);
#ifdef FIXED_POINT
scale = (1<<SIG_SHIFT);
#else
scale = 1.f/32768;
#endif
if (c2==-2)
scale /= C;
else if (c2>-1)
scale /= 2;
for (j=0;j<subframe;j++)
tmp[j] *= scale;
if ((c2==-2 && C==2) || c2>-1) {
for (j=0;j<subframe;j++) {
tmp[j] = HALF32(tmp[j]);
}
}
if (Fs == 48000)
{
ret = silk_resampler_down2_hp(S, y, tmp, subframe);
@@ -211,6 +204,9 @@ static opus_val32 downmix_and_resample(downmix_func downmix, const void *_x, opu
silk_resampler_down2_hp(S, y, tmp3x, 3*subframe);
}
RESTORE_STACK;
#ifndef FIXED_POINT
ret *= 1.f/32768/32768;
#endif
return ret;
}
@@ -422,7 +418,7 @@ static const float std_feature_bias[9] = {
#define SCALE_COMPENS (1.f/((opus_int32)1<<(15+SIG_SHIFT)))
#define SCALE_ENER(e) ((SCALE_COMPENS*SCALE_COMPENS)*(e))
#else
#define SCALE_ENER(e) (e)
#define SCALE_ENER(e) ((1.f/32768/32768)*e)
#endif
#ifdef FIXED_POINT

View File

@@ -86,7 +86,7 @@ void mapping_matrix_multiply_channel_in_float(
const MappingMatrix *matrix,
const float *input,
int input_rows,
opus_val16 *output,
opus_res *output,
int output_row,
int output_rows,
int frame_size)
@@ -108,17 +108,13 @@ void mapping_matrix_multiply_channel_in_float(
matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] *
input[MATRIX_INDEX(input_rows, col, i)];
}
#if defined(FIXED_POINT)
output[output_rows * i] = FLOAT2INT16((1/32768.f)*tmp);
#else
output[output_rows * i] = (1/32768.f)*tmp;
#endif
output[output_rows * i] = FLOAT2RES((1/32768.f)*tmp);
}
}
void mapping_matrix_multiply_channel_out_float(
const MappingMatrix *matrix,
const opus_val16 *input,
const opus_res *input,
int input_row,
int input_rows,
float *output,
@@ -137,11 +133,7 @@ void mapping_matrix_multiply_channel_out_float(
for (i = 0; i < frame_size; i++)
{
#if defined(FIXED_POINT)
input_sample = (1/32768.f)*input[input_rows * i];
#else
input_sample = input[input_rows * i];
#endif
input_sample = RES2FLOAT(input[input_rows * i]);
for (row = 0; row < output_rows; row++)
{
float tmp =
@@ -157,7 +149,7 @@ void mapping_matrix_multiply_channel_in_short(
const MappingMatrix *matrix,
const opus_int16 *input,
int input_rows,
opus_val16 *output,
opus_res *output,
int output_row,
int output_rows,
int frame_size)
@@ -186,7 +178,7 @@ void mapping_matrix_multiply_channel_in_short(
#endif
}
#if defined(FIXED_POINT)
output[output_rows * i] = (opus_int16)((tmp + 64) >> 7);
output[output_rows * i] = INT16TORES((tmp + 64) >> 7);
#else
output[output_rows * i] = (1/(32768.f*32768.f))*tmp;
#endif
@@ -195,7 +187,7 @@ void mapping_matrix_multiply_channel_in_short(
void mapping_matrix_multiply_channel_out_short(
const MappingMatrix *matrix,
const opus_val16 *input,
const opus_res *input,
int input_row,
int input_rows,
opus_int16 *output,
@@ -213,11 +205,7 @@ void mapping_matrix_multiply_channel_out_short(
for (i = 0; i < frame_size; i++)
{
#if defined(FIXED_POINT)
input_sample = (opus_int32)input[input_rows * i];
#else
input_sample = (opus_int32)FLOAT2INT16(input[input_rows * i]);
#endif
input_sample = RES2INT16(input[input_rows * i]);
for (row = 0; row < output_rows; row++)
{
opus_int32 tmp =
@@ -228,6 +216,72 @@ void mapping_matrix_multiply_channel_out_short(
}
}
void mapping_matrix_multiply_channel_in_int24(
const MappingMatrix *matrix,
const opus_int32 *input,
int input_rows,
opus_res *output,
int output_row,
int output_rows,
int frame_size)
{
/* Matrix data is ordered col-wise. */
opus_int16* matrix_data;
int i, col;
celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
matrix_data = mapping_matrix_get_data(matrix);
for (i = 0; i < frame_size; i++)
{
opus_val64 tmp = 0;
for (col = 0; col < input_rows; col++)
{
tmp +=
matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] *
(opus_val64)input[MATRIX_INDEX(input_rows, col, i)];
}
#if defined(FIXED_POINT)
output[output_rows * i] = INT24TORES((tmp + 16384) >> 15);
#else
output[output_rows * i] = INT24TORES((1/(32768.f))*tmp);
#endif
}
}
void mapping_matrix_multiply_channel_out_int24(
const MappingMatrix *matrix,
const opus_res *input,
int input_row,
int input_rows,
opus_int32 *output,
int output_rows,
int frame_size)
{
/* Matrix data is ordered col-wise. */
opus_int16* matrix_data;
int i, row;
opus_int32 input_sample;
celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
matrix_data = mapping_matrix_get_data(matrix);
for (i = 0; i < frame_size; i++)
{
input_sample = RES2INT24(input[input_rows * i]);
for (row = 0; row < output_rows; row++)
{
opus_int64 tmp =
(opus_int64)matrix_data[MATRIX_INDEX(matrix->rows, row, input_row)] *
input_sample;
output[MATRIX_INDEX(output_rows, row, i)] += (tmp + 16384) >> 15;
}
}
}
const MappingMatrix mapping_matrix_foa_mixing = { 6, 6, 0 };
const opus_int16 mapping_matrix_foa_mixing_data[36] = {
16384, 0, -16384, 23170, 0, 0, 16384, 23170,

View File

@@ -66,7 +66,7 @@ void mapping_matrix_multiply_channel_in_float(
const MappingMatrix *matrix,
const float *input,
int input_rows,
opus_val16 *output,
opus_res *output,
int output_row,
int output_rows,
int frame_size
@@ -74,7 +74,7 @@ void mapping_matrix_multiply_channel_in_float(
void mapping_matrix_multiply_channel_out_float(
const MappingMatrix *matrix,
const opus_val16 *input,
const opus_res *input,
int input_row,
int input_rows,
float *output,
@@ -87,7 +87,7 @@ void mapping_matrix_multiply_channel_in_short(
const MappingMatrix *matrix,
const opus_int16 *input,
int input_rows,
opus_val16 *output,
opus_res *output,
int output_row,
int output_rows,
int frame_size
@@ -95,7 +95,7 @@ void mapping_matrix_multiply_channel_in_short(
void mapping_matrix_multiply_channel_out_short(
const MappingMatrix *matrix,
const opus_val16 *input,
const opus_res *input,
int input_row,
int input_rows,
opus_int16 *output,
@@ -103,6 +103,26 @@ void mapping_matrix_multiply_channel_out_short(
int frame_size
);
void mapping_matrix_multiply_channel_in_int24(
const MappingMatrix *matrix,
const opus_int32 *input,
int input_rows,
opus_res *output,
int output_row,
int output_rows,
int frame_size
);
void mapping_matrix_multiply_channel_out_int24(
const MappingMatrix *matrix,
const opus_res *input,
int input_row,
int input_rows,
opus_int32 *output,
int output_rows,
int frame_size
);
/* Pre-computed mixing and demixing matrices for 1st to 3rd-order ambisonics.
* foa: first-order ambisonics
* soa: second-order ambisonics

View File

@@ -202,8 +202,26 @@ 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,
#ifdef ENABLE_RES24
static void smooth_fade(const opus_res *in1, const opus_res *in2,
opus_res *out, int overlap, int channels,
const celt_coef *window, opus_int32 Fs)
{
int i, c;
int inc = 48000/Fs;
for (c=0;c<channels;c++)
{
for (i=0;i<overlap;i++)
{
celt_coef w = MULT_COEF(window[i*inc], window[i*inc]);
out[i*channels+c] = ADD32(MULT_COEF_32(w,in2[i*channels+c]),
MULT_COEF_32(COEF_ONE-w, in1[i*channels+c]));
}
}
}
#else
static void smooth_fade(const opus_res *in1, const opus_res *in2,
opus_res *out, int overlap, int channels,
const opus_val16 *window, opus_int32 Fs)
{
int i, c;
@@ -218,6 +236,7 @@ static void smooth_fade(const opus_val16 *in1, const opus_val16 *in2,
}
}
}
#endif
static int opus_packet_get_mode(const unsigned char *data)
{
@@ -235,22 +254,20 @@ static int opus_packet_get_mode(const unsigned char *data)
}
static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
opus_int32 len, opus_res *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;
int pcm_silk_size;
VARDECL(opus_int16, pcm_silk);
int pcm_transition_silk_size;
VARDECL(opus_val16, pcm_transition_silk);
VARDECL(opus_res, pcm_transition_silk);
int pcm_transition_celt_size;
VARDECL(opus_val16, pcm_transition_celt);
opus_val16 *pcm_transition=NULL;
VARDECL(opus_res, pcm_transition_celt);
opus_res *pcm_transition=NULL;
int redundant_audio_size;
VARDECL(opus_val16, redundant_audio);
VARDECL(opus_res, redundant_audio);
int audiosize;
int mode;
@@ -262,7 +279,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
int celt_to_silk=0;
int c;
int F2_5, F5, F10, F20;
const opus_val16 *window;
const celt_coef *window;
opus_uint32 redundant_rng = 0;
int celt_accum;
ALLOC_STACK;
@@ -335,11 +352,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
/* In fixed-point, we can tell CELT to do the accumulation on top of the
SILK PCM buffer. This saves some stack space. */
#ifdef FIXED_POINT
celt_accum = (mode != MODE_CELT_ONLY) && (frame_size >= F10);
#else
celt_accum = 0;
#endif
celt_accum = (mode != MODE_CELT_ONLY);
pcm_transition_silk_size = ALLOC_NONE;
pcm_transition_celt_size = ALLOC_NONE;
@@ -355,7 +368,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
else
pcm_transition_silk_size = F5*st->channels;
}
ALLOC(pcm_transition_celt, pcm_transition_celt_size, opus_val16);
ALLOC(pcm_transition_celt, pcm_transition_celt_size, opus_res);
if (transition && mode == MODE_CELT_ONLY)
{
pcm_transition = pcm_transition_celt;
@@ -370,21 +383,22 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
frame_size = audiosize;
}
/* Don't allocate any memory when in CELT-only mode */
pcm_silk_size = (mode != MODE_CELT_ONLY && !celt_accum) ? IMAX(F10, frame_size)*st->channels : ALLOC_NONE;
ALLOC(pcm_silk, pcm_silk_size, opus_int16);
/* SILK processing */
if (mode != MODE_CELT_ONLY)
{
int lost_flag, decoded_samples;
opus_int16 *pcm_ptr;
#ifdef FIXED_POINT
if (celt_accum)
pcm_ptr = pcm;
else
#endif
opus_res *pcm_ptr;
int pcm_too_small;
int pcm_silk_size = ALLOC_NONE;
VARDECL(opus_res, pcm_silk);
pcm_too_small = (frame_size < F10);
if (pcm_too_small)
pcm_silk_size = F10*st->channels;
ALLOC(pcm_silk, pcm_silk_size, opus_res);
if (pcm_too_small)
pcm_ptr = pcm_silk;
else
pcm_ptr = pcm;
if (st->prev_mode==MODE_CELT_ONLY)
silk_ResetDecoder( silk_dec );
@@ -447,6 +461,9 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
pcm_ptr += silk_frame_size * st->channels;
decoded_samples += silk_frame_size;
} while( decoded_samples < frame_size );
if (pcm_too_small) {
OPUS_COPY(pcm, pcm_silk, frame_size*st->channels);
}
}
start_band = 0;
@@ -488,7 +505,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
pcm_transition_silk_size=ALLOC_NONE;
}
ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16);
ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_res);
if (transition && mode != MODE_CELT_ONLY)
{
@@ -526,7 +543,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
/* Only allocation memory for redundancy if/when needed */
redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE;
ALLOC(redundant_audio, redundant_audio_size, opus_val16);
ALLOC(redundant_audio, redundant_audio_size, opus_res);
/* 5 ms redundant frame for CELT->SILK*/
if (redundancy && celt_to_silk)
@@ -574,17 +591,6 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
}
}
if (mode != MODE_CELT_ONLY && !celt_accum)
{
#ifdef FIXED_POINT
for (i=0;i<frame_size*st->channels;i++)
pcm[i] = SAT16(ADD32(pcm[i], pcm_silk[i]));
#else
for (i=0;i<frame_size*st->channels;i++)
pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]);
#endif
}
{
const CELTMode *celt_mode;
MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode)));
@@ -668,7 +674,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
}
int opus_decode_native(OpusDecoder *st, const unsigned char *data,
opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec,
opus_int32 len, opus_res *pcm, int frame_size, int decode_fec,
int self_delimited, opus_int32 *packet_offset, int soft_clip, const OpusDRED *dred, opus_int32 dred_offset)
{
int i, nb_samples;
@@ -811,20 +817,24 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data,
}
#ifdef FIXED_POINT
#define OPTIONAL_CLIP 0
#else
#define OPTIONAL_CLIP 1
#endif
#if defined(FIXED_POINT) && !defined(ENABLE_RES24)
int opus_decode(OpusDecoder *st, const unsigned char *data,
opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
{
if(frame_size<=0)
return OPUS_BAD_ARG;
return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0, NULL, 0);
}
#ifndef DISABLE_FLOAT_API
int opus_decode_float(OpusDecoder *st, const unsigned char *data,
opus_int32 len, float *pcm, int frame_size, int decode_fec)
#else
int opus_decode(OpusDecoder *st, const unsigned char *data,
opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
{
VARDECL(opus_int16, out);
VARDECL(opus_res, out);
int ret, i;
int nb_samples;
ALLOC_STACK;
@@ -843,13 +853,57 @@ int opus_decode_float(OpusDecoder *st, const unsigned char *data,
return OPUS_INVALID_PACKET;
}
celt_assert(st->channels == 1 || st->channels == 2);
ALLOC(out, frame_size*st->channels, opus_int16);
ALLOC(out, frame_size*st->channels, opus_res);
ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, OPTIONAL_CLIP, NULL, 0);
if (ret > 0)
{
for (i=0;i<ret*st->channels;i++)
pcm[i] = RES2INT16(out[i]);
}
RESTORE_STACK;
return ret;
}
#endif
#if defined(FIXED_POINT) && defined(ENABLE_RES24)
int opus_decode24(OpusDecoder *st, const unsigned char *data,
opus_int32 len, opus_int32 *pcm, int frame_size, int decode_fec)
{
if(frame_size<=0)
return OPUS_BAD_ARG;
return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0, NULL, 0);
}
#else
int opus_decode24(OpusDecoder *st, const unsigned char *data,
opus_int32 len, opus_int32 *pcm, int frame_size, int decode_fec)
{
VARDECL(opus_res, out);
int ret, i;
int nb_samples;
ALLOC_STACK;
if(frame_size<=0)
{
RESTORE_STACK;
return OPUS_BAD_ARG;
}
if (data != NULL && len > 0 && !decode_fec)
{
nb_samples = opus_decoder_get_nb_samples(st, data, len);
if (nb_samples>0)
frame_size = IMIN(frame_size, nb_samples);
else
return OPUS_INVALID_PACKET;
}
celt_assert(st->channels == 1 || st->channels == 2);
ALLOC(out, frame_size*st->channels, opus_res);
ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0, NULL, 0);
if (ret > 0)
{
for (i=0;i<ret*st->channels;i++)
pcm[i] = (1.f/32768.f)*(out[i]);
pcm[i] = RES2INT24(out[i]);
}
RESTORE_STACK;
return ret;
@@ -857,11 +911,21 @@ int opus_decode_float(OpusDecoder *st, const unsigned char *data,
#endif
#else
int opus_decode(OpusDecoder *st, const unsigned char *data,
opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
#ifndef DISABLE_FLOAT_API
# if !defined(FIXED_POINT)
int opus_decode_float(OpusDecoder *st, const unsigned char *data,
opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
{
VARDECL(float, out);
if(frame_size<=0)
return OPUS_BAD_ARG;
return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0, NULL, 0);
}
# else
int opus_decode_float(OpusDecoder *st, const unsigned char *data,
opus_int32 len, float *pcm, int frame_size, int decode_fec)
{
VARDECL(opus_res, out);
int ret, i;
int nb_samples;
ALLOC_STACK;
@@ -871,7 +935,6 @@ int opus_decode(OpusDecoder *st, const unsigned char *data,
RESTORE_STACK;
return OPUS_BAD_ARG;
}
if (data != NULL && len > 0 && !decode_fec)
{
nb_samples = opus_decoder_get_nb_samples(st, data, len);
@@ -881,28 +944,22 @@ int opus_decode(OpusDecoder *st, const unsigned char *data,
return OPUS_INVALID_PACKET;
}
celt_assert(st->channels == 1 || st->channels == 2);
ALLOC(out, frame_size*st->channels, float);
ALLOC(out, frame_size*st->channels, opus_res);
ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1, NULL, 0);
ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0, NULL, 0);
if (ret > 0)
{
for (i=0;i<ret*st->channels;i++)
pcm[i] = FLOAT2INT16(out[i]);
pcm[i] = RES2FLOAT(out[i]);
}
RESTORE_STACK;
return ret;
}
int opus_decode_float(OpusDecoder *st, const unsigned char *data,
opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
{
if(frame_size<=0)
return OPUS_BAD_ARG;
return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0, NULL, 0);
}
# endif
#endif
int opus_decoder_ctl(OpusDecoder *st, int request, ...)
{
int ret = OPUS_OK;
@@ -1457,7 +1514,41 @@ int opus_decoder_dred_decode(OpusDecoder *st, const OpusDRED *dred, opus_int32 d
if (ret > 0)
{
for (i=0;i<ret*st->channels;i++)
pcm[i] = FLOAT2INT16(out[i]);
pcm[i] = RES2INT16(out[i]);
}
RESTORE_STACK;
return ret;
#else
(void)st;
(void)dred;
(void)dred_offset;
(void)pcm;
(void)frame_size;
return OPUS_UNIMPLEMENTED;
#endif
}
int opus_decoder_dred_decode24(OpusDecoder *st, const OpusDRED *dred, opus_int32 dred_offset, opus_int32 *pcm, opus_int32 frame_size)
{
#ifdef ENABLE_DRED
VARDECL(float, out);
int ret, i;
ALLOC_STACK;
if(frame_size<=0)
{
RESTORE_STACK;
return OPUS_BAD_ARG;
}
celt_assert(st->channels == 1 || st->channels == 2);
ALLOC(out, frame_size*st->channels, float);
ret = opus_decode_native(st, NULL, 0, out, frame_size, 0, 0, NULL, 1, dred, dred_offset);
if (ret > 0)
{
for (i=0;i<ret*st->channels;i++)
pcm[i] = RES2INT24(out[i]);
}
RESTORE_STACK;
return ret;

View File

@@ -119,9 +119,9 @@ struct OpusEncoder {
int silk_bw_switch;
/* Sampling rate (at the API level) */
int first;
opus_val16 * energy_masking;
celt_glog * energy_masking;
StereoWidthState width_mem;
opus_val16 delay_buffer[MAX_ENCODER_BUFFER*2];
opus_res delay_buffer[MAX_ENCODER_BUFFER*2];
#ifndef DISABLE_FLOAT_API
int detected_bandwidth;
int nb_no_activity_ms_Q1;
@@ -328,13 +328,52 @@ static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channel
return toc;
}
#ifndef FIXED_POINT
static void silk_biquad_float(
const opus_val16 *in, /* I: Input signal */
#ifdef FIXED_POINT
/* Second order ARMA filter, alternative implementation */
void silk_biquad_res(
const opus_res *in, /* I input signal */
const opus_int32 *B_Q28, /* I MA coefficients [3] */
const opus_int32 *A_Q28, /* I AR coefficients [2] */
opus_int32 *S, /* I/O State vector [2] */
opus_res *out, /* O output signal */
const opus_int32 len, /* I signal length (must be even) */
int stride
)
{
/* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
opus_int k;
opus_int32 inval, A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14;
/* Negate A_Q28 values and split in two parts */
A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */
A0_U_Q28 = silk_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */
A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */
A1_U_Q28 = silk_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */
for( k = 0; k < len; k++ ) {
/* S[ 0 ], S[ 1 ]: Q12 */
inval = RES2INT16(in[ k*stride ]);
out32_Q14 = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ), 2 );
S[ 0 ] = S[1] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A0_L_Q28 ), 14 );
S[ 0 ] = silk_SMLAWB( S[ 0 ], out32_Q14, A0_U_Q28 );
S[ 0 ] = silk_SMLAWB( S[ 0 ], B_Q28[ 1 ], inval);
S[ 1 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A1_L_Q28 ), 14 );
S[ 1 ] = silk_SMLAWB( S[ 1 ], out32_Q14, A1_U_Q28 );
S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval );
/* Scale back to Q0 and saturate */
out[ k*stride ] = INT16TORES( silk_SAT16( silk_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) ) );
}
}
#else
static void silk_biquad_res(
const opus_res *in, /* I: Input signal */
const opus_int32 *B_Q28, /* I: MA coefficients [3] */
const opus_int32 *A_Q28, /* I: AR coefficients [2] */
opus_val32 *S, /* I/O: State vector [2] */
opus_val16 *out, /* O: Output signal */
opus_res *out, /* O: Output signal */
const opus_int32 len, /* I: Signal length (must be even) */
int stride
)
@@ -368,7 +407,7 @@ static void silk_biquad_float(
}
#endif
static void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs, int arch)
static void hp_cutoff(const opus_res *in, opus_int32 cutoff_Hz, opus_res *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs, int arch)
{
opus_int32 B_Q28[ 3 ], A_Q28[ 2 ];
opus_int32 Fc_Q19, r_Q28, r_Q22;
@@ -391,22 +430,22 @@ static void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *ou
A_Q28[ 0 ] = silk_SMULWW( r_Q22, silk_SMULWW( Fc_Q19, Fc_Q19 ) - SILK_FIX_CONST( 2.0, 22 ) );
A_Q28[ 1 ] = silk_SMULWW( r_Q22, r_Q22 );
#ifdef FIXED_POINT
#if defined(FIXED_POINT) && !defined(ENABLE_RES24)
if( channels == 1 ) {
silk_biquad_alt_stride1( in, B_Q28, A_Q28, hp_mem, out, len );
} else {
silk_biquad_alt_stride2( in, B_Q28, A_Q28, hp_mem, out, len, arch );
}
#else
silk_biquad_float( in, B_Q28, A_Q28, hp_mem, out, len, channels );
silk_biquad_res( in, B_Q28, A_Q28, hp_mem, out, len, channels );
if( channels == 2 ) {
silk_biquad_float( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels );
silk_biquad_res( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels );
}
#endif
}
#ifdef FIXED_POINT
static void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs)
static void dc_reject(const opus_res *in, opus_int32 cutoff_Hz, opus_res *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs)
{
int c, i;
int shift;
@@ -418,10 +457,15 @@ static void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *ou
for (i=0;i<len;i++)
{
opus_val32 x, y;
x = SHL32(EXTEND32(in[channels*i+c]), 14);
x = SHL32((opus_val32)in[channels*i+c], 14-RES_SHIFT);
y = x-hp_mem[2*c];
hp_mem[2*c] = hp_mem[2*c] + PSHR32(x - hp_mem[2*c], shift);
out[channels*i+c] = EXTRACT16(SATURATE(PSHR32(y, 14), 32767));
#ifdef ENABLE_RES24
/* Don't saturate if we have the headroom to avoid it. */
out[channels*i+c] = PSHR32(y, 14-RES_SHIFT);
#else
out[channels*i+c] = SATURATE(PSHR32(y, 14-RES_SHIFT), 32767);
#endif
}
}
}
@@ -468,8 +512,8 @@ static void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *ou
}
#endif
static void stereo_fade(const opus_val16 *in, opus_val16 *out, opus_val16 g1, opus_val16 g2,
int overlap48, int frame_size, int channels, const opus_val16 *window, opus_int32 Fs)
static void stereo_fade(const opus_res *in, opus_res *out, opus_val16 g1, opus_val16 g2,
int overlap48, int frame_size, int channels, const celt_coef *window, opus_int32 Fs)
{
int i;
int overlap;
@@ -482,26 +526,27 @@ static void stereo_fade(const opus_val16 *in, opus_val16 *out, opus_val16 g1, op
{
opus_val32 diff;
opus_val16 g, w;
w = MULT16_16_Q15(window[i*inc], window[i*inc]);
w = COEF2VAL16(window[i*inc]);
w = MULT16_16_Q15(w, w);
g = SHR32(MAC16_16(MULT16_16(w,g2),
Q15ONE-w, g1), 15);
diff = EXTRACT16(HALF32((opus_val32)in[i*channels] - (opus_val32)in[i*channels+1]));
diff = MULT16_16_Q15(g, diff);
diff = HALF32((opus_val32)in[i*channels] - (opus_val32)in[i*channels+1]);
diff = MULT16_RES_Q15(g, diff);
out[i*channels] = out[i*channels] - diff;
out[i*channels+1] = out[i*channels+1] + diff;
}
for (;i<frame_size;i++)
{
opus_val32 diff;
diff = EXTRACT16(HALF32((opus_val32)in[i*channels] - (opus_val32)in[i*channels+1]));
diff = MULT16_16_Q15(g2, diff);
diff = HALF32((opus_val32)in[i*channels] - (opus_val32)in[i*channels+1]);
diff = MULT16_RES_Q15(g2, diff);
out[i*channels] = out[i*channels] - diff;
out[i*channels+1] = out[i*channels+1] + diff;
}
}
static void gain_fade(const opus_val16 *in, opus_val16 *out, opus_val16 g1, opus_val16 g2,
int overlap48, int frame_size, int channels, const opus_val16 *window, opus_int32 Fs)
static void gain_fade(const opus_res *in, opus_res *out, opus_val16 g1, opus_val16 g2,
int overlap48, int frame_size, int channels, const celt_coef *window, opus_int32 Fs)
{
int i;
int inc;
@@ -514,26 +559,28 @@ static void gain_fade(const opus_val16 *in, opus_val16 *out, opus_val16 g1, opus
for (i=0;i<overlap;i++)
{
opus_val16 g, w;
w = MULT16_16_Q15(window[i*inc], window[i*inc]);
w = COEF2VAL16(window[i*inc]);
w = MULT16_16_Q15(w, w);
g = SHR32(MAC16_16(MULT16_16(w,g2),
Q15ONE-w, g1), 15);
out[i] = MULT16_16_Q15(g, in[i]);
out[i] = MULT16_RES_Q15(g, in[i]);
}
} else {
for (i=0;i<overlap;i++)
{
opus_val16 g, w;
w = MULT16_16_Q15(window[i*inc], window[i*inc]);
w = COEF2VAL16(window[i*inc]);
w = MULT16_16_Q15(w, w);
g = SHR32(MAC16_16(MULT16_16(w,g2),
Q15ONE-w, g1), 15);
out[i*2] = MULT16_16_Q15(g, in[i*2]);
out[i*2+1] = MULT16_16_Q15(g, in[i*2+1]);
out[i*2] = MULT16_RES_Q15(g, in[i*2]);
out[i*2+1] = MULT16_RES_Q15(g, in[i*2+1]);
}
}
c=0;do {
for (i=overlap;i<frame_size;i++)
{
out[i*channels+c] = MULT16_16_Q15(g2, in[i*channels+c]);
out[i*channels+c] = MULT16_RES_Q15(g2, in[i*channels+c]);
}
}
while (++c<channels);
@@ -648,12 +695,6 @@ static opus_int32 user_bitrate_to_bitrate(OpusEncoder *st, int frame_size, int m
}
#ifndef DISABLE_FLOAT_API
#ifdef FIXED_POINT
#define PCM2VAL(x) FLOAT2INT16(x)
#else
#define PCM2VAL(x) SCALEIN(x)
#endif
void downmix_float(const void *_x, opus_val32 *y, int subframe, int offset, int c1, int c2, int C)
{
const float *x;
@@ -661,18 +702,18 @@ void downmix_float(const void *_x, opus_val32 *y, int subframe, int offset, int
x = (const float *)_x;
for (j=0;j<subframe;j++)
y[j] = PCM2VAL(x[(j+offset)*C+c1]);
y[j] = FLOAT2SIG(x[(j+offset)*C+c1]);
if (c2>-1)
{
for (j=0;j<subframe;j++)
y[j] += PCM2VAL(x[(j+offset)*C+c2]);
y[j] += FLOAT2SIG(x[(j+offset)*C+c2]);
} else if (c2==-2)
{
int c;
for (c=1;c<C;c++)
{
for (j=0;j<subframe;j++)
y[j] += PCM2VAL(x[(j+offset)*C+c]);
y[j] += FLOAT2SIG(x[(j+offset)*C+c]);
}
}
}
@@ -685,18 +726,41 @@ void downmix_int(const void *_x, opus_val32 *y, int subframe, int offset, int c1
x = (const opus_int16 *)_x;
for (j=0;j<subframe;j++)
y[j] = x[(j+offset)*C+c1];
y[j] = INT16TOSIG(x[(j+offset)*C+c1]);
if (c2>-1)
{
for (j=0;j<subframe;j++)
y[j] += x[(j+offset)*C+c2];
y[j] += INT16TOSIG(x[(j+offset)*C+c2]);
} else if (c2==-2)
{
int c;
for (c=1;c<C;c++)
{
for (j=0;j<subframe;j++)
y[j] += x[(j+offset)*C+c];
y[j] += INT16TOSIG(x[(j+offset)*C+c]);
}
}
}
void downmix_int24(const void *_x, opus_val32 *y, int subframe, int offset, int c1, int c2, int C)
{
const opus_int32 *x;
int j;
x = (const opus_int32 *)_x;
for (j=0;j<subframe;j++)
y[j] = INT24TOSIG(x[(j+offset)*C+c1]);
if (c2>-1)
{
for (j=0;j<subframe;j++)
y[j] += INT24TOSIG(x[(j+offset)*C+c2]);
} else if (c2==-2)
{
int c;
for (c=1;c<C;c++)
{
for (j=0;j<subframe;j++)
y[j] += INT24TOSIG(x[(j+offset)*C+c]);
}
}
}
@@ -726,7 +790,7 @@ opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_
return new_size;
}
opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int32 Fs, StereoWidthState *mem)
opus_val16 compute_stereo_width(const opus_res *pcm, int frame_size, opus_int32 Fs, StereoWidthState *mem)
{
opus_val32 xx, xy, yy;
opus_val16 sqrt_xx, sqrt_yy;
@@ -747,23 +811,23 @@ opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int3
opus_val32 pxy=0;
opus_val32 pyy=0;
opus_val16 x, y;
x = pcm[2*i];
y = pcm[2*i+1];
x = RES2VAL16(pcm[2*i]);
y = RES2VAL16(pcm[2*i+1]);
pxx = SHR32(MULT16_16(x,x),2);
pxy = SHR32(MULT16_16(x,y),2);
pyy = SHR32(MULT16_16(y,y),2);
x = pcm[2*i+2];
y = pcm[2*i+3];
x = RES2VAL16(pcm[2*i+2]);
y = RES2VAL16(pcm[2*i+3]);
pxx += SHR32(MULT16_16(x,x),2);
pxy += SHR32(MULT16_16(x,y),2);
pyy += SHR32(MULT16_16(y,y),2);
x = pcm[2*i+4];
y = pcm[2*i+5];
x = RES2VAL16(pcm[2*i+4]);
y = RES2VAL16(pcm[2*i+5]);
pxx += SHR32(MULT16_16(x,x),2);
pxy += SHR32(MULT16_16(x,y),2);
pyy += SHR32(MULT16_16(y,y),2);
x = pcm[2*i+6];
y = pcm[2*i+7];
x = RES2VAL16(pcm[2*i+6]);
y = RES2VAL16(pcm[2*i+7]);
pxx += SHR32(MULT16_16(x,x),2);
pxy += SHR32(MULT16_16(x,y),2);
pyy += SHR32(MULT16_16(y,y),2);
@@ -930,14 +994,14 @@ static opus_int32 compute_equiv_rate(opus_int32 bitrate, int channels,
#ifndef DISABLE_FLOAT_API
int is_digital_silence(const opus_val16* pcm, int frame_size, int channels, int lsb_depth)
int is_digital_silence(const opus_res* pcm, int frame_size, int channels, int lsb_depth)
{
int silence = 0;
opus_val32 sample_max = 0;
#ifdef MLP_TRAINING
return 0;
#endif
sample_max = celt_maxabs16(pcm, frame_size*channels);
sample_max = celt_maxabs_res(pcm, frame_size*channels);
#ifdef FIXED_POINT
silence = (sample_max == 0);
@@ -950,7 +1014,7 @@ int is_digital_silence(const opus_val16* pcm, int frame_size, int channels, int
}
#ifdef FIXED_POINT
static opus_val32 compute_frame_energy(const opus_val16 *pcm, int frame_size, int channels, int arch)
static opus_val32 compute_frame_energy(const opus_res *pcm, int frame_size, int channels, int arch)
{
int i;
opus_val32 sample_max;
@@ -960,7 +1024,7 @@ static opus_val32 compute_frame_energy(const opus_val16 *pcm, int frame_size, in
int len = frame_size*channels;
(void)arch;
/* Max amplitude in the signal */
sample_max = celt_maxabs16(pcm, len);
sample_max = RES2INT16(celt_maxabs_res(pcm, len));
/* Compute the right shift required in the MAC to avoid an overflow */
max_shift = celt_ilog2(len);
@@ -968,7 +1032,7 @@ static opus_val32 compute_frame_energy(const opus_val16 *pcm, int frame_size, in
/* Compute the energy */
for (i=0; i<len; i++)
energy += SHR32(MULT16_16(pcm[i], pcm[i]), shift);
energy += SHR32(MULT16_16(RES2INT16(pcm[i]), RES2INT16(pcm[i])), shift);
/* Normalize energy by the frame size and left-shift back to the original position */
energy /= len;
@@ -1042,7 +1106,7 @@ static int compute_redundancy_bytes(opus_int32 max_data_bytes, opus_int32 bitrat
return redundancy_bytes;
}
static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_res *pcm, int frame_size,
unsigned char *data, opus_int32 max_data_bytes,
int float_api, int first_frame,
#ifdef ENABLE_DRED
@@ -1054,7 +1118,7 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_val16 *pc
int redundancy, int celt_to_silk, int prefill,
opus_int32 equiv_rate, int to_celt);
opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
opus_int32 opus_encode_native(OpusEncoder *st, const opus_res *pcm, int frame_size,
unsigned char *data, opus_int32 out_data_bytes, int lsb_depth,
const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2,
int analysis_channels, downmix_func downmix, int float_api)
@@ -1562,6 +1626,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
unsigned char *curr_data;
int tmp_len;
int dtx_count = 0;
int bak_to_mono;
if (st->mode == MODE_SILK_ONLY)
{
@@ -1606,7 +1671,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
opus_repacketizer_init(rp);
int bak_to_mono = st->silk_mode.toMono;
bak_to_mono = st->silk_mode.toMono;
if (bak_to_mono)
st->force_channels = 1;
else
@@ -1695,7 +1760,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
}
}
static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_res *pcm, int frame_size,
unsigned char *data, opus_int32 max_data_bytes,
int float_api, int first_frame,
#ifdef ENABLE_DRED
@@ -1728,8 +1793,8 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_val16 *pc
int delay_compensation;
int total_buffer;
opus_int activity = VAD_NO_DECISION;
VARDECL(opus_val16, pcm_buf);
VARDECL(opus_val16, tmp_prefill);
VARDECL(opus_res, pcm_buf);
VARDECL(opus_res, tmp_prefill);
SAVE_STACK;
st->rangeFinal = 0;
@@ -1790,7 +1855,7 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_val16 *pc
ec_enc_init(&enc, data, max_data_bytes-1);
ALLOC(pcm_buf, (total_buffer+frame_size)*st->channels, opus_val16);
ALLOC(pcm_buf, (total_buffer+frame_size)*st->channels, opus_res);
OPUS_COPY(pcm_buf, &st->delay_buffer[(st->encoder_buffer-total_buffer)*st->channels], total_buffer*st->channels);
if (st->mode == MODE_CELT_ONLY)
@@ -1866,12 +1931,7 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_val16 *pc
if (st->mode != MODE_CELT_ONLY)
{
opus_int32 total_bitRate, celt_rate;
#ifdef FIXED_POINT
const opus_int16 *pcm_silk;
#else
VARDECL(opus_int16, pcm_silk);
ALLOC(pcm_silk, st->channels*frame_size, opus_int16);
#endif
const opus_res *pcm_silk;
/* Distribute bits between SILK and CELT */
total_bitRate = 8 * bytes_target * frame_rate;
@@ -1895,7 +1955,7 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_val16 *pc
if (st->energy_masking && st->use_vbr && !st->lfe)
{
opus_val32 mask_sum=0;
opus_val16 masking_depth;
celt_glog masking_depth;
opus_int32 rate_offset;
int c;
int end = 17;
@@ -1913,18 +1973,18 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_val16 *pc
{
for(i=0;i<end;i++)
{
opus_val16 mask;
mask = MAX16(MIN16(st->energy_masking[21*c+i],
QCONST16(.5f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT));
celt_glog mask;
mask = MAXG(MING(st->energy_masking[21*c+i],
GCONST(.5f)), -GCONST(2.0f));
if (mask > 0)
mask = HALF16(mask);
mask = HALF32(mask);
mask_sum += mask;
}
}
/* Conservative rate reduction, we cut the masking in half */
masking_depth = mask_sum / end*st->channels;
masking_depth += QCONST16(.2f, DB_SHIFT);
rate_offset = (opus_int32)PSHR32(MULT16_16(srate, masking_depth), DB_SHIFT);
masking_depth += GCONST(.2f);
rate_offset = (opus_int32)PSHR32(MULT16_16(srate, SHR32(masking_depth, DB_SHIFT-10)), 10);
rate_offset = MAX32(rate_offset, -2*st->silk_mode.bitRate/3);
/* Split the rate change between the SILK and CELT part for hybrid. */
if (st->bandwidth==OPUS_BANDWIDTH_SUPERWIDEBAND || st->bandwidth==OPUS_BANDWIDTH_FULLBAND)
@@ -2024,23 +2084,13 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_val16 *pc
gain_fade(st->delay_buffer+prefill_offset, st->delay_buffer+prefill_offset,
0, Q15ONE, celt_mode->overlap, st->Fs/400, st->channels, celt_mode->window, st->Fs);
OPUS_CLEAR(st->delay_buffer, prefill_offset);
#ifdef FIXED_POINT
pcm_silk = st->delay_buffer;
#else
for (i=0;i<st->encoder_buffer*st->channels;i++)
pcm_silk[i] = FLOAT2INT16(st->delay_buffer[i]);
#endif
silk_Encode( silk_enc, &st->silk_mode, pcm_silk, st->encoder_buffer, NULL, &zero, prefill, activity );
/* Prevent a second switch in the real encode call. */
st->silk_mode.opusCanSwitch = 0;
}
#ifdef FIXED_POINT
pcm_silk = pcm_buf+total_buffer*st->channels;
#else
for (i=0;i<frame_size*st->channels;i++)
pcm_silk[i] = FLOAT2INT16(pcm_buf[total_buffer*st->channels + i]);
#endif
ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0, activity );
if( ret ) {
/*fprintf (stderr, "SILK encode error: %d\n", ret);*/
@@ -2115,7 +2165,7 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_val16 *pc
celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(celt_pred));
}
ALLOC(tmp_prefill, st->channels*st->Fs/400, opus_val16);
ALLOC(tmp_prefill, st->channels*st->Fs/400, opus_res);
if (st->mode != MODE_SILK_ONLY && st->mode != st->prev_mode && st->prev_mode > 0)
{
OPUS_COPY(tmp_prefill, &st->delay_buffer[(st->encoder_buffer-total_buffer-st->Fs/400)*st->channels], st->channels*st->Fs/400);
@@ -2458,50 +2508,24 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_val16 *pc
return ret;
}
#ifdef FIXED_POINT
#ifndef DISABLE_FLOAT_API
opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size,
#if defined(FIXED_POINT) && !defined(ENABLE_RES24)
opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size,
unsigned char *data, opus_int32 max_data_bytes)
{
int i, ret;
int frame_size;
VARDECL(opus_int16, in);
ALLOC_STACK;
frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
if (frame_size <= 0)
{
RESTORE_STACK;
return OPUS_BAD_ARG;
}
ALLOC(in, frame_size*st->channels, opus_int16);
for (i=0;i<frame_size*st->channels;i++)
in[i] = FLOAT2INT16(pcm[i]);
ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16,
pcm, analysis_frame_size, 0, -2, st->channels, downmix_float, 1);
RESTORE_STACK;
return ret;
}
#endif
opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size,
unsigned char *data, opus_int32 out_data_bytes)
{
int frame_size;
frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 16,
return opus_encode_native(st, pcm, frame_size, data, max_data_bytes, 16,
pcm, analysis_frame_size, 0, -2, st->channels, downmix_int, 0);
}
#else
opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size,
unsigned char *data, opus_int32 max_data_bytes)
{
int i, ret;
int frame_size;
VARDECL(float, in);
VARDECL(opus_res, in);
ALLOC_STACK;
frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
@@ -2510,23 +2534,90 @@ opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_fram
RESTORE_STACK;
return OPUS_BAD_ARG;
}
ALLOC(in, frame_size*st->channels, float);
ALLOC(in, frame_size*st->channels, opus_res);
for (i=0;i<frame_size*st->channels;i++)
in[i] = (1.0f/32768)*pcm[i];
in[i] = INT16TORES(pcm[i]);
ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16,
pcm, analysis_frame_size, 0, -2, st->channels, downmix_int, 0);
pcm, analysis_frame_size, 0, -2, st->channels, downmix_int, 1);
RESTORE_STACK;
return ret;
}
#endif
#if defined(FIXED_POINT) && defined(ENABLE_RES24)
opus_int32 opus_encode24(OpusEncoder *st, const opus_int32 *pcm, int analysis_frame_size,
unsigned char *data, opus_int32 max_data_bytes)
{
int frame_size;
frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
return opus_encode_native(st, pcm, frame_size, data, max_data_bytes, MAX_ENCODING_DEPTH,
pcm, analysis_frame_size, 0, -2, st->channels, downmix_int24, 0);
}
#else
opus_int32 opus_encode24(OpusEncoder *st, const opus_int32 *pcm, int analysis_frame_size,
unsigned char *data, opus_int32 max_data_bytes)
{
int i, ret;
int frame_size;
VARDECL(opus_res, in);
ALLOC_STACK;
frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
if (frame_size <= 0)
{
RESTORE_STACK;
return OPUS_BAD_ARG;
}
ALLOC(in, frame_size*st->channels, opus_res);
for (i=0;i<frame_size*st->channels;i++)
in[i] = INT24TORES(pcm[i]);
ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, MAX_ENCODING_DEPTH,
pcm, analysis_frame_size, 0, -2, st->channels, downmix_int24, 1);
RESTORE_STACK;
return ret;
}
#endif
#ifndef DISABLE_FLOAT_API
# if !defined(FIXED_POINT)
opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size,
unsigned char *data, opus_int32 out_data_bytes)
{
int frame_size;
frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 24,
return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, MAX_ENCODING_DEPTH,
pcm, analysis_frame_size, 0, -2, st->channels, downmix_float, 1);
}
# else
opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size,
unsigned char *data, opus_int32 max_data_bytes)
{
int i, ret;
int frame_size;
VARDECL(opus_res, in);
ALLOC_STACK;
frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
if (frame_size <= 0)
{
RESTORE_STACK;
return OPUS_BAD_ARG;
}
ALLOC(in, frame_size*st->channels, opus_res);
for (i=0;i<frame_size*st->channels;i++)
in[i] = FLOAT2RES(pcm[i]);
ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, MAX_ENCODING_DEPTH,
pcm, analysis_frame_size, 0, -2, st->channels, downmix_float, 1);
RESTORE_STACK;
return ret;
}
# endif
#endif
@@ -3014,7 +3105,7 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
break;
case OPUS_SET_ENERGY_MASK_REQUEST:
{
opus_val16 *value = va_arg(ap, opus_val16*);
celt_glog *value = va_arg(ap, celt_glog*);
st->energy_masking = value;
ret = celt_encoder_ctl(celt_enc, OPUS_SET_ENERGY_MASK(value));
}

View File

@@ -193,7 +193,7 @@ int opus_multistream_decode_native(
int s, c;
char *ptr;
int do_plc=0;
VARDECL(opus_val16, buf);
VARDECL(opus_res, buf);
ALLOC_STACK;
VALIDATE_MS_DECODER(st);
@@ -205,7 +205,7 @@ int opus_multistream_decode_native(
/* Limit frame_size to avoid excessive stack allocations. */
MUST_SUCCEED(opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs)));
frame_size = IMIN(frame_size, Fs/25*3);
ALLOC(buf, 2*frame_size, opus_val16);
ALLOC(buf, 2*frame_size, opus_res);
ptr = (char*)st + align(sizeof(OpusMSDecoder));
coupled_size = opus_decoder_get_size(2);
mono_size = opus_decoder_get_size(1);
@@ -311,7 +311,7 @@ static void opus_copy_channel_out_float(
void *dst,
int dst_stride,
int dst_channel,
const opus_val16 *src,
const opus_res *src,
int src_stride,
int frame_size,
void *user_data
@@ -324,11 +324,7 @@ static void opus_copy_channel_out_float(
if (src != NULL)
{
for (i=0;i<frame_size;i++)
#if defined(FIXED_POINT)
float_dst[i*dst_stride+dst_channel] = (1/32768.f)*src[i*src_stride];
#else
float_dst[i*dst_stride+dst_channel] = src[i*src_stride];
#endif
float_dst[i*dst_stride+dst_channel] = RES2FLOAT(src[i*src_stride]);
}
else
{
@@ -342,7 +338,7 @@ static void opus_copy_channel_out_short(
void *dst,
int dst_stride,
int dst_channel,
const opus_val16 *src,
const opus_res *src,
int src_stride,
int frame_size,
void *user_data
@@ -355,11 +351,7 @@ static void opus_copy_channel_out_short(
if (src != NULL)
{
for (i=0;i<frame_size;i++)
#if defined(FIXED_POINT)
short_dst[i*dst_stride+dst_channel] = src[i*src_stride];
#else
short_dst[i*dst_stride+dst_channel] = FLOAT2INT16(src[i*src_stride]);
#endif
short_dst[i*dst_stride+dst_channel] = RES2INT16(src[i*src_stride]);
}
else
{
@@ -368,9 +360,38 @@ static void opus_copy_channel_out_short(
}
}
static void opus_copy_channel_out_int24(
void *dst,
int dst_stride,
int dst_channel,
const opus_res *src,
int src_stride,
int frame_size,
void *user_data
)
{
opus_int32 *short_dst;
opus_int32 i;
(void)user_data;
short_dst = (opus_int32*)dst;
if (src != NULL)
{
for (i=0;i<frame_size;i++)
short_dst[i*dst_stride+dst_channel] = RES2INT24(src[i*src_stride]);
}
else
{
for (i=0;i<frame_size;i++)
short_dst[i*dst_stride+dst_channel] = 0;
}
}
#ifdef FIXED_POINT
#define OPTIONAL_CLIP 0
#else
#define OPTIONAL_CLIP 1
#endif
int opus_multistream_decode(
OpusMSDecoder *st,
const unsigned char *data,
@@ -381,7 +402,20 @@ int opus_multistream_decode(
)
{
return opus_multistream_decode_native(st, data, len,
pcm, opus_copy_channel_out_short, frame_size, decode_fec, 0, NULL);
pcm, opus_copy_channel_out_short, frame_size, decode_fec, OPTIONAL_CLIP, NULL);
}
int opus_multistream_decode24(
OpusMSDecoder *st,
const unsigned char *data,
opus_int32 len,
opus_int32 *pcm,
int frame_size,
int decode_fec
)
{
return opus_multistream_decode_native(st, data, len,
pcm, opus_copy_channel_out_int24, frame_size, decode_fec, 0, NULL);
}
#ifndef DISABLE_FLOAT_API
@@ -393,29 +427,6 @@ int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
}
#endif
#else
int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
{
return opus_multistream_decode_native(st, data, len,
pcm, opus_copy_channel_out_short, frame_size, decode_fec, 1, NULL);
}
int opus_multistream_decode_float(
OpusMSDecoder *st,
const unsigned char *data,
opus_int32 len,
opus_val16 *pcm,
int frame_size,
int decode_fec
)
{
return opus_multistream_decode_native(st, data, len,
pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0, NULL);
}
#endif
int opus_multistream_decoder_ctl_va_list(OpusMSDecoder *st, int request,
va_list ap)
{

View File

@@ -184,35 +184,35 @@ static void channel_pos(int channels, int pos[8])
#if 1
/* Computes a rough approximation of log2(2^a + 2^b) */
static opus_val16 logSum(opus_val16 a, opus_val16 b)
static opus_val16 logSum(celt_glog a, celt_glog b)
{
opus_val16 max;
opus_val32 diff;
opus_val16 frac;
static const opus_val16 diff_table[17] = {
QCONST16(0.5000000f, DB_SHIFT), QCONST16(0.2924813f, DB_SHIFT), QCONST16(0.1609640f, DB_SHIFT), QCONST16(0.0849625f, DB_SHIFT),
QCONST16(0.0437314f, DB_SHIFT), QCONST16(0.0221971f, DB_SHIFT), QCONST16(0.0111839f, DB_SHIFT), QCONST16(0.0056136f, DB_SHIFT),
QCONST16(0.0028123f, DB_SHIFT)
celt_glog max;
celt_glog diff;
celt_glog frac;
static const celt_glog diff_table[17] = {
GCONST(0.5000000f), GCONST(0.2924813f), GCONST(0.1609640f), GCONST(0.0849625f),
GCONST(0.0437314f), GCONST(0.0221971f), GCONST(0.0111839f), GCONST(0.0056136f),
GCONST(0.0028123f)
};
int low;
if (a>b)
{
max = a;
diff = SUB32(EXTEND32(a),EXTEND32(b));
diff = SUB32(a,b);
} else {
max = b;
diff = SUB32(EXTEND32(b),EXTEND32(a));
diff = SUB32(b,a);
}
if (!(diff < QCONST16(8.f, DB_SHIFT))) /* inverted to catch NaNs */
if (!(diff < GCONST(8.f))) /* inverted to catch NaNs */
return max;
#ifdef FIXED_POINT
low = SHR32(diff, DB_SHIFT-1);
frac = SHL16(diff - SHL16(low, DB_SHIFT-1), 16-DB_SHIFT);
frac = VSHR32(diff - SHL32(low, DB_SHIFT-1), DB_SHIFT-16);
#else
low = (int)floor(2*diff);
frac = 2*diff - low;
#endif
return max + diff_table[low] + MULT16_16_Q15(frac, SUB16(diff_table[low+1], diff_table[low]));
return max + diff_table[low] + MULT16_32_Q15(frac, SUB32(diff_table[low+1], diff_table[low]));
}
#else
opus_val16 logSum(opus_val16 a, opus_val16 b)
@@ -221,7 +221,7 @@ opus_val16 logSum(opus_val16 a, opus_val16 b)
}
#endif
void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem,
void surround_analysis(const CELTMode *celt_mode, const void *pcm, celt_glog *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem,
int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in, int arch
)
{
@@ -234,9 +234,9 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
int freq_size;
opus_val16 channel_offset;
opus_val32 bandE[21];
opus_val16 maskLogE[3][21];
celt_glog maskLogE[3][21];
VARDECL(opus_val32, in);
VARDECL(opus_val16, x);
VARDECL(opus_res, x);
VARDECL(opus_val32, freq);
SAVE_STACK;
@@ -250,14 +250,14 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
break;
ALLOC(in, frame_size+overlap, opus_val32);
ALLOC(x, len, opus_val16);
ALLOC(x, len, opus_res);
ALLOC(freq, freq_size, opus_val32);
channel_pos(channels, pos);
for (c=0;c<3;c++)
for (i=0;i<21;i++)
maskLogE[c][i] = -QCONST16(28.f, DB_SHIFT);
maskLogE[c][i] = -GCONST(28.f);
for (c=0;c<channels;c++)
{
@@ -303,9 +303,9 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);
/* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */
for (i=1;i<21;i++)
bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i-1]-QCONST16(1.f, DB_SHIFT));
bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i-1]-GCONST(1.f));
for (i=19;i>=0;i--)
bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i+1]-QCONST16(2.f, DB_SHIFT));
bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i+1]-GCONST(2.f));
if (pos[c]==1)
{
for (i=0;i<21;i++)
@@ -318,8 +318,8 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
{
for (i=0;i<21;i++)
{
maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));
maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));
maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-GCONST(.5f));
maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-GCONST(.5f));
}
}
#if 0
@@ -347,7 +347,7 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
#endif
for (c=0;c<channels;c++)
{
opus_val16 *mask;
celt_glog *mask;
if (pos[c]!=0)
{
mask = &maskLogE[pos[c]-1][0];
@@ -819,14 +819,14 @@ int opus_multistream_encode_native
int s;
char *ptr;
int tot_size;
VARDECL(opus_val16, buf);
VARDECL(opus_val16, bandSMR);
VARDECL(opus_res, buf);
VARDECL(celt_glog, bandSMR);
unsigned char tmp_data[MS_FRAME_TMP];
OpusRepacketizer rp;
opus_int32 vbr;
const CELTMode *celt_mode;
opus_int32 bitrates[256];
opus_val16 bandLogE[42];
celt_glog bandLogE[42];
opus_val32 *mem = NULL;
opus_val32 *preemph_mem=NULL;
int frame_size;
@@ -862,11 +862,11 @@ int opus_multistream_encode_native
RESTORE_STACK;
return OPUS_BUFFER_TOO_SMALL;
}
ALLOC(buf, 2*frame_size, opus_val16);
ALLOC(buf, 2*frame_size, opus_res);
coupled_size = opus_encoder_get_size(2);
mono_size = opus_encoder_get_size(1);
ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16);
ALLOC(bandSMR, 21*st->layout.nb_channels, celt_glog);
if (st->mapping_type == MAPPING_TYPE_SURROUND)
{
surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, 120, st->layout.nb_channels, Fs, copy_channel_in, st->arch);
@@ -1014,7 +1014,7 @@ int opus_multistream_encode_native
#if !defined(DISABLE_FLOAT_API)
static void opus_copy_channel_in_float(
opus_val16 *dst,
opus_res *dst,
int dst_stride,
const void *src,
int src_stride,
@@ -1028,16 +1028,12 @@ static void opus_copy_channel_in_float(
(void)user_data;
float_src = (const float *)src;
for (i=0;i<frame_size;i++)
#if defined(FIXED_POINT)
dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
#else
dst[i*dst_stride] = float_src[i*src_stride+src_channel];
#endif
dst[i*dst_stride] = FLOAT2RES(float_src[i*src_stride+src_channel]);
}
#endif
static void opus_copy_channel_in_short(
opus_val16 *dst,
opus_res *dst,
int dst_stride,
const void *src,
int src_stride,
@@ -1051,54 +1047,25 @@ static void opus_copy_channel_in_short(
(void)user_data;
short_src = (const opus_int16 *)src;
for (i=0;i<frame_size;i++)
#if defined(FIXED_POINT)
dst[i*dst_stride] = short_src[i*src_stride+src_channel];
#else
dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
#endif
dst[i*dst_stride] = INT16TORES(short_src[i*src_stride+src_channel]);
}
#ifdef FIXED_POINT
int opus_multistream_encode(
OpusMSEncoder *st,
const opus_val16 *pcm,
static void opus_copy_channel_in_int24(
opus_res *dst,
int dst_stride,
const void *src,
int src_stride,
int src_channel,
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
void *user_data
)
{
return opus_multistream_encode_native(st, opus_copy_channel_in_short,
pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL);
}
#ifndef DISABLE_FLOAT_API
int opus_multistream_encode_float(
OpusMSEncoder *st,
const float *pcm,
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
)
{
return opus_multistream_encode_native(st, opus_copy_channel_in_float,
pcm, frame_size, data, max_data_bytes, 16, downmix_float, 1, NULL);
}
#endif
#else
int opus_multistream_encode_float
(
OpusMSEncoder *st,
const opus_val16 *pcm,
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
)
{
return opus_multistream_encode_native(st, opus_copy_channel_in_float,
pcm, frame_size, data, max_data_bytes, 24, downmix_float, 1, NULL);
const opus_int32 *short_src;
opus_int32 i;
(void)user_data;
short_src = (const opus_int32 *)src;
for (i=0;i<frame_size;i++)
dst[i*dst_stride] = INT24TORES(short_src[i*src_stride+src_channel]);
}
int opus_multistream_encode(
@@ -1112,6 +1079,31 @@ int opus_multistream_encode(
return opus_multistream_encode_native(st, opus_copy_channel_in_short,
pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL);
}
int opus_multistream_encode24(
OpusMSEncoder *st,
const opus_int32 *pcm,
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
)
{
return opus_multistream_encode_native(st, opus_copy_channel_in_int24,
pcm, frame_size, data, max_data_bytes, MAX_ENCODING_DEPTH, downmix_int24, 0, NULL);
}
#ifndef DISABLE_FLOAT_API
int opus_multistream_encode_float(
OpusMSEncoder *st,
const float *pcm,
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
)
{
return opus_multistream_encode_native(st, opus_copy_channel_in_float,
pcm, frame_size, data, max_data_bytes, MAX_ENCODING_DEPTH, downmix_float, 1, NULL);
}
#endif
int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request,

View File

@@ -125,7 +125,7 @@ int get_right_channel(const ChannelLayout *layout, int stream_id, int prev);
int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev);
typedef void (*opus_copy_channel_in_func)(
opus_val16 *dst,
opus_res *dst,
int dst_stride,
const void *src,
int src_stride,
@@ -138,7 +138,7 @@ typedef void (*opus_copy_channel_out_func)(
void *dst,
int dst_stride,
int dst_channel,
const opus_val16 *src,
const opus_res *src,
int src_stride,
int frame_size,
void *user_data
@@ -174,19 +174,20 @@ typedef void (*opus_copy_channel_out_func)(
typedef void (*downmix_func)(const void *, opus_val32 *, int, int, int, int, int);
void downmix_float(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C);
void downmix_int(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C);
int is_digital_silence(const opus_val16* pcm, int frame_size, int channels, int lsb_depth);
void downmix_int24(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C);
int is_digital_silence(const opus_res* pcm, int frame_size, int channels, int lsb_depth);
int encode_size(int size, unsigned char *data);
opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs);
opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
opus_int32 opus_encode_native(OpusEncoder *st, const opus_res *pcm, int frame_size,
unsigned char *data, opus_int32 out_data_bytes, int lsb_depth,
const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2,
int analysis_channels, downmix_func downmix, int float_api);
int opus_decode_native(OpusDecoder *st, const unsigned char *data, opus_int32 len,
opus_val16 *pcm, int frame_size, int decode_fec, int self_delimited,
opus_res *pcm, int frame_size, int decode_fec, int self_delimited,
opus_int32 *packet_offset, int soft_clip, const OpusDRED *dred, opus_int32 dred_offset);
/* Make sure everything is properly aligned. */

View File

@@ -49,7 +49,7 @@ static void opus_projection_copy_channel_out_float(
void *dst,
int dst_stride,
int dst_channel,
const opus_val16 *src,
const opus_res *src,
int src_stride,
int frame_size,
void *user_data)
@@ -72,7 +72,7 @@ static void opus_projection_copy_channel_out_short(
void *dst,
int dst_stride,
int dst_channel,
const opus_val16 *src,
const opus_res *src,
int src_stride,
int frame_size,
void *user_data)
@@ -89,6 +89,27 @@ static void opus_projection_copy_channel_out_short(
src_stride, short_dst, dst_stride, frame_size);
}
static void opus_projection_copy_channel_out_int24(
void *dst,
int dst_stride,
int dst_channel,
const opus_res *src,
int src_stride,
int frame_size,
void *user_data)
{
opus_int32 *short_dst;
const MappingMatrix *matrix;
short_dst = (opus_int32 *)dst;
matrix = (const MappingMatrix *)user_data;
if (dst_channel == 0)
OPUS_CLEAR(short_dst, frame_size * dst_stride);
if (src != NULL)
mapping_matrix_multiply_channel_out_int24(matrix, src, dst_channel,
src_stride, short_dst, dst_stride, frame_size);
}
static MappingMatrix *get_dec_demixing_matrix(OpusProjectionDecoder *st)
{
/* void* cast avoids clang -Wcast-align warning */
@@ -210,24 +231,28 @@ OpusProjectionDecoder *opus_projection_decoder_create(
}
#ifdef FIXED_POINT
int opus_projection_decode(OpusProjectionDecoder *st, const unsigned char *data,
opus_int32 len, opus_int16 *pcm, int frame_size,
int decode_fec)
{
return opus_multistream_decode_native(get_multistream_decoder(st), data, len,
pcm, opus_projection_copy_channel_out_short, frame_size, decode_fec, 0,
get_dec_demixing_matrix(st));
}
#define OPTIONAL_CLIP 0
#else
#define OPTIONAL_CLIP 1
#endif
int opus_projection_decode(OpusProjectionDecoder *st, const unsigned char *data,
opus_int32 len, opus_int16 *pcm, int frame_size,
int decode_fec)
{
return opus_multistream_decode_native(get_multistream_decoder(st), data, len,
pcm, opus_projection_copy_channel_out_short, frame_size, decode_fec, 1,
pcm, opus_projection_copy_channel_out_short, frame_size, decode_fec, OPTIONAL_CLIP,
get_dec_demixing_matrix(st));
}
int opus_projection_decode24(OpusProjectionDecoder *st, const unsigned char *data,
opus_int32 len, opus_int32 *pcm, int frame_size,
int decode_fec)
{
return opus_multistream_decode_native(get_multistream_decoder(st), data, len,
pcm, opus_projection_copy_channel_out_int24, frame_size, decode_fec, 0,
get_dec_demixing_matrix(st));
}
#endif
#ifndef DISABLE_FLOAT_API
int opus_projection_decode_float(OpusProjectionDecoder *st, const unsigned char *data,

View File

@@ -47,7 +47,7 @@ struct OpusProjectionEncoder
#if !defined(DISABLE_FLOAT_API)
static void opus_projection_copy_channel_in_float(
opus_val16 *dst,
opus_res *dst,
int dst_stride,
const void *src,
int src_stride,
@@ -62,7 +62,7 @@ static void opus_projection_copy_channel_in_float(
#endif
static void opus_projection_copy_channel_in_short(
opus_val16 *dst,
opus_res *dst,
int dst_stride,
const void *src,
int src_stride,
@@ -75,6 +75,20 @@ static void opus_projection_copy_channel_in_short(
(const opus_int16*)src, src_stride, dst, src_channel, dst_stride, frame_size);
}
static void opus_projection_copy_channel_in_int24(
opus_res *dst,
int dst_stride,
const void *src,
int src_stride,
int src_channel,
int frame_size,
void *user_data
)
{
mapping_matrix_multiply_channel_in_int24((const MappingMatrix*)user_data,
(const opus_int32*)src, src_stride, dst, src_channel, dst_stride, frame_size);
}
static int get_order_plus_one_from_channels(int channels, int *order_plus_one)
{
int order_plus_one_;
@@ -392,26 +406,24 @@ int opus_projection_encode(OpusProjectionEncoder *st, const opus_int16 *pcm,
max_data_bytes, 16, downmix_int, 0, get_mixing_matrix(st));
}
int opus_projection_encode24(OpusProjectionEncoder *st, const opus_int32 *pcm,
int frame_size, unsigned char *data,
opus_int32 max_data_bytes)
{
return opus_multistream_encode_native(get_multistream_encoder(st),
opus_projection_copy_channel_in_int24, pcm, frame_size, data,
max_data_bytes, MAX_ENCODING_DEPTH, downmix_int, 0, get_mixing_matrix(st));
}
#ifndef DISABLE_FLOAT_API
#ifdef FIXED_POINT
int opus_projection_encode_float(OpusProjectionEncoder *st, const float *pcm,
int frame_size, unsigned char *data,
opus_int32 max_data_bytes)
{
return opus_multistream_encode_native(get_multistream_encoder(st),
opus_projection_copy_channel_in_float, pcm, frame_size, data,
max_data_bytes, 16, downmix_float, 1, get_mixing_matrix(st));
max_data_bytes, MAX_ENCODING_DEPTH, downmix_float, 1, get_mixing_matrix(st));
}
#else
int opus_projection_encode_float(OpusProjectionEncoder *st, const float *pcm,
int frame_size, unsigned char *data,
opus_int32 max_data_bytes)
{
return opus_multistream_encode_native(get_multistream_encoder(st),
opus_projection_copy_channel_in_float, pcm, frame_size, data,
max_data_bytes, 24, downmix_float, 1, get_mixing_matrix(st));
}
#endif
#endif
void opus_projection_encoder_destroy(OpusProjectionEncoder *st)

View File

@@ -158,10 +158,10 @@ opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int
/* incorporate any extensions from the repacketizer padding */
for (i=begin;i<end;i++)
{
int j;
int j, ret;
opus_int32 frame_ext_count;
frame_ext_count = total_ext_count - ext_count;
int ret = opus_packet_extensions_parse(rp->paddings[i], rp->padding_len[i],
ret = opus_packet_extensions_parse(rp->paddings[i], rp->padding_len[i],
&all_extensions[ext_count], &frame_ext_count, rp->padding_nb_frames[i]);
if (ret<0)
{