Help with Basic Audio Lib results

Davidelvig

Well-known member
I'm getting results I don't understand from this setup on a Teensy 3.2:
Audio GUI shot.png
and this physical setup
Audio Physical Setup.jpg
The mic is an Adafruit Max4466
HTML:
https://www.adafruit.com/products/1063

and using this code:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputAnalog         adc1;           //xy=181,127
AudioAnalyzeRMS          rms1;           //xy=431,168
AudioAnalyzePeak         peak1;          //xy=433,130
AudioAnalyzeFFT1024      fft1024_1;      //xy=439,211
AudioConnection          patchCord1(adc1, peak1);
AudioConnection          patchCord2(adc1, rms1);
AudioConnection          patchCord3(adc1, fft1024_1);
// GUItool: end automatically generated code

void setup() {
      Serial.begin(9600);
      delay(1000);
      Serial.println("Teensy Audio AudioMemory()");
      AudioMemory(10);
}

int pk = 1, rm = 1, ff = 1;
int delayValue = 100;
unsigned long loopCount = 0;

void loop() {
      Serial.printf("----%lu----\n", loopCount);
      if (peak1.available()) {
            pk = (int)(peak1.read() * 100);
            for (int i = 0; i < pk; i++) {
                Serial.print("p"); 
            }
            Serial.printf("\tPeak: %d\n", pk);
      } else {
            Serial.println("peak1 not available");
      }
      if (rms1.available()) {
            rm = (int)(rms1.read() * 100);
            for (int i = 0; i < rm; i++) {
                Serial.print("r"); 
            }
            Serial.printf("\tRMS: %d\n", rm);
      } else {
            Serial.println("rms1 not available"); 
      }
      if (fft1024_1.available()) {
            float fftAccumulator = 0;
            for (int i = 0; i < 512; i++) {
                  fftAccumulator += fft1024_1.read(i);
            }
            ff = (int)(fftAccumulator * 100);
            for (int i = 0; i < ff; i++) {
                  Serial.print("f"); 
            }
            Serial.printf("\tFFT: %d\n", ff);
      } else {
           Serial.println("fft1024_1 not available");
      }
      
      loopCount++;
      
      delay(delayValue); // Delay for a period of time (in milliseconds).

}

Serial monitor results start with
Teensy Audio AudioMemory()
----0----
peak1 not available
rms1 not available
fft1024_1 not available
----1----
Peak: 0
RMS: 0
FFT: 0
----2----
Peak: 0
RMS: 0
FFT: 0

Sound input cause all three measures to respond appropriately, but with an increasing, and eventually fixed, non-zero baseline... always (in my setup) with values of 36, 36 and 57.

----141----
pppppppppppppppppppppppppppppppppppp Peak: 36
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr RMS: 36
fffffffffffffffffffffffffffffffffffffffffffffffffffffffff FFT: 57
----142----
pppppppppppppppppppppppppppppppppppp Peak: 36
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr RMS: 36
fffffffffffffffffffffffffffffffffffffffffffffffffffffffff FFT: 57
----143----
pppppppppppppppppppppppppppppppppppp Peak: 36
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr RMS: 36
fffffffffffffffffffffffffffffffffffffffffffffffffffffffff FFT: 57
----144----
pppppppppppppppppppppppppppppppppppp Peak: 36
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr RMS: 36
fffffffffffffffffffffffffffffffffffffffffffffffffffffffff FFT: 57
----145----
pppppppppppppppppppppppppppppppppppp Peak: 36
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr RMS: 36
fffffffffffffffffffffffffffffffffffffffffffffffffffffffff FFT: 57

I'd expect the values to return to (or near) zero.
I'm also expecting I've missed something fundamental.

What am I missing?
Thanks in advance!
 
Last edited:
You have a chance to be a audio library hero to me with a 5 minute inspection.
Really!
Any takers?
 
Well, i guess, without the mic (your yellow cable connected to GND), the output will be (almost) zero for all - right ?
 
I took 30 seconds - my nearest history is I tried to use a sparkfun mic doing FFT's and on occasion rather than going quiet it would exhibit noise with no sound and then the noise overwhelmed the sound. It has been over a year since I saw that and moved on - hopefully I described it well enough - does that sound like what you are seeing? When I took a manual Adafruit FFT sample it ran for days.

I'd suggest scanning the Audio Tutorial for a usable similar sample (changing the input to mic) that prints the FULL FFT - to Serial or a TFT display if you have that. My effort was before that was published - and I worked through that without trying the following - though I did enable the TFT display to show the FFT's as I did that. With that put together on a known sample either it won't happen - or will make clear what is wrong in the display or that there is some problem that could then be debugged?
 
Thanks Frank B - The Mic ground pin is connected to AGND - the far right white wire is not really clear.

and thank you, defragster. I'll output the FFT to a visualizer and post the results to see if it tells the story on Mic noise.

My aim is to get a relatively clean mic input without using the Audio Shield (I can get clean input with a similar electret on the Audio Shield)
I have a few of the Audio Shields, but due to pin-conflicts and library interrupts-competing with LED libraries, I'm seeking an off-shield solution.
 
Nope, i really meant the yellow cable - the ADC input - try to connect it to GND to take the mic out of the equation.
If the output is zero, then noise from the MIC is the problem.
 
That seems like a good idea Frank - I should have tried that. I did not and got moved away from that, and now I don't know if it was mic input making the noise or something in the system feeding on itself.

Not sure if this is a good idea - except/even for programmatic testing?: Parallel wire in an unused pin with the mic to selectively ground it?
[Only because then you don't have to touch the circuit when seeing the failed state]

This thread : Are-Teensy3-2-Pins-High-Low-and-Tri-State suggests if that pin is input - or later per FrankB Disabled - it should have minimal influence on the mic signal (small current & small impedance). Then in the code when you detect the silent mic not going to 0, trigger that pin:
pinMode( pinNumber, OUTPUT );
digitalWrite( pinNumber, LOW );
and see if the noise stops? - then return it to INPUT or do Frank's disable to return to the run state? YMMV - to auto trigger and reset for a One_Shot fix or 'some time' or add button or USB input commands to make this happen.
 
Have you tried checking the DC bias voltage? A voltmeter can just measure it, since it'll (mostly) ignore any AC signal due to sound.

By default the audio library uses a 1.2V signal range and expects the DC bias voltage to be approx 0.6 volts. Maybe this Adafruit product uses a higher voltage?
 
Thanks, all.
I checked (now that I know the lingo) and the DC bias is VCC/2 - from the Adafruit site...
The output will have a DC bias of VCC/2 so when its perfectly quiet, the voltage will be a steady VCC/2 volts (it is DC coupled). If the audio equipment you're using requires AC coupled audio, place a 100uF capacitor between the output pin and the input of your device. If you're connecting to an audio amplifier that has differential inputs or includes decoupling capacitors, the 100uF cap is not required.

The measured DC voltage is indeed 1.66V

I put in a 100 micro-F capacitor between the mic output and the teensy input.
I get the same behavior from Peak, RMS and FFT (plateaus at 36, 36, 57... and then decays a bit over a period of silence), though a lesser voltage, ranging over time between a 1V and 1.4V

Is this not the microphone for me my Teensies?

If not, I'd welcome a recommendation.
I tried the electret and other mics using the diagram in the GUI for the adc object - realizing after a long time that I need to amplify the signal.

Thanks
 
Added FFT graph of a sung note (457 Hz) and then silence, one second apart.
Screen Shot 2016-12-01 at 11.12.29 PM.jpg
Note, before the sung note, all bins were at zero.
After the sung note stops, bin 1 persists at that monstrous peak.

Same code as before, but with calls to my FFT routines replacing the crude FFT bin-sum.
Code:
      float freq = getFreqFFT(0.9);  // the 0.9 is my "confidence" factor required
      int note = getMIDINote(freq);
      Serial.printf("getFreqFFT() = %f\tgetMIDINote() = %d\n", freq, note);
      graphFFTBins();
      
//      if (FFT.available()) {
//          float fftAccumulator = 0;
//          for (int i = 0; i < 512; i++) {
//                fftAccumulator += FFT.read(i);
//          }
//          ff = (int)(fftAccumulator * 100);
//          for (int i = 0; i < ff; i++) {
//              Serial.print("f"); 
//          }
//          Serial.printf("\tFFT: %d\n", ff);
//      } else {
//          Serial.println("FFT not available");
//      }
      delay(1000);
So, I have a Mic delivering VCC/2 bias, which is not ideal.
Even with this setup, Audio Lib plus my FFT functions appear to be behaving well in pitch determination (matches my iPhone pitch app within a few Hz).

Other debugging - After the 36,36,57 plateau in Peak/RMS/FFT Accumulator is reached, I connect the A2 Input wire to AGND. There is a spike in Peak, RMS and FFT Accumulator up to the max, followed by rapid return to the 36,36,57 values - with the mic totally out of circuit.

Do the Peak and RMS values make sense as a Mic-noise or Mic-bias problem?
Is there a mic I can buy for this Audio-shield-less setup that is correctly-biased & low-noise?
i.e. What's the ideal setup for using the adc audio input object without the audio shield
I'm happy to use this RC setup - which looks like it might establish a correct bias... and do some filtering
adccircuit.png
with an appropriate "audio input" as indicated on the image.
What's that appropriate audio input?
 
IIRC the bin1 overload/persistence is what I saw.

If you want to try independent reference code - that may show your mic to be working:
Looking at Adafruit - this is Teensy 3 based, but not sure this is the one I ran {link}
Code download has toneinput.ino and spectrum.ino that do internal ARM FFT. It is the only relevant Adafruit Teensy_FFT. Whatever I found early last year I don't see on my systems now.

If that is what I used - with some tweaking - it seems I had screen print not LED's showing the buckets and gave a good view and sitting on my desk showed "0==silence" until I touched/moved my mouse or chair, keyboard, breathed, etc for days on the same mic that was not working well seeing result similar to yours.
 
Why don't you connect the DAC output A14 to an amplifier (through a 1uF cap) and listen to what you are actually getting? If it is noise, you will hear it.
The 36 reading you are getting represents a 0.36 count, which is about right for the voltage you are applying to the input pin. The RMS value can be between 0 and 1. Mid-value would be 0.5 so you are getting what I would expect.
 
Paul, The DC Offset is 1.47V per my oscilloscope (measuring at the "out" on the MAX4466). Peak-to-peek is up to the 3.3V (it clips there - I imagine since that's the voltage applied).

The wave form looks like a smooth sine wave in the o-scope. Input sound is a sine wave from a tuner app on my iPhone, played into the mic.
- Is this mic offset going to work with the Teensy adc input?
- If not, should I voltage-divide it down to the 0.6V range?
- Do you know of a mic board with this 0.6 offset off-the-shelf?
 
Last edited:
Here's my suggestion to get that Adafruit MAX4466 mic to work.

First, you need to remove the 1M resistor near the center of the board.

mic1.jpg
(on all these images, click for full size)

Then solder a 221K or 220K resistor in its place.

mic2.jpg

With this mod, you can then power it from 3.3V and connect the output directly to Teensy 3.2's analog input pin. To check if this worked, use a DC voltmeter. You should see approximately 0.59 volts. If you set your voltmeter to AC mode, you should see nearly zero volts when the room is silent, and fluctuations when you make sounds.

mic3.jpg

Another optional step would be adding a 220 ohm resistor between Teensy's 3.3V and the mic power input, and a 100 uF capacitor. This will filter away any audible noise which might be present on the 3.3V line. Adafruit's design has pretty much no filtering (two ferrite beads, but no decoupling capacitor), so any noise on the power supply is likely to end up in your audio signal.

mic4.jpg

You might experiment with using AGND or regular GND. Either is probably fine.
 
OK, I'm close. With an unmodified Adafruit MAX4466 and this setup:
Adafruit Mic with Teensy.jpg
I get an appropriate signal from a played-in sine wave.
It has a 1.6V offset (half of VCC) and a decent amplitude.
I think I'm looking for a 0.6V offset.
I note that you're referred to this thread in the ADC reference in the Audio GUI tool.
Were you referring to the replaced-resistor-on-the-MAX4466, or the external RC solution?

I'll see what this looks like in the Audio library's outputs (peak.read() and RMS.read()).
 
Were you referring to the replaced-resistor-on-the-MAX4466, or the external RC solution?

The external RC is not a solution. It's merely an optional extra, to clean up the power supply voltage being fed to the sensitive mic circuitry.

To make this work, you must replace the 1M resistor with 221K or 220K.
 
The external RC is not a solution. It's merely an optional extra, to clean up the power supply voltage being fed to the sensitive mic circuitry.

To make this work, you must replace the 1M resistor with 221K or 220K.

OK with RC filter.

changing 1M to 220k only if DC coupled, right?
what about AC coupling and providing 0.6V bias with interfacing circuit, or using 3.3V as Vref in Audio library?
what are the pro an cons?
 
Is there a reasonable alternative that does not require SMD soldering? Maybe a different microphone?
 
FYI - I tried changing that 1Meg to a 220K on a couple of the Adafruit MAX4466 microphone modules. Unfortunately, both exhibited a high level 1.2KHz ringing on the output. I changed one back and the output returned to normal. I suspect that the amp doesn't like being biased that far away from mid-supply. I'm going to go back to the recommended bias circuit to move the signal to the recommended 0.6V level.

It would be great for a future library mod to be able to set that offset via a parameter. I'm assuming that you're subtracting the offset somewhere to make the math work out.
 
I haven't found an alternative microphone module with a 0.6 output offset. Most are biased to mid-supply, like this one: https://www.sparkfun.com/products/12758

This would still require that we change R3 from 10K to 2.2K to shift that output down (at 3.3V supply). I don't have any to try out, but will get some on order.
 
I'm glad you posted, Neutronned. I just receive a four new AdaFruit miss and a box of SMD resistors to start my rework task. I view it as daunting, and skipping that for now is OK with me.

What is the "recommended bias circuit" you speak of?

Is it the circuit from the GUI Audi Designer tool:

adccircuit.png

and using the AdaFruit mic as the Audio Input?
 
Yes, that's the one! I've used that same circuit with line inputs from a headphone output and it works fine. Should work with any microphone module because it AC couples the input to the Teensy, while setting the bias to 0.6V. That said, I keep thinking that a simpler circuit might be possible. Mic.jpeg
 
@Davidelvig says that he gets good input using the audio shield so I'm just going to do that. This multi-day debate on how to use the mic directly on the ADC is not worth my time. Besides, I can use the SD socket. Sometimes it's better to be pragmatic than elegant.

If I decide to come back to this, I'll look at modifying the libraries. I'm a software person, not a hardware person, so I'd much rather hack the libraries than solder SMD.
 
Yes, that's the one! I've used that same circuit with line inputs from a headphone output and it works fine. Should work with any microphone module because it AC couples the input to the Teensy, while setting the bias to 0.6V. That said, I keep thinking that a simpler circuit might be possible. View attachment 9429

This bias circuit will increase problems since 20% of the inevitable RF noise on the +3.3V line will be fed into the ADC input. Basically, There should be two filters for decoupling from +3.3V: One for the mic power supply as Paul wrote above, and a separate one for the bias voltage.

Another problem might be that (as written above) the mic is pre-amplified and there is a ca. 3Vpp AC amplitude at its output with a 1.6V bias. Both are too high. The bias alone will saturate already the ADC and the AC signal will overdrive it. A simple voltage divider 18k and 10k from the Mic output would bring the bias and the AC amplitude of the mic down to an appropriate level which solves both problems at the same time.
 
Back
Top