Audio FFT using STM32L432KC Nucleo and .96" SPI OLED
Dependencies: Adafruit_GFX mbed
main.cpp
- Committer:
- ColoradoRob
- Date:
- 2017-03-23
- Revision:
- 1:947ee109759e
- Parent:
- 0:ac337301f28b
File content as of revision 1:947ee109759e:
#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; } } }