ref: af8402e033360256d34689cd822cd75291ff4bef
parent: df3cb9be1f623f4b8827ebb5faafadd6f34600df
author: Jean-Marc Valin <[email protected]>
date: Fri Feb 22 07:13:59 EST 2008
Fixed stuff that got broken during the forward-backward split of the FFT
--- a/libcelt/_kiss_fft_guts.h
+++ b/libcelt/_kiss_fft_guts.h
@@ -67,8 +67,8 @@
do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \
(m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)
# define C_MULC(m,a,b) \
- do{ (m).r = sround( smul((a).r,(b).r) + smul((a).i,(b).i) ); \
- (m).i = smul((a).i,(b).r) - sround( smul((a).r,(b).i) ); }while(0)
+ do{ (m).r = sround( smul((a).r,(b).r) + smul((a).i,(b).i) ); \
+ (m).i = sround( smul((a).i,(b).r) - smul((a).r,(b).i) ); }while(0)
# define C_MUL4(m,a,b) \
do{ (m).r = PSHR32( smul((a).r,(b).r) - smul((a).i,(b).i),17 ); \
@@ -84,6 +84,44 @@
# define C_MULBYSCALAR( c, s ) \
do{ (c).r = sround( smul( (c).r , s ) ) ;\
(c).i = sround( smul( (c).i , s ) ) ; }while(0)
+
+
+#define L1 32767
+#define L2 -7651
+#define L3 8277
+#define L4 -626
+
+static inline celt_word16_t _celt_cos_pi_2(celt_word16_t x)
+{
+ celt_word16_t x2;
+
+ x2 = MULT16_16_P15(x,x);
+ return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2
+ ))))))));
+}
+
+static inline celt_word16_t celt_cos_norm(celt_word32_t x)
+{
+ x = x&0x0001ffff;
+ if (x>SHL32(EXTEND32(1), 16))
+ x = SUB32(SHL32(EXTEND32(1), 17),x);
+ if (x&0x00007fff)
+ {
+ if (x<SHL32(EXTEND32(1), 15))
+ {
+ return _celt_cos_pi_2(EXTRACT16(x));
+ } else {
+ return NEG32(_celt_cos_pi_2(EXTRACT16(65536-x)));
+ }
+ } else {
+ if (x&0x0000ffff)
+ return 0;
+ else if (x&0x0001ffff)
+ return -32767;
+ else
+ return 32767;
+ }
+}
#else /* not FIXED_POINT*/
--- a/libcelt/kiss_fft.h
+++ b/libcelt/kiss_fft.h
@@ -33,7 +33,7 @@
#ifdef FIXED_POINT
#include "arch.h"
-# define kiss_fft_scalar spx_int16_t
+# define kiss_fft_scalar celt_int16_t
#else
# ifndef kiss_fft_scalar
/* default is float */
--- a/tests/dft-test.c
+++ b/tests/dft-test.c
@@ -25,13 +25,17 @@
im = -im;
#ifdef FIXED_POINT
- re /= nfft;
- im /= nfft;
+ if (!isinverse)
+ {
+ re /= nfft;
+ im /= nfft;
+ }
#endif
ansr += in[k].r * re - in[k].i * im;
ansi += in[k].r * im + in[k].i * re;
}
+ /*printf ("%d %d ", (int)ansr, (int)ansi);*/
difr = ansr - out[bin].r;
difi = ansi - out[bin].i;
errpow += difr*difr + difi*difi;
@@ -55,9 +59,21 @@
}
if (isinverse)
+ {
+ for (k=0;k<nfft;++k) {
+ in[k].r /= nfft;
+ in[k].i /= nfft;
+ }
+ }
+
+ /*for (k=0;k<nfft;++k) printf("%d %d ", in[k].r, in[k].i);printf("\n");*/
+
+ if (isinverse)
kiss_ifft(cfg,in,out);
else
kiss_fft(cfg,in,out);
+
+ /*for (k=0;k<nfft;++k) printf("%d %d ", out[k].r, out[k].i);printf("\n");*/
check(in,out,nfft,isinverse);