home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include "uspl.h"
- #include "fftmain.h"
- /*---------------------------------------------------------------------------
- Some important notes and issues regarding this program.
- remember, the frequency of the sine wave you are generating
- *must* be < sample_rate/2, or the waveform will be aliased.
- The resolution of the fft in determining the frequency generated
- is dependant on sample_rate/fft_size, therefore if you have a high
- sample rate and a small fft size, the fft bins are so large that there
- is a lot of error in determining the frequency of the sine wave.
- ---------------------------------------------------------------------------*/
-
- float *sig=NULL,*fftsig=NULL;
- float *weights=NULL;
- float *fftreal=NULL;
- long num_samps=0,fsize=0;
- float bin_width=0.0;
-
- void cleanup(int exitcode)
- {
- if (sig!=NULL) free(sig);
- if (fftsig!=NULL) free(fftsig);
- if (weights!=NULL) free(weights);
- if (fftreal!=NULL) free(fftreal);
-
- sig=NULL;
- fftsig=NULL;
- weights=NULL;
- fftreal=NULL;
- }
-
-
- float fftmain(long sample_rate, long fft_size, float freq)
- {
- float start,stop,step;
- long n,one=1,two=2;
- float max_val;
- float amp=10;
- long bin;
- long num_samps2;
- float found_freq;
- float duration=0.5;
-
- fsize=fft_size;
- /* tell user what we are going to do */
- printf("Generating sine wave at %f Hz for %d samples.\n",freq,sample_rate);
-
- /* allocate memory */
- printf("Allocating memory.\n");
- num_samps=sample_rate*duration;
- num_samps2=num_samps*2;
- sig=(float *)malloc(num_samps2*sizeof(float));
- n=fft_size*2;
- weights=(float *)malloc(n*sizeof(float));
- fftsig=(float *)malloc(n*sizeof(float));
- fftreal=(float *)malloc(fft_size*sizeof(float));
- vclr_(sig,&one,&num_samps2);
- vclr_(fftsig,&one,&n);
-
- /* generate 1 second sine wave */
- /* using x=Amp sin(theta + 2pi*wt) */
- start=0.0;
- step=2.0*Pi*freq/sample_rate;
- stop=step*(num_samps-1);
- /* generate time series for sine wave (complex)
- could have used vramp instead */
- vgen_(&start,&stop,sig,&two,&num_samps);
- /* create sine wave, skipping every other output sample
- thus creating complex sine wave with imaginary=0; */
- vsin_(sig,&two,sig,&two,&num_samps);
- /* create amplitude */
- vsmul_(sig,&two,&,sig,&two,&num_samps);
-
- /* setup fft_wts - these only needs to be done once */
- /* per program execution with max>fft_size */
- fftwts_(weights,&fft_size,&fft_size);
-
- /* perform complex forward fft */
- printf("Performing %d point FFT\n",fft_size);
- cfftf_(sig,&one,fftsig,&one,&fft_size);
- cfftsc_(fftsig,&fft_size);
- /* convert from complex to real */
- /* remember, data is only valid up til fft_size/2 */
- n=fft_size/2;
- vreal_(fftsig,&one,fftreal,&one,&n);
- /* search for maximum bin */
- maxv_(fftreal,&one,&max_val,&bin,&n);
- /* adjust for the bins we skipped */
- bin-=1;
- printf("located maximum bin=%d\n",bin);
- /* compute bin_width */
- bin_width=(float) sample_rate/(fft_size/2);
- printf("current bin width(Hz)=%f.\n",bin_width);
- /* compute frequency of found signal */
- found_freq=bin_width*bin;
-
- /* make sure we didn't find negative freq */
- if (found_freq>sample_rate/2.0)
- found_freq=sample_rate-found_freq;
- printf("Maximum response found at %fHz.\n",found_freq);
-
- /* free memory, except in test mode */
- #ifndef VIEWOUTPUT
- cleanup(0);
- #endif
- return found_freq;
-
- }
-
-