Teensy 3.1 FFT Adafruit AGC Electret Microphone - first two bins not zeroing out

Status
Not open for further replies.

ksumrall

New member
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:

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:
I was seeing something similar intermittently on my Sparkfun mic breakout and thought the mic was giving an odd value - Then I got distracted doing other stuff first and never got back to it.

One ran fine for days on my downstairs desktop I could see when I breathed or clicked my mouse - then it started acting oddly . . .
 
By any chance is there a small dc offset on your mic input that accounts for bins 0 & 1? Bin 0 is the dc level, and that will be "smeared" into 1 by the Hanning window function.
 
There is a 1.25 dc offset with a 1Vpp swing. That will leave at least a 0.25V value. I'm sure that has some influence on the values, but I don't see how that would cause the values in those two bins only to continually rise and latch during silence.
 
B.Jacquot -
I have just created a video to demonstrate my observations - https://youtu.be/TQP7IqIM3zI.
I tried a microphone without AGC which produced better results. Here's a link to the mic on ebay.
I think it does have something to do with AGC, but not sure what. Electronics is hard.
Until I have a better understanding of what is happening, I'll either use the mic without AGC or use the mic with AGC and ignore the first two bins.
Any thoughts?
 
Last edited:
Status
Not open for further replies.
Back
Top