Hello,
I'm working on a light to music project and stuck getting a reliable spectrum.
I'm using a Teensy 3.1 and an Adafruit AGC Electrit Microphone (https://www.adafruit.com/product/1713).
I'm running the teensy through USB for now so that I can use the serial monitor ro view results.
My code is as follows:
The results look good for all but the first two bands. The first two bands seem to latch on to the maximum value experienced...
Those first two bands keep latching onto the max value experienced. What's interesting is that I do see them show lower values as there is sound being calculated, but when it goes quiet, they appear in their 'latched' state.
I remember seeing some example code of Paul's where he skipped the first two bins. That makes me wonder if I should do the same and move on with just 30 bins.
*EDIT*
The scale of the values is 0 - 255
I have seen through the course of one song a the first two bins reading 248 and 196 respectively during silence. While the song is playing, the first bins seem to show properly fluctuating levels.
I'm working on a light to music project and stuck getting a reliable spectrum.
I'm using a Teensy 3.1 and an Adafruit AGC Electrit Microphone (https://www.adafruit.com/product/1713).
I'm running the teensy through USB for now so that I can use the serial monitor ro view results.
My code is as follows:
Code:
// FFT Test
//
// Compute a 1024 point Fast Fourier Transform (spectrum analysis)
// on audio connected to an adafruit AGC Electret Microphone MAX9814
// https://www.adafruit.com/product/1713
//
// The 512 bins are calculated into 32 bins.
//
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#define debug
const unsigned int matrix_width = 32;
const unsigned int matrix_height = 256;
// These parameters adjust the vertical thresholds
const float maxLevel = 0.4; // 1.0 = max, lower is more "sensitive"
const float dynamicRange = 40.0; // total range to display, in decibels
const float linearBlend = 0.3; // useful range is 0 to 0.7
// Create the Audio components. These should be created in the
// order data flows, inputs/sources -> processing -> outputs
AudioInputAnalog adc1(A2);
AudioAnalyzeFFT1024 myFFT;
AudioConnection patchCord1(adc1, myFFT);
// This array specifies how many of the FFT frequency bins to use for each horizontal pixel.
// Because humans hear in octaves, and FFT bins are linear, the low frequencies
// use a small number of bins, higher frequencies use more.
const int lowerFFTBins[] = {0,1,2,3,4,5,6,8,10,12,15,18,22,27,32,38,45,53,63,74,87,102,119,138,160,186,216,250,289,334,385,444};
const int upperFFTBins[] = {0,1,2,3,4,5,7,9,11,14,17,21,26,31,37,44,52,62,73,86,101,118,137,159,185,215,249,288,333,384,443,511};
float thresholdVertical[matrix_height];
float thresholdVert[matrix_height];
void setup() {
analogReadAveraging(4);
AudioMemory(12);
// compute the vertical thresholds before starting
computeVerticalLevels();
for(unsigned int j = 0; j < matrix_height; j++) {
thresholdVert[j] = thresholdVertical[matrix_height-j-1];
}
myFFT.windowFunction(AudioWindowHanning1024);
}
void loop() {
float level;
int maxY;
if (myFFT.available()) {
#ifdef debug
Serial.print("FFT: ");
#else
Serial.write(255);
#endif
float bar[60];
int index = 2;
for (int x = 0; x < matrix_width; x++) {
level = myFFT.read(lowerFFTBins[x], upperFFTBins[x]);
maxY = 0;
for(int y = 0; y < matrix_height; y++){
if(level >= thresholdVert[y]){
maxY = y;
}
}
#ifdef debug
Serial.print(maxY);
Serial.print(" ");
#else
Serial.write(maxY);
#endif
}
#ifdef debug
Serial.println();
#endif
delay(20);
}
}
// Run once from setup, the compute the vertical levels
void computeVerticalLevels() {
unsigned int y;
float n, logLevel, linearLevel;
for (y=0; y < matrix_height; y++) {
n = (float)y / (float)(matrix_height - 1);
logLevel = pow10f(n * -1.0 * (dynamicRange / 20.0));
linearLevel = 1.0 - n;
linearLevel = linearLevel * linearBlend;
logLevel = logLevel * (1.0 - linearBlend);
thresholdVertical[y] = (logLevel + linearLevel) * maxLevel;
}
}
The results look good for all but the first two bands. The first two bands seem to latch on to the maximum value experienced...
Code:
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
FFT: 24 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Those first two bands keep latching onto the max value experienced. What's interesting is that I do see them show lower values as there is sound being calculated, but when it goes quiet, they appear in their 'latched' state.
I remember seeing some example code of Paul's where he skipped the first two bins. That makes me wonder if I should do the same and move on with just 30 bins.
*EDIT*
The scale of the values is 0 - 255
I have seen through the course of one song a the first two bins reading 248 and 196 respectively during silence. While the song is playing, the first bins seem to show properly fluctuating levels.
Last edited: