Electronic – arduino – FFT Beat Detection Circuit

arduinoaudiodspfftsound

I have for over a year now tried to figure out both the electronic aspect and the software aspect of my project.

I have somewhat successfully managed to make the overall idea to work,
the bumps I have come along the way are quite frankly stressing me out.

Project description and goal:

Basically a beat-detection device with a very small formfactor.

I am using an Arduino Uno as a prototyping device,
but I have an Arduino Mega, Sparkfun Micro and several other development boards
it stock to use if needed.

I want the microcontroller to read analog audio, convert it to FFT or FHT or
any other easily translated data, read the lower frequencies where the Kick of the
music is presented, and finally measure the timing between each kick to
calculate the BPM of the song.

The frequency range of where the Kick in the music is present is
around the 45Hz to 55Hz range and is most distinguishable in that area
when looking at it in a spectrum analyzer.

This should also be correct when doing FFT/FHT with a microcontroller
due to the nature of raw analog to digital to FFT/FHT conversion.

However, it may differ and is most likely to differ if a microphone is used
to listen to the audio.

What I have successfully accomplished:

  • Assembling a circuit which allows for audio to be injected to an analog input of the arduino. The circuit can be found here:

block diagram
(source: interface.khm.de)

So the two most important components of the project is in place.

What I have problems with:

  • I get a constant peak in the lower frequency area of the spectrum which is present at all times. This is a problem because the Kick of the music is in that area.

Things I have tried:

  • A guy on youtube tried to help me out by giving me simple instructions and he told me to use a 1uF capacitor between the Audio Surce and the Analog input, as well as trying either a pull-up or a pull-down resistor on the Analog Input.

Results (quote):

When using  a pull-up, the low freq peak increases, when using a
pull-down, the low freq disappears.

So the Pull-down is the way to go.

HOWEVER, with the pull-down present, harmonics of the sinus tone is
introduced but no peak at the lower freq area as long as no sound is
present.

With the pull-down NOT present, the harmonics vanish, but the peak is
present.

  • Implementing FIR and IIR filters. Results: Audio still reacting to all frequencies.

What more can I try before I throw this project out the window?

Approaches and suggestions need to be component-limited and preferably software oriented.

The light organ needs to have low power consumption and very few physical components,
and if physical components are required, they need to be tiny and surface mounted.

Best Answer

I think the youtube guy might have been on the right track, but the confusion is that "ground" is typically centered between two supplies for most analog circuits, and coexistent with the lower supply for most digital circuits. So whether you pulled it up or down, the DC level was already clipped, and so anything added to that (your music) was also clipped automatically.

Instead, you need to pull it to a point halfway in between. The easiest way to do that is to simply pull it up and down at the same time, using two resistors. That should center it nicely, with the exact level being determined by the ratio of the two resistors.

Also to consider:

  • The cutoff frequency is 1 / (2 * pi * R * C) in hertz, where R is the parallel combination of the two resistors in ohms and C is the capacitor in farads. You'll want to be about 1/10 of the lowest frequency that you want to detect.
  • The two resistors in parallel (and the one resistor that you used before) will load down the audio source. If it's greater than a few kohms, I wouldn't worry about it.
  • The two resistors in series will draw current from the power supply. If you're running from the wall and you've satisfied the previous point, that won't be a problem. Batteries might be different.

Update:

From a rather long discussion in the comments and a link to a different forum (http://www.openmusiclabs.com/forums/viewtopic.php?f=4&t=493&sid=c89646aea90012eb0fbcbf4161ab5b74), it seems that the problem has to do with DC offset. The original schematic attempts to solve this, but it includes an unnecessary adjustment that is easy to get wrong. Here's a better way to do it:

schematic

simulate this circuit – Schematic created using CircuitLab

Make sure to keep R1 and R2 equal. The cutoff frequency is described above.

The purpose of the original adjustment seems to be to fine-tune the DC offset to match the ADC, but I expect enough variation from other sources that it's easier to just make it close and use a digital highpass to finish the job.

Some other changes:

  • I switched to 10k resistors instead of 100k. This provides a lower source impedance to the ADC for the DC level. This requires a bigger cap for the same cutoff, which usually isn't a problem.
  • I added a resistor to complete the basic anti-alias filter. Use the same equation for cutoff frequency to put it about twice the highest frequency that you care about (10x would be better, but that may be asking too much of the ADC with this kind of filter), then run the ADC at least 10x the cutoff frequency.

As shown, the cutoff frequencies are ~1.5Hz and ~48kHz, so you'll want to get around to sampling that ADC channel at least 500kHz. Why not 48kHz like standard audio? Because this filter rolls off very slowly. Only at much higher frequencies does it finally attenuate noise enough to not mess with your signal when shifted down by aliasing. If you don't want to run the FHT that fast, you can use a more complex analog lowpass, or you can use a digital lowpass running that fast followed by throwing away most of the samples.