Audio FFT using STM32L432KC Nucleo and .96" SPI OLED

Dependencies:   Adafruit_GFX mbed

Revision:
0:ac337301f28b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Mar 23 00:36:24 2017 +0000
@@ -0,0 +1,86 @@
+#include "mbed.h"
+#include "Adafruit_SSD1306.h"
+#include "arm_math.h"
+
+DigitalOut led(LED1);
+AnalogIn audio_in(PA_0);
+Ticker sampler;
+
+SPI oled_spi(PA_7, PA_6, PA_5);
+Adafruit_SSD1306_Spi oled(oled_spi, PA_11, PB_5, PB_4, 64);
+
+volatile int flag = 0;
+
+#define AMPLITUDE (1.0)    // x * 3.3V
+#define RANGE     (32)
+#define OFFSET    (32)
+
+#define BUFFER_SIZE (128)
+int16_t buffer[BUFFER_SIZE];
+
+void calculate_sinewave(void);
+
+arm_rfft_fast_instance_f32 S;
+float audio_buffer[BUFFER_SIZE * 2];
+float fft_output[BUFFER_SIZE * 2];
+
+void sample()
+{
+    static int16_t count = 0;
+    if (flag) return;
+    audio_buffer[count++] = audio_in * 2.0f - 1.0f;
+    if (count == (BUFFER_SIZE * 2)) {
+        count = 0;
+        flag = 1;
+    }
+}
+
+void do_fft()
+{
+    int32_t sum = 0;
+    arm_rfft_fast_f32 (&S, audio_buffer, fft_output, 0);
+    for (int i = 0; i != BUFFER_SIZE * 2; i += 2) {
+        float n = fft_output[i] * fft_output[i] + fft_output[i + 1] * fft_output[i + 1];
+        buffer[i/2] = 20 * log10(n);    // convert to dB
+        if (i != 0) sum += buffer[i/2]; // ignore DC component
+    }
+    int avg = sum / BUFFER_SIZE;
+    oled.printf("%+02ddB\r", avg);
+    buffer[0] = avg;                // overwrite DC offset
+    for (int i = 0; i != BUFFER_SIZE; ++i) {
+        int offset = 48 - (buffer[i] - int(avg));   // Normalize the values
+        offset = std::max(0, offset);               // Limit to display size
+        offset = std::min(63, offset);
+        oled.drawFastVLine(i, offset, 63, 1);
+    }
+    oled.drawFastHLine(0, 48 - avg / 2, 127, 0);
+    oled.drawFastHLine(0, 47 - avg / 2, 127, 0);
+    oled.drawFastHLine(0, 49 - avg / 2, 127, 0);
+
+}
+
+
+int main() {
+    arm_rfft_fast_init_f32(&S , 256);
+ 
+    oled_spi.frequency(8000000);   
+    oled.begin();
+    wait_ms(200);
+    
+    oled.splash();
+    oled.display();
+    wait(2);
+    oled.clearDisplay();
+    
+    sampler.attach(sample, 1.0 / 6600.0);
+    
+     while(1) {      
+        if (flag) {
+            do_fft();
+            oled.display();
+            oled.clearDisplay();
+            led = !led;
+            flag = 0;
+        }       
+   }
+}