Craig Evans / Mbed 2 deprecated AudioIn

Dependencies:   N5110 mbed

Committer:
eencae
Date:
Tue Jul 22 15:03:32 2014 +0000
Revision:
0:a497562bb2f9
Child:
1:7c6c1f98b8f5
Initial version.; ; Reads in audio signal through ADC (signal needs externally biasing at Vcc/2).; ; Performs FFT on signal and extracts highest frequency component.; ; Also gets the RMS power in each set of samples and display a bar graph on the LEDs.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eencae 0:a497562bb2f9 1 #include "mbed.h"
eencae 0:a497562bb2f9 2
eencae 0:a497562bb2f9 3 extern "C" void fftR4(short *y, short *x, int N);
eencae 0:a497562bb2f9 4
eencae 0:a497562bb2f9 5 float magnitude(short y1, short y2);
eencae 0:a497562bb2f9 6 void updateSamples();
eencae 0:a497562bb2f9 7 void doFFT();
eencae 0:a497562bb2f9 8 void printSpectrum();
eencae 0:a497562bb2f9 9 void printSamples();
eencae 0:a497562bb2f9 10 void barGraph();
eencae 0:a497562bb2f9 11 int calcPeakFrequency();
eencae 0:a497562bb2f9 12
eencae 0:a497562bb2f9 13 AnalogIn audio(p17);
eencae 0:a497562bb2f9 14 BusOut leds(LED1,LED2,LED3,LED4);
eencae 0:a497562bb2f9 15 LocalFileSystem local("local"); // Create the local filesystem under the name "local"
eencae 0:a497562bb2f9 16 Timer timer;
eencae 0:a497562bb2f9 17 Serial serial(USBTX,USBRX);
eencae 0:a497562bb2f9 18
eencae 0:a497562bb2f9 19 #define BUF_LEN 1024
eencae 0:a497562bb2f9 20 #define SAMP_FREQ 10000
eencae 0:a497562bb2f9 21
eencae 0:a497562bb2f9 22 short samples[BUF_LEN];
eencae 0:a497562bb2f9 23 short mx[BUF_LEN*2]; // input data 16 bit, 4 byte aligned x0r,x0i,x1r,x1i,....
eencae 0:a497562bb2f9 24 short my[BUF_LEN*2]; // output data 16 bit,4 byte aligned y0r,y0i,y1r,y1i,....
eencae 0:a497562bb2f9 25 float spectrum[BUF_LEN/2];
eencae 0:a497562bb2f9 26
eencae 0:a497562bb2f9 27 int main()
eencae 0:a497562bb2f9 28 {
eencae 0:a497562bb2f9 29 serial.baud(115200);
eencae 0:a497562bb2f9 30 leds = 15;
eencae 0:a497562bb2f9 31 wait(2.0);
eencae 0:a497562bb2f9 32 leds = 0;
eencae 0:a497562bb2f9 33
eencae 0:a497562bb2f9 34 int tone;
eencae 0:a497562bb2f9 35
eencae 0:a497562bb2f9 36 while(1) {
eencae 0:a497562bb2f9 37
eencae 0:a497562bb2f9 38 updateSamples();
eencae 0:a497562bb2f9 39 barGraph();
eencae 0:a497562bb2f9 40 doFFT();
eencae 0:a497562bb2f9 41 //printSpectrum();
eencae 0:a497562bb2f9 42 //printSamples();
eencae 0:a497562bb2f9 43 tone = calcPeakFrequency();
eencae 0:a497562bb2f9 44 serial.printf("f = %u\n",tone);
eencae 0:a497562bb2f9 45 wait_ms(10);
eencae 0:a497562bb2f9 46
eencae 0:a497562bb2f9 47 }
eencae 0:a497562bb2f9 48 }
eencae 0:a497562bb2f9 49
eencae 0:a497562bb2f9 50 void barGraph()
eencae 0:a497562bb2f9 51 {
eencae 0:a497562bb2f9 52 float rms = 0.0;
eencae 0:a497562bb2f9 53 for (int i = 0; i < BUF_LEN; i++) {
eencae 0:a497562bb2f9 54 rms+= samples[i]*samples[i];
eencae 0:a497562bb2f9 55 }
eencae 0:a497562bb2f9 56 rms/=BUF_LEN;
eencae 0:a497562bb2f9 57 rms = sqrt(rms);
eencae 0:a497562bb2f9 58 rms/= 16384.0; // scale according to 16-bit signed maximum value
eencae 0:a497562bb2f9 59
eencae 0:a497562bb2f9 60 if (rms > 0.8) {
eencae 0:a497562bb2f9 61 leds = 15;
eencae 0:a497562bb2f9 62 } else if (rms > 0.6) {
eencae 0:a497562bb2f9 63 leds = 7;
eencae 0:a497562bb2f9 64 } else if (rms > 0.4) {
eencae 0:a497562bb2f9 65 leds = 3;
eencae 0:a497562bb2f9 66 } else if (rms > 0.2) {
eencae 0:a497562bb2f9 67 leds = 1;
eencae 0:a497562bb2f9 68 } else {
eencae 0:a497562bb2f9 69 leds = 0;
eencae 0:a497562bb2f9 70 }
eencae 0:a497562bb2f9 71
eencae 0:a497562bb2f9 72 serial.printf("RMS = %f\n",rms);
eencae 0:a497562bb2f9 73 }
eencae 0:a497562bb2f9 74
eencae 0:a497562bb2f9 75 float magnitude(short y1, short y2)
eencae 0:a497562bb2f9 76 {
eencae 0:a497562bb2f9 77 return sqrt(float(y1*y1+y2*y2));
eencae 0:a497562bb2f9 78 }
eencae 0:a497562bb2f9 79
eencae 0:a497562bb2f9 80 void updateSamples()
eencae 0:a497562bb2f9 81 {
eencae 0:a497562bb2f9 82 for (int i = 0; i < BUF_LEN; i++) {
eencae 0:a497562bb2f9 83 samples[i] = (short) (audio.read_u16() - 0x8000); // read unsigned 16-bit and convert to signed 16-bit (subtract 32768)
eencae 0:a497562bb2f9 84 wait_us(1e6/SAMP_FREQ);
eencae 0:a497562bb2f9 85 }
eencae 0:a497562bb2f9 86 }
eencae 0:a497562bb2f9 87
eencae 0:a497562bb2f9 88 void doFFT()
eencae 0:a497562bb2f9 89 {
eencae 0:a497562bb2f9 90 for (int i=0; i<2*BUF_LEN; i++) {
eencae 0:a497562bb2f9 91 my[i] = 0;
eencae 0:a497562bb2f9 92 mx[i] = 0;
eencae 0:a497562bb2f9 93 }
eencae 0:a497562bb2f9 94
eencae 0:a497562bb2f9 95 for (int i=0; i<BUF_LEN; i++) { // load samples in array (skip imaginiary input values)
eencae 0:a497562bb2f9 96 mx[i*2]=samples[i];
eencae 0:a497562bb2f9 97 }
eencae 0:a497562bb2f9 98
eencae 0:a497562bb2f9 99 fftR4(my, mx, BUF_LEN); // call FFT routine
eencae 0:a497562bb2f9 100
eencae 0:a497562bb2f9 101 int j = 0;
eencae 0:a497562bb2f9 102 for (int i = 0; i < BUF_LEN; i+=2) {
eencae 0:a497562bb2f9 103 spectrum[j] = magnitude(my[i],my[i+1]);
eencae 0:a497562bb2f9 104 j++;
eencae 0:a497562bb2f9 105 }
eencae 0:a497562bb2f9 106 }
eencae 0:a497562bb2f9 107
eencae 0:a497562bb2f9 108 void printSpectrum()
eencae 0:a497562bb2f9 109 {
eencae 0:a497562bb2f9 110 FILE *fp = fopen("/local/fft.csv","w");
eencae 0:a497562bb2f9 111 //now write a CSV file to filesytem of frequency vs amplitude
eencae 0:a497562bb2f9 112 int j = 0;
eencae 0:a497562bb2f9 113 for (int i = 0; i < BUF_LEN; i+=2) {
eencae 0:a497562bb2f9 114 int frequency = int(SAMP_FREQ/BUF_LEN/2*i);
eencae 0:a497562bb2f9 115 fprintf(fp, "%d,%f\n", frequency, spectrum[j]);
eencae 0:a497562bb2f9 116 j++;
eencae 0:a497562bb2f9 117 }
eencae 0:a497562bb2f9 118 fclose(fp);
eencae 0:a497562bb2f9 119 }
eencae 0:a497562bb2f9 120
eencae 0:a497562bb2f9 121 void printSamples()
eencae 0:a497562bb2f9 122 {
eencae 0:a497562bb2f9 123 FILE *fp = fopen("/local/samples.csv","w");
eencae 0:a497562bb2f9 124 //now write a CSV file to filesytem of frequency vs amplitude
eencae 0:a497562bb2f9 125 for (int i = 0; i < BUF_LEN; i++) {
eencae 0:a497562bb2f9 126 fprintf(fp, "%d\n", samples[i]);
eencae 0:a497562bb2f9 127 }
eencae 0:a497562bb2f9 128 fclose(fp);
eencae 0:a497562bb2f9 129 }
eencae 0:a497562bb2f9 130
eencae 0:a497562bb2f9 131 int calcPeakFrequency()
eencae 0:a497562bb2f9 132 {
eencae 0:a497562bb2f9 133 float max = 0.0;
eencae 0:a497562bb2f9 134 int frequency = 0;
eencae 0:a497562bb2f9 135 int j = 0;
eencae 0:a497562bb2f9 136 for (int i=0; i<BUF_LEN; i+=2) {
eencae 0:a497562bb2f9 137 if (spectrum[j] > max) {
eencae 0:a497562bb2f9 138 max = spectrum[j];
eencae 0:a497562bb2f9 139 frequency = int(SAMP_FREQ/BUF_LEN/2*i);
eencae 0:a497562bb2f9 140 }
eencae 0:a497562bb2f9 141 j++;
eencae 0:a497562bb2f9 142 }
eencae 0:a497562bb2f9 143 return frequency;
eencae 0:a497562bb2f9 144 }