void scfft_doifft(scfft * f) { #if SC_FFT_FFTW float *trbuf = f->trbuf; size_t bytesize = f->nfull * sizeof(float); memcpy(trbuf, f->indata, bytesize); trbuf[1] = 0.f; trbuf[f->nfull] = f->indata[1]; // Nyquist goes all the way down to the end of the line... trbuf[f->nfull+1] = 0.f; fftwf_execute(f->plan); // NB the plan already includes copying data to f->outbuf #elif SC_FFT_VDSP vDSP_ctoz((COMPLEX*) f->indata, 2, &splitBuf, 1, f->nfull >> 1); vDSP_fft_zrip(fftSetup[f->log2nfull], &splitBuf, 1, f->log2nfull, FFT_INVERSE); vDSP_ztoc(&splitBuf, 1, (DSPComplex*) f->outdata, 2, f->nfull >> 1); #elif SC_FFT_GREEN float *trbuf = f->trbuf; size_t bytesize = f->nfull * sizeof(float); memcpy(trbuf, f->indata, bytesize); // Green FFT is in-place riffts(trbuf, f->log2nfull, 1, cosTable[f->log2nfull]); // Copy to public buffer memcpy(f->outdata, trbuf, f->nwin * sizeof(float)); #endif scfft_dowindowing(f->outdata, f->nwin, f->nfull, f->log2nwin, f->wintype, f->scalefac); }
void f_alpha(int n_pts, int n_exp, double X[], double Q_d, double alpha) { int i, length; double ha; double *hfa, *wfa; #ifdef HAVE_LIBFFTW3 fftw_complex *out = NULL; fftw_plan plan_forward = NULL; fftw_plan plan_backward = NULL; NG_IGNORE(n_exp); #endif ha = alpha/2.0; // Q_d = sqrt(Q_d); /* find the deviation of the noise */ #ifdef HAVE_LIBFFTW3 length = 2 * (n_pts/2 + 1); #else length = n_pts; #endif hfa = TMALLOC(double, length); wfa = TMALLOC(double, length); hfa[0] = 1.0; wfa[0] = Q_d * GaussWa; /* generate the coefficients hk */ for (i = 1; i < n_pts; i++) { /* generate the coefficients hk */ hfa[i] = hfa[i-1] * (ha + (double)(i-1)) / ((double)(i)); /* fill the sequence wk with white noise */ wfa[i] = Q_d * GaussWa; } #ifdef HAVE_LIBFFTW3 /* in-place transformation needs zero padding on the end */ hfa[n_pts] = 0.0; wfa[n_pts] = 0.0; hfa[n_pts+1] = 0.0; wfa[n_pts+1] = 0.0; /* perform the discrete Fourier transform */ plan_forward = fftw_plan_dft_r2c_1d(n_pts, hfa, (fftw_complex *)hfa, FFTW_ESTIMATE); fftw_execute(plan_forward); fftw_destroy_plan(plan_forward); plan_forward = fftw_plan_dft_r2c_1d(n_pts, wfa, (fftw_complex *)wfa, FFTW_ESTIMATE); fftw_execute(plan_forward); fftw_destroy_plan(plan_forward); out = fftw_malloc(sizeof(fftw_complex) * (unsigned int) (n_pts/2 + 1)); /* multiply the two complex vectors */ for (i = 0; i < n_pts/2 + 1; i++) { out[i][0] = hfa[i]*wfa[i] - hfa[i+1]*wfa[i+1]; out[i][1] = hfa[i]*wfa[i+1] + hfa[i+1]*wfa[i]; } /* inverse transform */ plan_backward = fftw_plan_dft_c2r_1d(n_pts, out, X, FFTW_ESTIMATE); fftw_execute(plan_backward); fftw_destroy_plan(plan_backward); for (i = 0; i < n_pts; i++) { X[i] = X[i] / (double) n_pts; } fftw_free(out); #else /* Green's FFT */ /* perform the discrete Fourier transform */ fftInit(n_exp); rffts(hfa, n_exp, 1); rffts(wfa, n_exp, 1); /* multiply the two complex vectors */ rspectprod(hfa, wfa, X, n_pts); /* inverse transform */ riffts(X, n_exp, 1); #endif free(hfa); free(wfa); /* fft tables will be freed in vsrcaccept.c and isrcaccept.c fftFree(); */ fprintf(stdout, "%d 1/f noise values in time domain created\n", n_pts); }
void main(){ const long N2 = 2; /* the number ffts to test */ long N = 2048; /* size of FFTs, must be power of 2 */ long kernSize = 1003; /* kernal size must be less than N */ long dataSize = N-kernSize+1; /* data size */ float *a; float *b; long i1; long i2; long TheErr; long M; FILE *fdataout; /* output file */ unsigned int randseed = 777; int rannum; #if macintosh UnsignedWide TheTime1; Microseconds(&TheTime1); randseed = TheTime1.lo; #endif printf(" %6d Byte Floats \n", sizeof(a[0])); printf(" randseed = %10u\n", randseed); srand(randseed); M = roundtol(LOG2(N)); N = POW2(M); printf("fft size = %6d, ", N); if (dataSize <= 0) TheErr = 22; else TheErr = 0; if(!TheErr){ TheErr = fftInit(M); } a = (float *) calloc(N2*N,sizeof(float) ); // calloc to zero pad data to fill N if (a == 0) TheErr = 2; if(!TheErr){ b = (float *) calloc(N2*N,sizeof(float) ); // calloc to zero pad data to fill N if (b == 0) TheErr = 2; } if(!TheErr){ fdataout = fopen("convdat.cnv", "wb"); if (fdataout == NULL) TheErr = -50; } if(!TheErr){ /* write sizes to fdataout */ fwrite(&dataSize, sizeof(dataSize), 1, fdataout); fwrite(&kernSize, sizeof(kernSize), 1, fdataout); fwrite(&N2, sizeof(N2), 1, fdataout); /* set up a simple test case and write to fdataout */ for (i2=0; i2<N2; i2++){ for (i1=0; i1<dataSize; i1++){ rannum = rand(); a[i2*N+i1] = BIPRAND(rannum); } fwrite(&a[i2*N], dataSize*sizeof(float), 1, fdataout); } for (i2=0; i2<N2; i2++){ for (i1=0; i1<kernSize; i1++){ rannum = rand(); b[i2*N+i1] = BIPRAND(rannum); } fwrite(&b[i2*N], kernSize*sizeof(float), 1, fdataout); } /* fast convolution of zero padded sequences */ rffts(a, M, N2); rffts(b, M, N2); for (i2=0; i2<N2*N; i2+=N){ rspectprod(&a[i2], &b[i2], &a[i2], N); } riffts(a, M, N2); /* write out answer */ fwrite(a, N2*N*sizeof(float), 1, fdataout); fclose(fdataout); free(b); free(a); fftFree(); } else{ if(TheErr==2) printf(" out of memory \n"); else printf(" error \n"); fftFree(); } printf(" Done. \n"); return; }
void convolve_s_fetch(snd_susp_type a_susp, snd_list_type snd_list) { convolve_susp_type susp = (convolve_susp_type) a_susp; int cnt = 0; /* how many samples computed */ int togo; int n; sample_block_type out; register sample_block_values_type out_ptr; register sample_block_values_type out_ptr_reg; sample_type *R = susp->R; sample_type *R_current; int N = susp->N; falloc_sample_block(out, "convolve_s_fetch"); out_ptr = out->samples; snd_list->block = out; while (cnt < max_sample_block_len) { /* outer loop */ /* first compute how many samples to generate in inner loop: */ /* don't overflow the output sample block: */ togo = max_sample_block_len - cnt; /* if we need output samples, generate them here */ if (susp->R_current >= R + N) { /* Copy N samples of x_snd into X and zero fill to size 2N */ int i = 0; sample_type *X = susp->X; sample_type *H = susp->H; int to_copy; while (i < N) { if (susp->x_snd_cnt == 0) { susp_get_samples(x_snd, x_snd_ptr, x_snd_cnt); if (susp->x_snd->logical_stop_cnt == susp->x_snd->current - susp->x_snd_cnt) { min_cnt(&susp->susp.log_stop_cnt, susp->x_snd, (snd_susp_type) susp, susp->x_snd_cnt); } } if (susp->x_snd_ptr == zero_block->samples) { min_cnt(&susp->terminate_cnt, susp->x_snd, (snd_susp_type) susp, susp->x_snd_cnt); /* extend the output to include impulse response */ susp->terminate_cnt += susp->h_len; } /* copy no more than the remaining space and no more than * the amount remaining in the block */ to_copy = min(N - i, susp->x_snd_cnt); memcpy(X + i, susp->x_snd_ptr, to_copy * sizeof(*susp->x_snd_ptr)); susp->x_snd_ptr += to_copy; susp->x_snd_cnt -= to_copy; i += to_copy; } /* zero fill to size 2N */ memset(X + N, 0, N * sizeof(X[0])); /* Compute FFT of X in place */ fftInit(susp->M); rffts(X, susp->M, 1); /* Multiply X by H (result goes into X) */ rspectprod(X, H, X, N * 2); /* Compute IFFT of X in place */ riffts(X, susp->M, 1); /* Shift R, zero fill, add X, all in one loop */ for (i = 0; i < N; i++) { R[i] = R[i + N] + X[i]; R[i + N] = X[i + N]; } /* now N samples of R can be output */ susp->R_current = R; } /* compute togo, the number of samples to "compute" */ /* can't use more than what's left in R. R_current is the next sample of R, so what's left is N - (R - R_current) */ R_current = susp->R_current; togo = min(togo, N - (R_current - R)); /* don't run past terminate time */ if (susp->terminate_cnt != UNKNOWN && susp->terminate_cnt <= susp->susp.current + cnt + togo) { togo = susp->terminate_cnt - (susp->susp.current + cnt); if (togo == 0) break; } /* don't run past logical stop time */ if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN && susp->susp.log_stop_cnt <= susp->susp.current + cnt + togo) { togo = susp->susp.log_stop_cnt - (susp->susp.current + cnt); if (togo == 0) break; } n = togo; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ *out_ptr_reg++ = (sample_type) *R_current++; } while (--n); /* inner loop */ /* using R_current is a bad idea on RS/6000: */ susp->R_current += togo; out_ptr += togo; cnt += togo; } /* outer loop */ /* test for termination */ if (togo == 0 && cnt == 0) { snd_list_terminate(snd_list); } else { snd_list->block_len = cnt; susp->susp.current += cnt; } /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } } /* convolve_s_fetch */
void ifft__fetch(register ifft_susp_type susp, snd_list_type snd_list) { int cnt = 0; /* how many samples computed */ int togo; int n; sample_block_type out; register sample_block_values_type out_ptr; register sample_block_values_type out_ptr_reg; register long index_reg; register sample_type * outbuf_reg; falloc_sample_block(out, "ifft__fetch"); out_ptr = out->samples; snd_list->block = out; while (cnt < max_sample_block_len) { /* outer loop */ /* first compute how many samples to generate in inner loop: */ /* don't overflow the output sample block: */ togo = max_sample_block_len - cnt; if (susp->src == NULL) { out: togo = 0; /* indicate termination */ break; /* we're done */ } if (susp->index >= susp->stepsize) { long i; long m, n; LVAL elem; susp->index = 0; susp->array = xleval(cons(s_send, cons(susp->src, consa(s_next)))); if (susp->array == NULL) { susp->src = NULL; goto out; } else if (!vectorp(susp->array)) { xlerror("array expected", susp->array); } else if (susp->samples == NULL) { /* assume arrays are all the same size as first one; now that we know the size, we just have to do this first allocation. */ susp->length = getsize(susp->array); if (susp->length < 1) xlerror("array has no elements", susp->array); if (susp->window && (susp->window_len != susp->length)) xlerror("window size and spectrum size differ", susp->array); /* tricky non-power of 2 detector: only if this is a * power of 2 will the highest 1 bit be cleared when * we subtract 1 ... */ if (susp->length & (susp->length - 1)) xlfail("spectrum size must be a power of 2"); susp->samples = (sample_type *) calloc(susp->length, sizeof(sample_type)); susp->outbuf = (sample_type *) calloc(susp->length, sizeof(sample_type)); } else if (getsize(susp->array) != susp->length) { xlerror("arrays must all be the same length", susp->array); } /* at this point, we have a new array to put samples */ /* the incoming array format is [DC, R1, I1, R2, I2, ... RN] * where RN is the real coef at the Nyquist frequency * but susp->samples should be organized as [DC, RN, R1, I1, ...] */ n = susp->length; /* get the DC (real) coef */ elem = getelement(susp->array, 0); MUST_BE_FLONUM(elem) susp->samples[0] = (sample_type) getflonum(elem); /* get the Nyquist (real) coef */ elem = getelement(susp->array, n - 1); MUST_BE_FLONUM(elem); susp->samples[1] = (sample_type) getflonum(elem); /* get the remaining coef */ for (i = 1; i < n - 1; i++) { elem = getelement(susp->array, i); MUST_BE_FLONUM(elem) susp->samples[i + 1] = (sample_type) getflonum(elem); } susp->array = NULL; /* free the array */ /* here is where the IFFT and windowing should take place */ //fftnf(1, &n, susp->samples, susp->samples + n, -1, 1.0); m = round(log(n) / M_LN2); if (!fftInit(m)) riffts(susp->samples, m, 1); else xlfail("FFT initialization error"); if (susp->window) { n = susp->length; for (i = 0; i < n; i++) { susp->samples[i] *= susp->window[i]; } } /* shift the outbuf */ n = susp->length - susp->stepsize; for (i = 0; i < n; i++) { susp->outbuf[i] = susp->outbuf[i + susp->stepsize]; } /* clear end of outbuf */ for (i = n; i < susp->length; i++) { susp->outbuf[i] = 0; } /* add in the ifft result */ n = susp->length; for (i = 0; i < n; i++) { susp->outbuf[i] += susp->samples[i]; } } togo = min(togo, susp->stepsize - susp->index); n = togo; index_reg = susp->index; outbuf_reg = susp->outbuf; out_ptr_reg = out_ptr; if (n) do { /* the inner sample computation loop */ *out_ptr_reg++ = outbuf_reg[index_reg++];; } while (--n); /* inner loop */ susp->index = index_reg; susp->outbuf = outbuf_reg; out_ptr += togo; cnt += togo; } /* outer loop */ /* test for termination */ if (togo == 0 && cnt == 0) { snd_list_terminate(snd_list); } else { snd_list->block_len = cnt; susp->susp.current += cnt; } } /* ifft__fetch */