ref: 49ca99efa524928080db0774eed01beba7be45e2
parent: bd43729ecdbbf6d37042d5a35f2b9decb4273aa0
author: Jean-Marc Valin <[email protected]>
date: Mon Feb 25 09:05:10 EST 2008
fixed-point: initial support for using the fixed-point MDCT (rest is still all float)
--- a/configure.ac
+++ b/configure.ac
@@ -88,6 +88,21 @@
AC_DEFINE_UNQUOTED(CELT_MICRO_VERSION, ${CELT_MICRO_VERSION}, [Version micro])
AC_DEFINE_UNQUOTED(CELT_EXTRA_VERSION, "${CELT_EXTRA_VERSION}", [Version extra])
+AC_ARG_ENABLE(fixed-point, [ --enable-fixed-point Compile as fixed-point],
+[if test "$enableval" = yes; then
+ AC_DEFINE([FIXED_POINT], , [Compile as fixed-point])
+ AC_DEFINE([DOUBLE_PRECISION], , [Compile as fixed-point])
+else
+ AC_DEFINE([FLOATING_POINT], , [Compile as floating-point])
+fi],
+AC_DEFINE([FLOATING_POINT], , [Compile as floating-point]))
+
+AC_ARG_ENABLE(fixed-point-debug, [ --enable-fixed-point-debug Debug fixed-point implementation],
+[if test "$enableval" = yes; then
+ AC_DEFINE([FIXED_DEBUG], , [Debug fixed-point implementation])
+fi])
+
+
AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
--- a/libcelt/_kiss_fft_guts.h
+++ b/libcelt/_kiss_fft_guts.h
@@ -81,11 +81,11 @@
# define smul(a,b) ( (SAMPPROD)(a)*(b) )
# define sround( x ) (kiss_fft_scalar)( ( (x) + ((SAMPPROD)1<<(FRACBITS-1)) ) >> FRACBITS )
-#if MIXED_PRECISION
+#ifdef MIXED_PRECISION
#undef MULT16_32_Q15
#define MULT16_16SU(a,b) ((celt_word32_t)(celt_word16_t)(a)*(celt_word32_t)(celt_uint16_t)(b))
-//#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))
+/*#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))*/
#define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15))
# define S_MUL(a,b) MULT16_32_Q15(b, a)
--- a/libcelt/arch.h
+++ b/libcelt/arch.h
@@ -51,10 +51,15 @@
typedef celt_int16_t celt_word16_t;
typedef celt_int32_t celt_word32_t;
+typedef float celt_sig_t;
+typedef float celt_norm_t;
+
#define Q15ONE 32767
#define LPC_SCALING 8192
-#define SIG_SCALING 16384
+#define SIG_SCALING 16384.f
+#define SIG_SCALING_1 0.000061035
+
#define LSP_SCALING 8192.
#define GAMMA_SCALING 32768.
#define GAIN_SCALING 64
@@ -99,6 +104,7 @@
#define Q15ONE 1.0f
#define LPC_SCALING 1.f
#define SIG_SCALING 1.f
+#define SIG_SCALING_1 1.f
#define LSP_SCALING 1.f
#define GAMMA_SCALING 1.f
#define GAIN_SCALING 1.f
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -166,10 +166,10 @@
{
int i, c;
float E = 1e-15;
- VARDECL(celt_sig_t *x);
- VARDECL(celt_sig_t *tmp);
- ALLOC(x, 2*N, celt_sig_t);
- ALLOC(tmp, N, celt_sig_t);
+ VARDECL(celt_word32_t *x);
+ VARDECL(celt_word32_t *tmp);
+ ALLOC(x, 2*N, celt_word32_t);
+ ALLOC(tmp, N, celt_word32_t);
for (c=0;c<C;c++)
{
for (i=0;i<B;i++)
@@ -177,13 +177,13 @@
int j;
for (j=0;j<2*N;j++)
{
- x[j] = window[j]*in[C*i*N+C*j+c];
- E += x[j]*x[j];
+ x[j] = SIG_SCALING*window[j]*in[C*i*N+C*j+c];
+ E += SIG_SCALING_1*SIG_SCALING_1*x[j]*x[j];
}
mdct_forward(mdct_lookup, x, tmp);
/* Interleaving the sub-frames */
for (j=0;j<N;j++)
- out[C*B*j+C*i+c] = tmp[j];
+ out[C*B*j+C*i+c] = SIG_SCALING_1*tmp[j];
}
}
return E;
@@ -193,10 +193,10 @@
static void compute_inv_mdcts(mdct_lookup *mdct_lookup, float *window, celt_sig_t *X, celt_sig_t *out_mem, celt_sig_t *mdct_overlap, int N, int overlap, int B, int C)
{
int i, c, N4;
- VARDECL(celt_sig_t *x);
- VARDECL(celt_sig_t *tmp);
- ALLOC(x, 2*N, celt_sig_t);
- ALLOC(tmp, N, celt_sig_t);
+ VARDECL(celt_word32_t *x);
+ VARDECL(celt_word32_t *tmp);
+ ALLOC(x, 2*N, celt_word32_t);
+ ALLOC(tmp, N, celt_word32_t);
N4 = (N-overlap)/2;
for (c=0;c<C;c++)
{
@@ -205,16 +205,16 @@
int j;
/* De-interleaving the sub-frames */
for (j=0;j<N;j++)
- tmp[j] = X[C*B*j+C*i+c];
+ tmp[j] = SIG_SCALING*X[C*B*j+C*i+c];
mdct_backward(mdct_lookup, tmp, x);
for (j=0;j<2*N;j++)
x[j] = window[j]*x[j];
for (j=0;j<overlap;j++)
- out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] = 2*(x[N4+j]+mdct_overlap[C*j+c]);
+ out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] = 2*(SIG_SCALING_1*x[N4+j]+mdct_overlap[C*j+c]);
for (j=0;j<2*N4;j++)
- out_mem[C*(MAX_PERIOD+(i-B)*N)+C*(j+overlap)+c] = 2*x[j+N4+overlap];
+ out_mem[C*(MAX_PERIOD+(i-B)*N)+C*(j+overlap)+c] = 2*SIG_SCALING_1*x[j+N4+overlap];
for (j=0;j<overlap;j++)
- mdct_overlap[C*j+c] = x[N+N4+j];
+ mdct_overlap[C*j+c] = SIG_SCALING_1*x[N+N4+j];
}
}
}
--- a/libcelt/pitch.c
+++ b/libcelt/pitch.c
@@ -48,16 +48,16 @@
{
int c, i;
float max_corr;
- VARDECL(celt_sig_t *xx);
- VARDECL(celt_sig_t *yy);
- VARDECL(celt_sig_t *X);
- VARDECL(celt_sig_t *Y);
+ VARDECL(celt_word32_t *xx);
+ VARDECL(celt_word32_t *yy);
+ VARDECL(celt_word32_t *X);
+ VARDECL(celt_word32_t *Y);
VARDECL(float *curve);
int n2 = lag/2;
- ALLOC(xx, lag*C, celt_sig_t);
- ALLOC(yy, lag*C, celt_sig_t);
- ALLOC(X, lag*C, celt_sig_t);
- ALLOC(Y, lag*C, celt_sig_t);
+ ALLOC(xx, lag*C, celt_word32_t);
+ ALLOC(yy, lag*C, celt_word32_t);
+ ALLOC(X, lag*C, celt_word32_t);
+ ALLOC(Y, lag*C, celt_word32_t);
ALLOC(curve, n2*C, float);
for (i=0;i<C*lag;i++)
@@ -65,9 +65,9 @@
for (c=0;c<C;c++)
{
for (i=0;i<len;i++)
- xx[c*lag+i] = x[C*i+c];
+ xx[c*lag+i] = SIG_SCALING*x[C*i+c];
for (i=0;i<lag;i++)
- yy[c*lag+i] = y[C*i+c];
+ yy[c*lag+i] = SIG_SCALING*y[C*i+c];
}
@@ -82,13 +82,17 @@
/*n = 1.f/(1e1+sqrt(sqrt((X[2*i-1]*X[2*i-1] + X[2*i ]*X[2*i ])*(Y[2*i-1]*Y[2*i-1] + Y[2*i ]*Y[2*i ]))));*/
/*n = 1;*/
n = 1.f/sqrt(1+curve[i]);
+ /*printf ("%f ", n);*/
/*n = 1.f/(1+curve[i]);*/
tmp = X[2*i];
- X[2*i] = (X[2*i ]*Y[2*i ] + X[2*i+1]*Y[2*i+1])*n;
- X[2*i+1] = (- X[2*i+1]*Y[2*i ] + tmp*Y[2*i+1])*n;
+ X[2*i] = (1.f*X[2*i ]*Y[2*i ] + 1.f*X[2*i+1]*Y[2*i+1])*n;
+ X[2*i+1] = (- 1.f*X[2*i+1]*Y[2*i ] + 1.f*tmp*Y[2*i+1])*n;
}
+ /*printf ("\n");*/
X[0] = X[1] = 0;
kiss_fftri(fft, X, xx);
+ /*for (i=0;i<C*lag;i++)
+ printf ("%d %d\n", X[i], xx[i]);*/
max_corr=-1e10;
*pitch = 0;
@@ -101,6 +105,7 @@
max_corr = xx[i];
}
}
+ /*printf ("%f\n", max_corr);*/
/*printf ("\n");
printf ("%d %f\n", *pitch, max_corr);
printf ("%d\n", *pitch);*/
--- a/libcelt/psy.c
+++ b/libcelt/psy.c
@@ -122,15 +122,15 @@
}
/* Compute a marking threshold from the spectrum X. */
-void compute_masking(struct PsyDecay *decay, celt_sig_t *X, float *mask, int len, int Fs)
+void compute_masking(struct PsyDecay *decay, celt_word32_t *X, float *mask, int len, int Fs)
{
int i;
VARDECL(float *psd);
int N=len/2;
ALLOC(psd, N, float);
- psd[0] = X[0]*X[0];
+ psd[0] = X[0]*1.f*X[0];
for (i=1;i<N;i++)
- psd[i] = X[i*2]*X[i*2] + X[i*2+1]*X[i*2+1];
+ psd[i] = X[i*2]*1.f*X[i*2] + X[i*2+1]*1.f*X[i*2+1];
/* TODO: Do tone masking */
/* Noise masking */
spreading_func(decay, psd, mask, N, Fs);
@@ -137,7 +137,7 @@
}
-void compute_mdct_masking(struct PsyDecay *decay, float *X, float *mask, int len, int Fs)
+void compute_mdct_masking(struct PsyDecay *decay, celt_word32_t *X, float *mask, int len, int Fs)
{
int i;
VARDECL(float *psd);
--- a/libcelt/psy.h
+++ b/libcelt/psy.h
@@ -45,9 +45,9 @@
void psydecay_clear(struct PsyDecay *decay);
/** Compute the masking curve for an input (DFT) spectrum X */
-void compute_masking(struct PsyDecay *decay, celt_sig_t *X, float *mask, int len, int Fs);
+void compute_masking(struct PsyDecay *decay, celt_word32_t *X, float *mask, int len, int Fs);
/** Compute the masking curve for an input (MDCT) spectrum X */
-void compute_mdct_masking(struct PsyDecay *decay, float *X, float *mask, int len, int Fs);
+void compute_mdct_masking(struct PsyDecay *decay, celt_word32_t *X, float *mask, int len, int Fs);
#endif /* PSY_H */