[xiph-commits] r10528 - trunk/speex/libspeex
jm at svn.xiph.org
jm at svn.xiph.org
Fri Dec 2 21:01:53 PST 2005
Author: jm
Date: 2005-12-02 21:01:49 -0800 (Fri, 02 Dec 2005)
New Revision: 10528
Modified:
trunk/speex/libspeex/fftwrap.c
trunk/speex/libspeex/kiss_fft.c
trunk/speex/libspeex/kiss_fftr.c
trunk/speex/libspeex/mdf.c
Log:
Added kiss-fft support to fft-wrap, some fixed-point scaling tuning to mdf.
Modified: trunk/speex/libspeex/fftwrap.c
===================================================================
--- trunk/speex/libspeex/fftwrap.c 2005-12-02 22:46:18 UTC (rev 10527)
+++ trunk/speex/libspeex/fftwrap.c 2005-12-03 05:01:49 UTC (rev 10528)
@@ -32,16 +32,16 @@
*/
-#define USE_SMALLFT
+/*#define USE_SMALLFT*/
+#define USE_KISS_FFT
#include "misc.h"
+#include <math.h>
-
#ifdef USE_SMALLFT
#include "smallft.h"
-#include <math.h>
void *spx_fft_init(int size)
{
@@ -89,19 +89,134 @@
spx_drft_backward((struct drft_lookup *)table, out);
}
+#elif defined(USE_KISS_FFT)
+
+#include "kiss_fftr.h"
+#include "kiss_fft.h"
+
+struct kiss_config {
+ kiss_fftr_cfg forward;
+ kiss_fftr_cfg backward;
+ kiss_fft_cpx *freq_data;
+ int N;
+};
+
+void *spx_fft_init(int size)
+{
+ struct kiss_config *table;
+ table = speex_alloc(sizeof(struct kiss_config));
+ table->freq_data = speex_alloc(sizeof(kiss_fft_cpx)*((size>>1)+1));
+ table->forward = kiss_fftr_alloc(size,0,NULL,NULL);
+ table->backward = kiss_fftr_alloc(size,1,NULL,NULL);
+ table->N = size;
+ return table;
+}
+
+void spx_fft_destroy(void *table)
+{
+ struct kiss_config *t = (struct kiss_config *)table;
+ kiss_fftr_free(t->forward);
+ kiss_fftr_free(t->backward);
+ speex_free(t->freq_data);
+ speex_free(table);
+}
+
+void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
+{
+ int i;
+ float scale;
+#ifdef FIXED_POINT
+ int shift;
+#endif
+ struct kiss_config *t = (struct kiss_config *)table;
+#ifdef FIXED_POINT
+ scale = 1;
#else
+ scale = 1./t->N;
+#endif
+ kiss_fftr(t->forward, in, t->freq_data);
+ out[0] = scale*t->freq_data[0].r;
+ for (i=1;i<t->N>>1;i++)
+ {
+ out[(i<<1)-1] = scale*t->freq_data[i].r;
+ out[(i<<1)] = scale*t->freq_data[i].i;
+ }
+ out[(i<<1)-1] = scale*t->freq_data[i].r;
+}
+void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)
+{
+ int i;
+ struct kiss_config *t = (struct kiss_config *)table;
+ t->freq_data[0].r = in[0];
+ t->freq_data[0].i = 0;
+ for (i=1;i<t->N>>1;i++)
+ {
+ t->freq_data[i].r = in[(i<<1)-1];
+ t->freq_data[i].i = in[(i<<1)];
+ }
+ t->freq_data[i].r = in[(i<<1)-1];
+ t->freq_data[i].i = 0;
+
+ kiss_fftri(t->backward, t->freq_data, out);
+}
+
+
+#else
+
#error No other FFT implemented
#endif
+#ifdef FIXED_POINT
+
void spx_fft_float(void *table, float *in, float *out)
{
+ int i;
+#ifdef USE_SMALLFT
+ int N = ((struct drft_lookup *)table)->n;
+#elif defined(USE_KISS_FFT)
+ int N = ((struct kiss_config *)table)->N;
+#else
+#endif
+ spx_word16_t _in[N];
+ spx_word16_t _out[N];
+ for (i=0;i<N;i++)
+ _in[i] = (int)floor(.5+in[i]);
+ spx_fft(table, _in, _out);
+ for (i=0;i<N;i++)
+ out[i] = _out[i];
+}
+
+void spx_ifft_float(void *table, float *in, float *out)
+{
+ int i;
+#ifdef USE_SMALLFT
+ int N = ((struct drft_lookup *)table)->n;
+#elif defined(USE_KISS_FFT)
+ int N = ((struct kiss_config *)table)->N;
+#else
+#endif
+ spx_word16_t _in[N];
+ spx_word16_t _out[N];
+ for (i=0;i<N;i++)
+ _in[i] = (int)floor(.5+in[i]);
+ spx_ifft(table, _in, _out);
+ for (i=0;i<N;i++)
+ out[i] = _out[i];
+}
+
+#else
+
+void spx_fft_float(void *table, float *in, float *out)
+{
spx_fft(table, in, out);
}
void spx_ifft_float(void *table, float *in, float *out)
{
spx_ifft(table, in, out);
}
+
+#endif
Modified: trunk/speex/libspeex/kiss_fft.c
===================================================================
--- trunk/speex/libspeex/kiss_fft.c 2005-12-02 22:46:18 UTC (rev 10527)
+++ trunk/speex/libspeex/kiss_fft.c 2005-12-03 05:01:49 UTC (rev 10528)
@@ -45,7 +45,9 @@
kiss_fft_cpx t;
Fout2 = Fout + m;
do{
+ if (!st->inverse) {
C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2);
+ }
C_MUL (t, *Fout2 , *tw1);
tw1 += fstride;
@@ -72,7 +74,9 @@
tw3 = tw2 = tw1 = st->twiddles;
do {
+ if (!st->inverse) {
C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4);
+ }
C_MUL(scratch[0],Fout[m] , *tw1 );
C_MUL(scratch[1],Fout[m2] , *tw2 );
@@ -120,7 +124,9 @@
tw1=tw2=st->twiddles;
do{
+ if (!st->inverse) {
C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3);
+ }
C_MUL(scratch[1],Fout[m] , *tw1);
C_MUL(scratch[2],Fout[m2] , *tw2);
@@ -171,7 +177,9 @@
tw=st->twiddles;
for ( u=0; u<m; ++u ) {
+ if (!st->inverse) {
C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5);
+ }
scratch[0] = *Fout0;
C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
@@ -228,7 +236,9 @@
k=u;
for ( q1=0 ; q1<p ; ++q1 ) {
scratchbuf[q1] = Fout[ k ];
+ if (!st->inverse) {
C_FIXDIV(scratchbuf[q1],p);
+ }
k += m;
}
Modified: trunk/speex/libspeex/kiss_fftr.c
===================================================================
--- trunk/speex/libspeex/kiss_fftr.c 2005-12-02 22:46:18 UTC (rev 10527)
+++ trunk/speex/libspeex/kiss_fftr.c 2005-12-03 05:01:49 UTC (rev 10528)
@@ -134,15 +134,15 @@
st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r;
st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r;
- C_FIXDIV(st->tmpbuf[0],2);
+ /*C_FIXDIV(st->tmpbuf[0],2);*/
for (k = 1; k <= ncfft / 2; ++k) {
kiss_fft_cpx fk, fnkc, fek, fok, tmp;
fk = freqdata[k];
fnkc.r = freqdata[ncfft - k].r;
fnkc.i = -freqdata[ncfft - k].i;
- C_FIXDIV( fk , 2 );
- C_FIXDIV( fnkc , 2 );
+ /*C_FIXDIV( fk , 2 );
+ C_FIXDIV( fnkc , 2 );*/
C_ADD (fek, fk, fnkc);
C_SUB (tmp, fk, fnkc);
Modified: trunk/speex/libspeex/mdf.c
===================================================================
--- trunk/speex/libspeex/mdf.c 2005-12-02 22:46:18 UTC (rev 10527)
+++ trunk/speex/libspeex/mdf.c 2005-12-03 05:01:49 UTC (rev 10528)
@@ -55,6 +55,14 @@
#define min(a,b) ((a)<(b) ? (a) : (b))
#define max(a,b) ((a)>(b) ? (a) : (b))
+#ifdef FIXED_POINT
+#define WEIGHT_SCALING 128.f
+#define WEIGHT_SCALING_1 0.0078125f
+#else
+#define WEIGHT_SCALING 1.f
+#define WEIGHT_SCALING_1 1.f
+#endif
+
/** Compute inner product of two real vectors */
static inline float inner_prod(float *x, float *y, int N)
{
@@ -236,7 +244,11 @@
st->Y[i] = 0;
for (j=0;j<M;j++)
spectral_mul_accum(&st->X[j*N], &st->W[j*N], st->Y, N);
-
+
+ /* Convert Y (filter response) to time domain */
+ for (i=0;i<N;i++)
+ st->Y[i] *= WEIGHT_SCALING_1;
+
spx_ifft_float(st->fft_table, st->Y, st->y);
/* Compute error signal (signal with echo removed) */
@@ -332,11 +344,11 @@
r = leak_estimate*st->Yf[i] / (1+st->Rf[i]);
if (r>1)
r = 1;
- st->power_1[i] = adapt_rate*r/(1.f+st->power[i]);
+ st->power_1[i] = WEIGHT_SCALING*adapt_rate*r/(1.f+st->power[i]);
}
} else {
for (i=0;i<=st->frame_size;i++)
- st->power_1[i] = adapt_rate/(1.f+st->power[i]);
+ st->power_1[i] = WEIGHT_SCALING*adapt_rate/(1.f+st->power[i]);
}
/* Compute weight gradient */
More information about the commits
mailing list