Unique Audio Frequency Analyzer-Volume by Frequency

Hello all,

I have looked in Youtube videos as well as this forum, and I don't think I have quite found the resources I need to do the project I am hoping to make, so I am looking for some assistance.

I want to make a fiber optic light audio visualizer, but a bit different from any of the ones I have seen made so far. What I would like to do is:

  1. Take an audio sample (music, through a microphone)
  2. Separate that sample into 9 different frequency bands (16 to 32 Hz, 32 to 65 Hz, etc by octave)
  3. Measure the volume of each band
  4. Measure the peak volume of the overall sample
  5. Determine average volume of the overall sample
  6. Signal the LED/light source for a specific band to turn on if it's band average volume is above the
    overall sample average volume (so it only activates the loudest few bands in the sample)
  7. Adjust brightness of each band based on how loud it is compared to the others that are active (if the band volume is 70% of peak, turn pin High for 7ms then Low 3ms, etc)
  8. Should last about 10ms before taking new sample and restarting.

Now, I have seen examples and code that do some of these functions but I am just unsure how it would work, especially in distinguishing the frequency bands and treating them differently from one another.

So I guess I am looking into some insights on how this can be done.

Thank you in advance!!

A DFRobot Audio Analyzer.

In general terminology, you're looking for a "spectrum analyzer"*.

(I've never done anything with frequency but I've made several sound-activated lighting effects.)

There are two ways of doing it:

The [u]MSGEQ7 chip[/u] has frequency filtering built-in and AC-to-DC built-in but it only gives you 7 frequency bands.

In software you can use [u]FFT[/u] or FHT to get many frequency bands. FFT and FHT are software intensive. There are libraries so you don't have to write the code yourself.

The Arduino ADC can't read the negative half of an AC audio waveform so with FFT/FHT you'll have to bias the input (2 resistors and a capacitor).

In either case, if you want to use a microphone you'll need a preamp. Or, you can get a [u]microphone board[/u] with a mic, preamp, and biased output. (That particular one doesn't have a gain control.)

  1. Measure the volume of each band

Yes, that's what spectrum analysis is. :wink:

  1. Measure the peak volume of the overall sample

The "true peak" is a little tricky because frequency requires time and a single (or single sample) peak doesn't have any frequency information. Also, FFT/FHT on the Arduino don't "catch everything" because they take a short sample, and then "pause" to analyze it. The MSGEQ7 also has some "delay" or "smoothing" too. But, you should be able to get some useful quick readings that resemble peaks.

...8. Should last about 10ms before taking new sample and restarting.

Your software may not run that fast... But in my experience, 100ms is about as fast as you want to go for a visual effect, unless you want the perception of "dimming/brightness".

  1. Determine average volume of the overall sample
  2. Signal the LED/light source for a specific band to turn on if it's band average volume is above the
    overall sample average volume (so it only activates the loudest few bands in the sample)
  3. Adjust brightness of each band based on how loud it is compared to the others that are active (if the band volume is 70% of peak, turn pin High for 7ms then Low 3ms, etc)

Once you get the data, that's fairly straightforward.

I do something similar so my lighting effects adjust automatically to volume changes - For all of my effects, I take a "sample" of the "loudness" once per second and I store it in a 20-second circular buffer. Then depending on the effect, I take the average and/or the peak from that buffer (array) to use as a reference. The way I'm doing it, I don't have a "true peak" I just have "a peak" but it works to set the "top reference" of my "VU meter" effect. My [u]World's Simplest Lighting Effect[/u] might give you some ideas.

  • A spectrum analyzer is a measurement instrument or measurement software. You are not doing precise measurement/analysis so you're actually building a spectrum analyzer effect.

Thank you both for the input!

Doug, any chance I could pay you to write the code for this? I can do the breadboard setup easily enough, but I'm garbage at code. If not, do you know of a resource where I would be able to have it made?

I'll probably use an LM393 as the mic, and an Arduino UNO R3. Outputs for each band would be 1 pin each leading to a transistor and then the light itself.

Doug, any chance I could pay you to write the code for this? I can do the breadboard setup easily enough, but I'm garbage at code. If not, do you know of a resource where I would be able to have it made?

Sorry, no. I don't have the time right now, and like I said I've never done anything with frequency analysis. I have "studied" the MSGEQ7 and it's not difficult as long as you can understand the timing diagram.

This is mostly a do-it-yourself forum where users share information and learn from each other and figure-out things "the hard way", but somebody with experience can probably help you to get started if you want to play around with the FFT/FHT libraries. The libraries are the "hard part" of the code but you need to understand enough to use it.

There is a [u]Gigs and Collaborations sub forum[/u] where you may find some free or paid help.

Something like this can take many hours and there's usually some back-and-forth so the hours can add-up. A programmer is typically going to charge rates similar to a plumber or auto mechanic so it can cost a lot if you have to pay for it. This type of work is usually charged by the hour on a "best effort" basis so if you find a bug, or if you want a change later you have to pay more (unless the programmer decides to give you a break). It's also difficult if the programmer doesn't have his hands on your particular hardware for testing/debugging so it's best to find someone local.

I'll probably use an LM393 as the mic,

The LM393 isn't a microphone, and it's not even an amplifier...

So the first question is, do you really want to use a microphone? If the thing is music-driven it's easer to tap-into a line-level or headphone-level audio signal. And, usually you don't want to pick-up the room noise anyway...

If you do want to use a microphone I recommend buying a microphone board, at least to get started. Then later, if you really want to build something yourself, SparkFun publishes the schematic for their board and that can give you a good starting-point for your own design.

and an Arduino UNO R3. Outputs for each band would be 1 pin each leading to a transistor and then the light itself.

That depends on the type of "light". MOSFETs are common for driving LED strips. A regular transistor can work but MOSFETs can generally handle more power without overheating. "Regular little" LEDs can be driven directly (with a current limiting resistor). Addressable LED strips (NeoPixels, etc.) can be driven directly. AC lights can be controlled with a solid state relay.

Doug,

Thanks for your help, it's pointing me in the right directions and giving me a better place to start.

It doesn't look like the MSGEQ7 would be suitable for my needs. It analyzes 7 bands instead of 9, and are centered around frequencies that I'm not in control of or prefer (I'm hoping for each band to start on a C note, from C0 to C8). The FFT and FHT are something I will look into more.

Using a direct 3.5mm line in/out is a good idea, I think I will go that route instead :slight_smile:

MOSFETS are a good thing to look into. I'm not aiming to use LED strips, rather it will be a 12V, 3W mini LED's leading into a side emitting fiber optic line, one for each frequency band (12V will be it's own supply, not directly into the Arduino, don't worry :wink:

Any other insights you might be able to provide? Or anyone else care to comment?

12V will be it's own supply, not directly into the Arduino,

Remember to join the ground of the Arduino to the ground of the 12V supply.

As mentioned earlier, you won't get the refresh rate from a Uno running an FFT as you specified you needed. The Uno can sample at 10K samples per second meaning that the top frequency you can detect is only 5KHz. With a bit of tweeking you might get the sample rate up to about 40K samples per second, meaning a top rate of 20KHz.

However, the FFT splits the results into bins, each bin detects half the frequency as the previous one. So if you have a bin at 20KHz, the next bin is at 10KHz, then 5KHz, then 2.5KHz and so on. There is no way to detect if a frequency registered in the 2.5K bin was actually the result of an input in the range of that bin.

To cover specific frequency ranges you will have to group and aggregate the results in several bins.

MOSFETS are a good thing to look into. I'm not aiming to use LED strips, rather it will be a 12V, 3W mini LED's leading

"Raw" high-power LEDs (1W or more) present a couple of additional challenges.

LEDs are "current driven" so they are normally driven by a constant-current (or controlled-current) driver. You can't use a regular constant-voltage power supply.... You supply the current and the voltage "falls into place". This is the opposite of almost everything else in electronics where you supply the voltage and the current "falls into place". Constant current LED drivers not easy to build yourself and they can be expensive to buy. (You may be able to find a cheap one.)

Usually there is a control-input of for on/off or dimming so with the driver you shouldn't need an additional transistor or MOSFET. However, the "industry standard" is 10V control, which can be 0-10VDC or 10V PWM for dimming so yo might need a "small" (low current) 10V power supply and some "small" (low current) transistors or MOSFETs.

With regular little LEDs we use simply a resistor to limit current, with about half the voltage dropped across the resistor and half across the LED. You can do that with high power LEDs, but it's inefficient and you need to use a power-resistor (and you need a supply-voltage higher than the rated LED voltage). LED strips have a built-in resistor for each LED. (Of course, that's also inefficient but the wasted heat is distributed over the length of the strip.)

They also need heatsinks. An LED doesn't get as hot as a regular light bulb of the same wattage (and it's brighter than a regular light bulb) but they can't handle as much heat as a regular light blub without burning-up.