www.pudn.com > ETSI_ES_202_212_software.rar > rfft.c
/*=============================================================================== * ETSI ES 202 212 Distributed Speech Recognition * Extended Advanced Front-End Feature Extraction Algorithm & Compression Algorithm * Speech Reconstruction Algorithm. * C-language software implementation * Version 1.1.1 October, 2003 *===============================================================================*/ /*------------------------------------------------------------------------------- * * FILE NAME: rfft.c * PURPOSE: Real valued, in-place split-radix FFT. * *-------------------------------------------------------------------------------*/ /*----------------- * File Inclusions *-----------------*/ #include#include "rfft.h" /*--------------------------------------------------------------------------- * FUNCTION NAME: rfft * * PURPOSE: Real valued, in-place split-radix FFT * * INPUT: * x Pointer to input and output array * n Length of FFT, must be power of 2 * * OUTPUT Output order * Re(0), Re(1), ..., Re(n/2), Im(N/2-1), ..., Im(1) * * RETURN VALUE * none * * DESIGN REFERENCE: * IEEE Transactions on Acoustic, Speech, and Signal Processing, * Vol. ASSP-35. No. 6, June 1987, pp. 849-863. * * Subroutine adapted from fortran routine pp. 858-859. * Note corrected printing errors on page 859: * SS1 = SIN(A3) -> should be SS1 = SIN(A); * CC3 = COS(3) -> should be CC3 = COS(A3) * *---------------------------------------------------------------------------*/ void rfft (float *x, int n, int m) { int j, i, k, is, id; int i0, i1, i2, i3, i4, i5, i6, i7, i8; int n2, n4, n8; float xt, a0, e, a, a3; float t1, t2, t3, t4, t5, t6; float cc1, ss1, cc3, ss3; float *r0; /* Digit reverse counter */ j = 0; r0 = x; for (i = 0; i < n - 1; i++) { if (i < j) { xt = x[j]; x[j] = *r0; *r0 = xt; } r0++; k = n >> 1; while (k <= j) { j = j - k; k >>= 1; } j += k; } /* Length two butterflies */ is = 0; id = 4; while (is < n - 1) { for (i0 = is; i0 < n; i0 += id) { i1 = i0 + 1; a0 = x[i0]; x[i0] += x[i1]; x[i1] = a0 - x[i1]; } is = (id << 1) - 2; id <<= 2; } /* L shaped butterflies */ n2 = 2; for (k = 1; k < m; k++) { n2 <<= 1; n4 = n2 >> 2; n8 = n2 >> 3; e = (M_PI * 2) / n2; is = 0; id = n2 << 1; while (is < n) { for (i = is; i <= n - 1; i += id) { i1 = i; i2 = i1 + n4; i3 = i2 + n4; i4 = i3 + n4; t1 = x[i4] + x[i3]; x[i4] -= x[i3]; x[i3] = x[i1] - t1; x[i1] += t1; if (n4 != 1) { i1 += n8; i2 += n8; i3 += n8; i4 += n8; t1 = (x[i3] + x[i4]) / M_SQRT2; t2 = (x[i3] - x[i4]) / M_SQRT2; x[i4] = x[i2] - t1; x[i3] = -x[i2] - t1; x[i2] = x[i1] - t2; x[i1] = x[i1] + t2; } } is = (id << 1) - n2; id <<= 2; } for (j = 1; j < n8; j++) { a = j * e; a3 = 3 * a; cc1 = cos (a); ss1 = sin (a); cc3 = cos (a3); ss3 = sin (a3); is = 0; id = n2 << 1; while (is < n) { for (i = is; i <= n - 1; i += id) { i1 = i + j; i2 = i1 + n4; i3 = i2 + n4; i4 = i3 + n4; i5 = i + n4 - j; i6 = i5 + n4; i7 = i6 + n4; i8 = i7 + n4; t1 = x[i3] * cc1 + x[i7] * ss1; t2 = x[i7] * cc1 - x[i3] * ss1; t3 = x[i4] * cc3 + x[i8] * ss3; t4 = x[i8] * cc3 - x[i4] * ss3; t5 = t1 + t3; t6 = t2 + t4; t3 = t1 - t3; t4 = t2 - t4; t2 = x[i6] + t6; x[i3] = t6 - x[i6]; x[i8] = t2; t2 = x[i2] - t3; x[i7] = -x[i2] - t3; x[i4] = t2; t1 = x[i1] + t5; x[i6] = x[i1] - t5; x[i1] = t1; t1 = x[i5] + t4; x[i5] = x[i5] - t4; x[i2] = t1; } is = (id << 1) - n2; id <<= 2; } } } }