Support 32-bit window and comb filter
Some checks failed
Autotools / AutoMake/Linux/GCC (push) Has been cancelled
Autotools / AutoMake/Linux/GCC/EnableDNN (push) Has been cancelled
Autotools / AutoMake/Linux/GCC/EnableCustomModes (push) Has been cancelled
Autotools / AutoMake/Linux/GCC/EnableAssertions (push) Has been cancelled
CMake / Test build with CMake 3.16.0 (push) Has been cancelled
CMake / CMake MINGW (push) Has been cancelled
CMake / CMake/Linux/Lib/X64/Release (push) Has been cancelled
CMake / CMake/MacOSX/Lib/X64/Release (push) Has been cancelled
CMake / CMake/MacOSX/Framework/X64/Release (push) Has been cancelled
CMake / CMake/Linux/So/X64/Release (push) Has been cancelled
CMake / CMake/MacOSX/So/X64/Release (push) Has been cancelled
CMake / CMake/Android/So/ARMv8/Release (push) Has been cancelled
CMake / CMake/Android/Lib/ARMv8/Release (push) Has been cancelled
CMake / CMake/Android/So/X86/Release (push) Has been cancelled
CMake / CMake/Android/Lib/X86/Release (push) Has been cancelled
CMake / CMake/Android/So/X64/Release (push) Has been cancelled
CMake / CMake/Android/Lib/X64/Release (push) Has been cancelled
CMake / CMake/AssertionsFuzz/Linux/Lib/X64/Release (push) Has been cancelled
CMake / CMake/AssertionsFuzz/MacOSX/Lib/X64/Release (push) Has been cancelled
CMake / CMake/CustomModes/Linux/Lib/X64/Release (push) Has been cancelled
CMake / CMake/iOS/Framework/arm64/Release (push) Has been cancelled
CMake / CMake/iOS/Dll/arm64/Release (push) Has been cancelled
CMake / CMake/iOS/Lib/arm64/Release (push) Has been cancelled
CMake / CMake/Windows/Dll/ARMv8/Release (push) Has been cancelled
CMake / CMake/Windows/Lib/armv8/Release (push) Has been cancelled
CMake / CMake/Windows/Dll/X64/Release (push) Has been cancelled
CMake / CMake/Windows/Dll/X86/Release (push) Has been cancelled
CMake / CMake/AssertionsFuzz/Windows/Lib/X64/Release (push) Has been cancelled
CMake / CMake/Windows/Lib/X64/Release (push) Has been cancelled
CMake / CMake/Windows/Lib/X86/Release (push) Has been cancelled
DRED / CMake/Android/Lib/ARMv8/Release (push) Has been cancelled
DRED / CMake/Android/Lib/X64/Release (push) Has been cancelled
DRED / CMake/MacOSX/Lib/X64/Release (push) Has been cancelled
DRED / CMake/Linux/Lib/X64/Release (push) Has been cancelled
DRED / CMake/iOS/Lib/arm64/Release (push) Has been cancelled
DRED / CMake/Windows/Lib/armv8/Release (push) Has been cancelled
DRED / CMake/Windows/Lib/X64/Release (push) Has been cancelled
DRED / AutoTools/Linux/Clang (push) Has been cancelled
DRED / AutoTools/Linux/GCC (push) Has been cancelled
Repository / Check trailing white spaces (push) Has been cancelled

This commit is contained in:
Jean-Marc Valin 2024-05-28 13:03:10 -04:00
parent 88544c4abe
commit 0de8c2630f
No known key found for this signature in database
GPG key ID: 8D2952BBB52C646D
17 changed files with 160 additions and 81 deletions

View file

@ -175,8 +175,20 @@ typedef opus_val16 opus_res;
#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
@ -265,6 +277,8 @@ static OPUS_INLINE int celt_isnan(float x)
#define Q15ONE 1.0f
#define Q31ONE 1.0f
#define COEF_ONE 1.0f
#define COEF2VAL16(x) (x)
#define NORM_SCALING 1.f
@ -321,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))
@ -332,6 +347,10 @@ 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))

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"
@ -236,7 +237,7 @@ void celt_preemphasis(const opus_res * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTR
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);

View file

@ -535,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);
}
@ -692,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;
@ -880,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]);
}

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

@ -99,9 +99,19 @@ void dump_modes(FILE *file, CELTMode **modes, int nb_modes)
fprintf(file, "#ifndef DEF_WINDOW%d\n", mode->overlap);
fprintf(file, "#define DEF_WINDOW%d\n", mode->overlap);
fprintf (file, "static const opus_val16 window%d[%d] = {\n", mode->overlap, mode->overlap);
fprintf (file, "static const celt_coef window%d[%d] = {\n", mode->overlap, mode->overlap);
#if defined(FIXED_POINT) && defined(ENABLE_QEXT)
fprintf(file, "#ifdef ENABLE_QEXT\n");
for (j=0;j<mode->overlap;j++)
fprintf (file, WORD32 ",%c", mode->window[j],(j+6)%5==0?'\n':' ');
fprintf(file, "#else\n");
for (j=0;j<mode->overlap;j++)
fprintf (file, WORD16 ",%c", COEF16(mode->window[j], 16),(j+6)%5==0?'\n':' ');
fprintf(file, "#endif\n");
#else
for (j=0;j<mode->overlap;j++)
fprintf (file, WORD16 ",%c", mode->window[j],(j+6)%5==0?'\n':' ');
#endif
fprintf (file, "};\n");
fprintf(file, "#endif\n");
fprintf(file, "\n");

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

View file

@ -71,6 +71,13 @@
#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))))

View file

@ -120,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;
@ -159,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;
@ -184,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;
@ -258,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;
@ -346,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

@ -67,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)
@ -83,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) \
@ -93,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,7 +370,7 @@ 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;
@ -378,8 +378,13 @@ CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error)
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

@ -11,7 +11,33 @@
#ifndef DEF_WINDOW120
#define DEF_WINDOW120
static const opus_val16 window120[120] = {
static const celt_coef window120[120] = {
#ifdef ENABLE_QEXT
144497, 1300330, 3611201, 7075520, 11690888,
17454086, 24361057, 32406886, 41585775, 51891010,
63314937, 75848919, 89483305, 104207389, 120009370,
136876310, 154794092, 173747378, 193719571, 214692768,
236647730, 259563841, 283419076, 308189974, 333851610,
360377579, 387739975, 415909390, 444854905, 474544098,
504943052, 536016380, 567727246, 600037405, 632907246,
666295841, 700161014, 734459402, 769146541, 804176949,
839504226, 875081151, 910859801, 946791664, 982827766,
1018918806, 1055015289, 1091067669, 1127026498, 1162842572,
1198467087, 1233851789, 1268949131, 1303712427, 1338096005,
1372055357, 1405547287, 1438530057, 1470963523, 1502809271,
1534030739, 1564593342, 1594464576, 1623614127, 1652013955,
1679638381, 1706464157, 1732470523, 1757639262, 1781954728,
1805403878, 1827976281, 1849664119, 1870462176, 1890367815,
1909380945, 1927503971, 1944741740, 1961101474, 1976592691,
1991227121, 2005018606, 2017983003, 2030138066, 2041503334,
2052100005, 2061950805, 2071079860, 2079512552, 2087275383,
2094395834, 2100902217, 2106823531, 2112189320, 2117029526,
2121374346, 2125254091, 2128699048, 2131739342, 2134404803,
2136724837, 2138728300, 2140443379, 2141897477, 2143117096,
2144127739, 2144953806, 2145618501, 2146143740, 2146550076,
2146856617, 2147080957, 2147239112, 2147345466, 2147412715,
2147451824, 2147471990, 2147480610, 2147483253, 2147483642,
#else
2, 20, 55, 108, 178,
266, 372, 494, 635, 792,
966, 1157, 1365, 1590, 1831,
@ -36,6 +62,7 @@ static const opus_val16 window120[120] = {
32717, 32729, 32740, 32748, 32754,
32758, 32762, 32764, 32766, 32767,
32767, 32767, 32767, 32767, 32767,
#endif
};
#endif

View file

@ -109,7 +109,7 @@ void test1d(int nfft,int isinverse,int arch)
kiss_fft_scalar *in;
kiss_fft_scalar *in_copy;
kiss_fft_scalar *out;
opus_val16 *window;
celt_coef *window;
int k;
#ifdef CUSTOM_MODES
@ -133,14 +133,18 @@ void test1d(int nfft,int isinverse,int arch)
in = (kiss_fft_scalar*)malloc(buflen);
in_copy = (kiss_fft_scalar*)malloc(buflen);
out = (kiss_fft_scalar*)malloc(buflen);
window = (opus_val16*)malloc(sizeof(opus_val16)*nfft/2);
window = (celt_coef*)malloc(sizeof(*window)*nfft/2);
for (k=0;k<nfft;++k) {
in[k] = (rand() % 32768) - 16384;
}
for (k=0;k<nfft/2;++k) {
#ifdef ENABLE_QEXT
window[k] = Q31ONE;
#else
window[k] = Q15ONE;
#endif
}
for (k=0;k<nfft;++k) {
in[k] *= 32768;

View file

@ -205,7 +205,7 @@ OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
#ifdef ENABLE_RES24
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)
const celt_coef *window, opus_int32 Fs)
{
int i, c;
int inc = 48000/Fs;
@ -213,9 +213,9 @@ static void smooth_fade(const opus_res *in1, const opus_res *in2,
{
for (i=0;i<overlap;i++)
{
opus_val16 w = MULT16_16_Q15(window[i*inc], window[i*inc]);
out[i*channels+c] = ADD32(MULT16_32_Q15(w,in2[i*channels+c]),
MULT16_32_Q15(Q15ONE-w, in1[i*channels+c]));
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]));
}
}
}
@ -279,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;

View file

@ -513,7 +513,7 @@ static void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *ou
#endif
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 opus_val16 *window, opus_int32 Fs)
int overlap48, int frame_size, int channels, const celt_coef *window, opus_int32 Fs)
{
int i;
int overlap;
@ -526,7 +526,8 @@ static void stereo_fade(const opus_res *in, opus_res *out, opus_val16 g1, opus_v
{
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 = HALF32((opus_val32)in[i*channels] - (opus_val32)in[i*channels+1]);
@ -545,7 +546,7 @@ static void stereo_fade(const opus_res *in, opus_res *out, opus_val16 g1, opus_v
}
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 opus_val16 *window, opus_int32 Fs)
int overlap48, int frame_size, int channels, const celt_coef *window, opus_int32 Fs)
{
int i;
int inc;
@ -558,7 +559,8 @@ static void gain_fade(const opus_res *in, opus_res *out, opus_val16 g1, opus_val
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_RES_Q15(g, in[i]);
@ -567,7 +569,8 @@ static void gain_fade(const opus_res *in, opus_res *out, opus_val16 g1, opus_val
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_RES_Q15(g, in[i*2]);