home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / univspl / fftmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-02  |  3.3 KB  |  113 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include "uspl.h"
  5. #include "fftmain.h"
  6. /*---------------------------------------------------------------------------
  7. Some important notes and issues regarding this program.
  8. remember, the frequency of the sine wave you are generating
  9. *must* be < sample_rate/2, or the waveform will be aliased.
  10. The resolution of the fft in determining the frequency generated
  11. is dependant on sample_rate/fft_size, therefore if you have a high
  12. sample rate and a small fft size, the fft bins are so large that there
  13. is a lot of error in determining the frequency of the sine wave.
  14. ---------------------------------------------------------------------------*/
  15.  
  16. float *sig=NULL,*fftsig=NULL;
  17. float *weights=NULL;
  18. float *fftreal=NULL;
  19. long num_samps=0,fsize=0;
  20. float bin_width=0.0;
  21.  
  22. void cleanup(int exitcode)
  23. {
  24.    if (sig!=NULL) free(sig);
  25.    if (fftsig!=NULL) free(fftsig);
  26.    if (weights!=NULL) free(weights);
  27.    if (fftreal!=NULL) free(fftreal);
  28.  
  29.    sig=NULL;
  30.    fftsig=NULL;
  31.    weights=NULL;
  32.    fftreal=NULL;
  33. }
  34.  
  35.  
  36. float fftmain(long sample_rate, long fft_size, float freq)
  37. {
  38. float start,stop,step;
  39. long n,one=1,two=2;
  40. float max_val;
  41. float amp=10;
  42. long bin;
  43. long num_samps2;
  44. float found_freq;
  45. float duration=0.5;
  46.  
  47. fsize=fft_size;
  48. /* tell user what we are going to do */
  49. printf("Generating sine wave at %f Hz for %d samples.\n",freq,sample_rate);
  50.  
  51. /* allocate memory */
  52. printf("Allocating memory.\n");
  53. num_samps=sample_rate*duration;
  54. num_samps2=num_samps*2;
  55. sig=(float *)malloc(num_samps2*sizeof(float));
  56. n=fft_size*2;
  57. weights=(float *)malloc(n*sizeof(float));
  58. fftsig=(float *)malloc(n*sizeof(float));
  59. fftreal=(float *)malloc(fft_size*sizeof(float));
  60. vclr_(sig,&one,&num_samps2);
  61. vclr_(fftsig,&one,&n);
  62.  
  63. /* generate 1 second sine wave */
  64. /* using x=Amp sin(theta + 2pi*wt) */
  65. start=0.0;
  66. step=2.0*Pi*freq/sample_rate;
  67. stop=step*(num_samps-1);
  68. /* generate time series for sine wave (complex)
  69.    could have used vramp instead */
  70. vgen_(&start,&stop,sig,&two,&num_samps);
  71. /* create sine wave, skipping every other output sample
  72.    thus creating complex sine wave with imaginary=0; */
  73. vsin_(sig,&two,sig,&two,&num_samps);
  74. /* create amplitude */
  75. vsmul_(sig,&two,&,sig,&two,&num_samps);
  76.  
  77. /* setup fft_wts - these only needs to be done once */
  78. /* per program execution with max>fft_size */
  79. fftwts_(weights,&fft_size,&fft_size);
  80.  
  81. /* perform complex forward fft */
  82. printf("Performing %d point FFT\n",fft_size);
  83. cfftf_(sig,&one,fftsig,&one,&fft_size);
  84. cfftsc_(fftsig,&fft_size);
  85. /* convert from complex to real */
  86. /* remember, data is only valid up til fft_size/2 */
  87. n=fft_size/2;
  88. vreal_(fftsig,&one,fftreal,&one,&n);
  89. /* search for maximum bin */
  90. maxv_(fftreal,&one,&max_val,&bin,&n);
  91. /* adjust for the bins we skipped */
  92. bin-=1;
  93. printf("located maximum bin=%d\n",bin);
  94. /* compute bin_width */
  95. bin_width=(float) sample_rate/(fft_size/2);
  96. printf("current bin width(Hz)=%f.\n",bin_width);
  97. /* compute frequency of found signal */
  98. found_freq=bin_width*bin;
  99.  
  100. /* make sure we didn't find negative freq */
  101. if (found_freq>sample_rate/2.0)
  102.    found_freq=sample_rate-found_freq;
  103. printf("Maximum response found at %fHz.\n",found_freq);
  104.  
  105. /* free memory, except in test mode */
  106. #ifndef VIEWOUTPUT
  107. cleanup(0);
  108. #endif
  109. return found_freq;
  110.  
  111. }
  112.  
  113.