The audio lib has some examples of FFT and analog input. Here is a slightly messy sketch that samples (44.1khz) mic input on Teensy A2 and runs fft1024 and displays FFT cells on tiny OLED (SPI or I2C version). The teensy audio lib manages ADC and FFT with double-buffered DMA @44.1KHz. The example does not require the PJRC audio adaptor board.
Code:
// Spectrum Analyzer using a Teensy 3.2 & OLED 128x32 mono
// Test microphone is connected to A2, I2C and pin 4 or SPI
// https://forum.pjrc.com/threads/45418-FFT-analysis-using-teensy-3-2
#include <SPI.h>
#include <Wire.h>
#include <Audio.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define HT 31
#define WD 128
// define 1 for I2C else 0 will do SPI
#define DOI2C 0
#if DOI2C
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#else
#define OLED_DC 6
#define OLED_CS 7
#define OLED_RESET 8
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
#endif
#define MIC_GAIN 2 // multiplier for the specific mic
//Set-up the audio library functions
AudioInputAnalog adc1(A2); //default for adc1 is A2
AudioAnalyzeFFT1024 fft1024_1;
AudioConnection patchCord1(adc1, fft1024_1);
// An array to hold the 16 frequency bands
float level[16];
void setup() {
Serial.begin(9600);
// while (!Serial);
#if DOI2C
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32)
#else
display.begin(SSD1306_SWITCHCAPVCC);
#endif
display.display(); // splash screen
delay(2000);
#if DOI2C
// TWBR = 12; // I2C @400khz really 333khz
I2C0_F = 0x1a; // I2C analyzer shows 395khz
#endif
#if 0
// benchmark
for (int i = 0; i < 10; i++) {
uint32_t t = micros();
display.display();
t = micros() - t;
Serial.println(t);
delay(1000);
}
#endif
// Audio connections require memory to work.
AudioMemory(12);
// Configure the window algorithm to use
fft1024_1.windowFunction(AudioWindowHanning1024);
}
void spectrum() {
uint32_t t2;
if (fft1024_1.available()) {
// each time new FFT data is available, bin it into 16 channels, octaves
// Note- response doesn't seem flat so each is normalized <experimenting!
// Note- these calculations go very fast!
level[0] = fft1024_1.read(0) * 1.21 * MIC_GAIN;
level[1] = fft1024_1.read(1) * 1.18 * MIC_GAIN;
level[2] = fft1024_1.read(2, 3) * 1.15 * MIC_GAIN;
level[3] = fft1024_1.read(4, 6) * 1.12 * MIC_GAIN;
level[4] = fft1024_1.read(7, 10) * 1.09 * MIC_GAIN;
level[5] = fft1024_1.read(11, 15) * 1.06 * MIC_GAIN;
level[6] = fft1024_1.read(16, 22) * 1.03 * MIC_GAIN;
level[7] = fft1024_1.read(23, 32) * 1.00 * MIC_GAIN;
level[8] = fft1024_1.read(33, 46) * 0.96 * MIC_GAIN;
level[9] = fft1024_1.read(47, 66) * 0.93 * MIC_GAIN;
level[10] = fft1024_1.read(67, 93) * 0.90 * MIC_GAIN;
level[11] = fft1024_1.read(94, 131) * 0.87 * MIC_GAIN;
level[12] = fft1024_1.read(132, 184) * 0.84 * MIC_GAIN;
level[13] = fft1024_1.read(185, 257) * 0.81 * MIC_GAIN;
level[14] = fft1024_1.read(258, 359) * 0.78 * MIC_GAIN;
level[15] = fft1024_1.read(360, 511) * 0.75 * MIC_GAIN;
//***** LCD OUTPUT
t2 = micros();
display.clearDisplay();
for (int i = 0; i < 16; i++) {
int line1 = level[i] * HT;
if (line1 > HT) {
line1 = HT;
}
display.fillRect(i * 8, HT - line1, 6, line1 + 1, 1); // insure a base line of 1
}
display.display();
t2 = micros() - t2;
#if 0
Serial.println(t2);
#endif
}
}
void spectrum_bins() {
// just linear FFT data first 128 bins
int h, i;
uint32_t t2;
if (fft1024_1.available()) {
t2 = micros();
display.clearDisplay();
for (i = 0; i < WD; i++) {
h = 5 * HT * fft1024_1.read(i); // need * MICGAIN ?
// display.drawLine(i, HT - h, i, HT, WHITE);
display.drawFastVLine(i, HT - h, h, WHITE);
}
display.display();
t2 = micros() - t2;
#if 0
Serial.println(t2);
#endif
}
}
void print_fft() {
float n;
int i;
if (fft1024_1.available()) {
// each time new FFT data is available
// print it all to the Arduino Serial Monitor
int printed = 0;
// Serial.print("FFT: ");
for (i = 0; i < 40; i++) {
n = fft1024_1.read(i);
if (n >= 0.04) {
printed = 1;
Serial.print(i); Serial.print(":");
Serial.print(n);
Serial.print(" ");
} else {
//Serial.print(" - "); // don't print "0.00"
}
}
if (printed)Serial.println();
}
}
void loop() {
// pick one
//spectrum(); //octaves
spectrum_bins();
// print_fft();
}
I don't think the mic I was using is available any longer.
OLEDs:
https://www.adafruit.com/product/931
https://www.adafruit.com/product/661