예제 #1
0
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);
}
예제 #2
0
파일: 1-f-code.c 프로젝트: Anastien/ngspice
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);
}
예제 #3
0
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;
}
예제 #4
0
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 */
예제 #5
0
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 */