Exemple #1
0
void scfft_dofft(scfft * f)
{
	// Data goes to transform buf
	memcpy(f->trbuf, f->indata, f->nwin * sizeof(float));
	scfft_dowindowing(f->trbuf, f->nwin, f->nfull, f->log2nwin, f->wintype, f->scalefac);
	#if SC_FFT_FFTW
		fftwf_execute(f->plan);
		// Rearrange output data onto public buffer
		memcpy(f->outdata, f->trbuf, f->nfull * sizeof(float));
		f->outdata[1] = f->trbuf[f->nfull]; // Pack nyquist val in
	#elif SC_FFT_VDSP
		// Perform even-odd split
		vDSP_ctoz((COMPLEX*) f->trbuf, 2, &splitBuf, 1, f->nfull >> 1);
		// Now the actual FFT
		vDSP_fft_zrip(fftSetup[f->log2nfull], &splitBuf, 1, f->log2nfull, FFT_FORWARD);
		// Copy the data to the public output buf, transforming it back out of "split" representation
		vDSP_ztoc(&splitBuf, 1, (DSPComplex*) f->outdata, 2, f->nfull >> 1);
	#elif SC_FFT_GREEN
		// Green FFT is in-place
		rffts(f->trbuf, f->log2nfull, 1, cosTable[f->log2nfull]);
		// Copy to public buffer
		memcpy(f->outdata, f->trbuf, f->nfull * sizeof(float));
	#endif
}
Exemple #2
0
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);
}
Exemple #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;
}
Exemple #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 */
Exemple #5
0
sound_type snd_make_convolve(sound_type x_snd, sound_type h_snd)
{
    register convolve_susp_type susp;
    rate_type sr = x_snd->sr;
    time_type t0 = x_snd->t0;
    sample_type scale_factor = 1.0F;
    time_type t0_min = t0;
    table_type table;
    double log_len;
    falloc_generic(susp, convolve_susp_node, "snd_make_convolve");
    table = sound_to_table(h_snd);
    susp->h_len = table->length;
    log_len = log(table->length) / M_LN2; /* compute log-base-2(length) */
    susp->M = (int) log_len;
    if (susp->M != log_len) susp->M++; /* round up */
    susp->N = 1 << susp->M; /* size of data blocks */
    susp->M++; /* M = log2(2 * N) */
    susp->H = (sample_type *) calloc(2 * susp->N, sizeof(susp->H[0]));
    if (!susp->H) {
        xlabort("memory allocation failure in convolve");
    }
    memcpy(susp->H, table->samples, sizeof(susp->H[0]) * susp->N);
    table_unref(table); /* don't need table now */
    /* remaining N samples are already zero-filled */
    if (fftInit(susp->M)) {
        free(susp->H);
        xlabort("fft initialization error in convolve");
    }
    rffts(susp->H, susp->M, 1);
    susp->X = (sample_type *) calloc(2 * susp->N, sizeof(susp->X[0]));
    susp->R = (sample_type *) calloc(2 * susp->N, sizeof(susp->R[0]));
    if (!susp->X || !susp->R) {
        free(susp->H);
        if (susp->X) free(susp->X);
        if (susp->R) free(susp->R);
        xlabort("memory allocation failed in convolve");
    }
    susp->R_current = susp->R + susp->N;
    susp->susp.fetch = &convolve_s_fetch;
    susp->terminate_cnt = UNKNOWN;
    /* handle unequal start times, if any */
    if (t0 < x_snd->t0) sound_prepend_zeros(x_snd, t0);
    /* minimum start time over all inputs: */
    t0_min = min(x_snd->t0, t0);
    /* how many samples to toss before t0: */
    susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5);
    if (susp->susp.toss_cnt > 0) {
        susp->susp.keep_fetch = susp->susp.fetch;
        susp->susp.fetch = convolve_toss_fetch;
    }

    /* initialize susp state */
    susp->susp.free = convolve_free;
    susp->susp.sr = sr;
    susp->susp.t0 = t0;
    susp->susp.mark = convolve_mark;
    susp->susp.print_tree = convolve_print_tree;
    susp->susp.name = "convolve";
    susp->logically_stopped = false;
    susp->susp.log_stop_cnt = logical_stop_cnt_cvt(x_snd);
    susp->susp.current = 0;
    susp->x_snd = x_snd;
    susp->x_snd_cnt = 0;
    return sound_create((snd_susp_type)susp, t0, sr, scale_factor);
}