int fix_fft(int16_t iq[], int m) /* interleaved iq[], 0 <= n < 2**m, changes in place */ { int mr, nn, i, j, l, k, istep, n, shift; int16_t qr, qi, tr, ti, wr, wi; n = 1 << m; if (n > N_WAVE) {return -1;} mr = 0; nn = n - 1; /* decimation in time - re-order data */ for (m=1; m<=nn; ++m) { l = n; do {l >>= 1;} while (mr+l > nn); mr = (mr & (l-1)) + l; if (mr <= m) {continue;} // real = 2*m, imag = 2*m+1 tr = iq[2*m]; iq[2*m] = iq[2*mr]; iq[2*mr] = tr; ti = iq[2*m+1]; iq[2*m+1] = iq[2*mr+1]; iq[2*mr+1] = ti; } l = 1; k = LOG2_N_WAVE-1; while (l < n) { shift = 1; istep = l << 1; for (m=0; m<l; ++m) { j = m << k; wr = Sinewave[j+N_WAVE/4]; wi = -Sinewave[j]; if (shift) { wr >>= 1; wi >>= 1;} for (i=m; i<n; i+=istep) { j = i + l; tr = FIX_MPY(wr,iq[2*j]) - FIX_MPY(wi,iq[2*j+1]); ti = FIX_MPY(wr,iq[2*j+1]) + FIX_MPY(wi,iq[2*j]); qr = iq[2*i]; qi = iq[2*i+1]; if (shift) { qr >>= 1; qi >>= 1;} iq[2*j] = qr - tr; iq[2*j+1] = qi - ti; iq[2*i] = qr + tr; iq[2*i+1] = qi + ti; } } --k; l = istep; } return 0; }
void operation(int16_t* x,int16_t* y, int16_t* z, int N){ int i; for (i=0; i<N; i+=8){ z[i] = FIX_MPY(x[i], y[i]); z[i+1] = FIX_MPY(x[i+1], y[i+1]); z[i+2] = FIX_MPY(x[i+2], y[i+2]); z[i+3] = FIX_MPY(x[i+3], y[i+3]); z[i+4] = FIX_MPY(x[i+4], y[i+4]); z[i+5] = FIX_MPY(x[i+5], y[i+5]); z[i+6] = FIX_MPY(x[i+6], y[i+6]); z[i+7] = FIX_MPY(x[i+7], y[i+7]); } }
/* fix_dot() - dot product of two fixed arrays */ fixed fix_dot(fixed *hpa, fixed *pb, int n) { fixed *pa; long sum; register fixed a,b; unsigned int seg,off; sum = 0L; while(n--) { a = *pa++; b = *pb++; FIX_MPY(a,a,b); sum += a; } if(sum > 0x7FFF) sum = 0x7FFF; else if(sum < -0x7FFF) sum = -0x7FFF; return (fixed)sum; }
/* fix_mpy() - fixed-point multiplication */ fixed fix_mpy(fixed a, fixed b) { FIX_MPY(a,a,b); return a; }