Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of audio_FFT by
main.cpp
00001 00002 #define SAMPLE_RATE 48000 00003 00004 #include "mbed.h" 00005 #include "adc.h" 00006 00007 //Going to use the Mellen FFT rather than STM, as the STM (port by Igor) won't compile 00008 //extern "C" void cr4_fft_256_stm32(void *pssOUT, void *pssIN, uint16_t Nbin); 00009 extern "C" void fftR4(short *y, short *x, int N); 00010 00011 //use the LED as a bargraph 00012 DigitalOut l1(LED1); 00013 DigitalOut l2(LED1); 00014 DigitalOut l3(LED1); 00015 DigitalOut l4(LED1); 00016 00017 //set up a timer for timing FFT's 00018 Timer timer; 00019 00020 //Set up filesystem so we can write some useful files 00021 00022 LocalFileSystem local("local"); 00023 FILE *fp; 00024 00025 //Set up a global buffer for audio data so interrupt can access it 00026 int Counter = 0; 00027 int16_t Buffer[5000]; 00028 00029 //Initialise ADC to maximum SAMPLE_RATE and cclk divide set to 1 00030 ADC adc(SAMPLE_RATE, 1); 00031 00032 //Functions to write 16 bit audio data and 32 bit headers to files in au format (cf sndRecorder Cookbook) 00033 void fwrite16(uint16_t v) 00034 { 00035 uint8_t *b = (uint8_t *)&v; 00036 00037 fprintf(fp,"%c%c", b[1], b[0]); 00038 } 00039 void fwrite32(uint32_t v) 00040 { 00041 uint8_t *b = (uint8_t *)&v; 00042 00043 fprintf(fp,"%c%c%c%c", b[3], b[2], b[1], b[0]); 00044 } 00045 00046 //Our interrupt handler for audio sampling 00047 void sample_ADC(int chan, uint32_t value) { 00048 00049 float s; 00050 s = adc.read(p20); 00051 int16_t b = (s -2048)*16; 00052 Buffer[Counter] = b; 00053 Counter += 1; 00054 /* bar graph */ 00055 int g = abs(s-2048); 00056 l1 = g > 0.1f*2048; 00057 l2 = g > 0.3f*2048; 00058 l3 = g > 0.6f*2048; 00059 l4 = g > 0.8f*2048; 00060 } 00061 00062 int main() { 00063 00064 //Prepare for burst mode on all ADC pins and set up interrupt handler (using ADC library from Simon Blandford 00065 adc.append(sample_ADC); 00066 adc.startmode(0,0); 00067 adc.burst(1); 00068 adc.setup(p20,1); 00069 00070 //introduce a delay as initial waveform has bias whilst decoupling cap charges 00071 wait(1); 00072 00073 //start the interrupt and wait for about 4096 samples 00074 adc.interrupt_state(p20,1); 00075 wait(0.1); 00076 00077 //Finsh up - Unset pin 20 00078 adc.interrupt_state(p20,0); 00079 adc.setup(p20,0); 00080 int actual_rate = adc.actual_sample_rate(); 00081 00082 //for debugging tell the terminal sample rate and how many samples we took 00083 printf("Requested max sample rate is %u, actual max sample rate is %u.\n", 00084 SAMPLE_RATE, actual_rate); 00085 printf("We did %i samples\n",Counter); 00086 00087 //write original audio file to filesytem so we can load on PC and see what's there (cf sndRecorder Cookbook) 00088 fp = fopen("/local/out.au", "w"); 00089 fprintf(fp,".snd"); 00090 fwrite32(24); 00091 fwrite32(-1); 00092 fwrite32(3); 00093 fwrite32(48000); 00094 fwrite32(1); 00095 int writeCount = 0; 00096 while(writeCount <=Counter) { 00097 fwrite16(Buffer[writeCount]); 00098 writeCount+=1; 00099 } 00100 00101 //Not using the STM FFT, but leave code here for the moment 00102 00103 /* 00104 //now do a fft of the initial 1024 samples 00105 #define N 256 //Number of points 00106 uint32_t x[N], y[N]; // input and output arrays 00107 int16_t real[N], imag[N]; // real and imaginary arrays 00108 memset(real, 0, sizeof(real)); 00109 memset(imag, 0, sizeof(imag)); 00110 // real[1]=SHRT_MAX; 00111 // Fill the input array 00112 for (int i=0; i<N; i++) 00113 { 00114 x[i] = (((uint16_t)(Buffer[i])) | ((uint32_t)(0<<16))); 00115 } 00116 timer.reset(); 00117 timer.start(); 00118 cr4_fft_256_stm32(y, x, N); //computes the FFT of the x[N] samples 00119 printf("ST32 fft up took %i\n",timer.read_us()); 00120 FILE* log = fopen("/local/stm32.txt","w"); 00121 for (int i=0; i<N; i++) 00122 { 00123 fprintf(log, "%d: %d, %d -> %d, %d\n", i, Buffer[i], 0 , int16_t(y[i] & 0xFFFF), int16_t(y[i] >> 16)); 00124 } 00125 fclose(log); 00126 00127 //compute frequencies and magnitudes of result 00128 FILE* spectrum = fopen("/local/stm32Spec.txt","w"); 00129 for (int i=0; i<N/2; i++) 00130 { 00131 float real = int16_t(y[i] & 0xFFFF)* int16_t(y[i] & 0xFFFF); 00132 float imag = int16_t(y[i] >> 16)* int16_t(y[i] >> 16); 00133 fprintf(spectrum, "%d -> %f\n", int(SAMPLE_RATE/N*i),sqrt(imag+real)); 00134 } 00135 fclose(spectrum); 00136 */ 00137 00138 //now lets try mellen fft 00139 timer.reset(); 00140 timer.start(); 00141 #define MN 1024 /*Number of points*/ 00142 short mx[MN*2]; // input data 16 bit, 4 byte aligned x0r,x0i,x1r,x1i,.... 00143 short my[MN*2]; // output data 16 bit,4 byte aligned y0r,y0i,y1r,y1i,.... 00144 for (int i=0;i<MN*2;i++) mx[i]=0; 00145 for (int i=0;i<MN;i=i+1) 00146 { mx[i*2]=Buffer[i];} 00147 printf("Mellen set up took %i\n",timer.read_us()); 00148 //call functions 00149 timer.reset(); 00150 timer.start(); 00151 fftR4(my, mx, MN); 00152 printf("Mellen fft took %i\n",timer.read_us()); 00153 FILE* mlog = fopen("/local/mellen.csv","w"); 00154 00155 //now write a CSV file to filesytem of frequency vs amplitude 00156 for (int i=0; i<MN; i=i+2) 00157 { 00158 // fprintf(mlog, "%d: %d -> %d\n", i, mx[i], my[i]); 00159 fprintf(mlog, "%d,%f\n", int(actual_rate/MN/2*i),sqrt(float( (my[i]*my[i]) +(my[i+1]*my[i+1]) ) ) ); 00160 } 00161 fclose(mlog); 00162 00163 00164 } 00165 00166 00167 00168 00169
Generated on Wed Jul 13 2022 01:32:39 by
