void cr1_fft(complex *cdata, REAL *data, int n, int sign) { int j; double *datft; if (NINT(pow(2.0, (double)NINT(log((double)n)/log(2.0)))) != n) { if (npfar(n) == n) pfacr(sign,n,cdata,data); else crdft(cdata,data,n,sign); } else { datft = (double *)malloc(n*sizeof(double)); if (datft == NULL) fprintf(stderr,"cr1_fft: memory allocation error\n"); for (j = 0; j < n/2; j++) { datft[j] = (double)cdata[j].r; datft[n-1-j] = (double)cdata[j+1].i; } datft[n/2] = (double)cdata[n/2].r; realifft(n, datft); if (sign == -1) { for (j = 0; j < n; j++) data[j] = (REAL)datft[j]; } else if (sign == 1) { for (j = 1; j < n; j++) data[j] = (REAL)datft[n-j]; data[0] = (REAL)datft[0]; } free(datft); } return; }
void crm_fft(complex *cdata, REAL *data, int n1, int n2, int ldc, int ldr, int sign) { int j, i; double *datft; if (NINT(pow(2.0, (double)NINT(log((double)n1)/log(2.0)))) != n1) { if (npfar(n1) == n1) { if (ldr == n1 && ldc == n2) { pfa2cr(sign, 1, n1, n2, cdata, data); } else { for (i = 0; i < n2; i++) { pfacr(sign, n1, &cdata[i*ldc], &data[i*ldr]); } } } else { for (i = 0; i < n2; i++) { crdft(&cdata[i*ldc], &data[i*ldr], n1, sign); } } } else { datft = (double *)malloc(n1*sizeof(double)); if (datft == NULL) fprintf(stderr,"crm_fft: memory allocation error\n"); for (i = 0; i < n2; i++) { for (j = 0; j < n1/2; j++) { datft[j] = (double)cdata[i*ldc+j].r; datft[n1-1-j] = (double)cdata[i*ldc+j+1].i; } datft[n1/2] = (double)cdata[i*ldc+n1/2].r; realifft(n1, datft); if (sign == -1) { for (j = 0; j < n1; j++) data[i*ldr+j] = (REAL)datft[j]; } else if (sign == 1) { for (j = 1; j < n1; j++) data[i*ldr+j] = (REAL)datft[n1-j]; data[i*ldr] = (REAL)datft[0]; } } free(datft); } return; }
t_int *fft_real_perform(t_int *w) { t_fft *x = (t_fft *)(w[1]); float *in = (float *)(w[2]); float *out = (float *)(w[3]); float *outsync = (float *)(w[4]); int n = w[5],m,np,count; long pts = x->f_points, interval = x->f_interval; float *b, *ei = x->f_realin + pts, *eo = x->f_realout + pts; float mult = x->f_1overpts; if (x->f_obj.z_disabled) goto out; if (n > pts) { np = pts; count = n / pts; } else { np = n; count = 1; } m = np; while (count--) { #ifdef USING_PHASE if (x->f_start) { long phase = x->f_phase % interval; if (phase < pts) x->f_realoutptr = x->f_realout + phase; else x->f_realoutptr = x->f_realout + pts; if (pts + phase >= interval) { x->f_countdown = 0; x->f_realinptr = x->f_realin + (pts + phase - interval); } else { x->f_countdown = (interval - phase - pts) / np; x->f_realinptr = x->f_realin; } x->f_start = 0; } #endif if (x->f_countdown) { x->f_countdown--; b = 0; } else { b = x->f_realinptr; BlockMove(in,b, np * sizeof(float)); b += np; } if (x->f_realoutptr != eo) { double q = (int)(x->f_realoutptr - x->f_realout); BlockMove(x->f_realoutptr,out,np * sizeof(float)); x->f_realoutptr += np; if (!fts_mode) { while (m--) { *outsync++ = q; q += 1.0; } } } else { if (!fts_mode) { while (m--) *outsync++ = 0.; } } if (b == ei) { BlockMove(x->f_realin,x->f_realout,pts * sizeof(float)); if (x->f_inverse) { float *real = x->f_realout; float mult = x->f_1overpts; realifft(pts, real); while (pts--) *real++ *= mult; } else realfft(pts, x->f_realout); x->f_realoutptr = x->f_realout; x->f_realinptr = x->f_realin; x->f_countdown = (interval - x->f_points) / np; if (fts_mode) clock_delay(x->f_clock, 0L); } else if (b) { x->f_realinptr += np; } } out: return (w + 6); }