Basic software architecture for LED "display"

I've got my Arduino's PWM pins wired up to a common-cathode LED strip. This is cool. My aim is to have the Arduino listen to the beat of the ambient music and play an increasingly complex series of sequences in time with that beat.

I'm thinking the way to go is to have a timed interrupt every 1/60th of a second which reads a HSL value from a circular buffer, translates it to RGB and sends it to the PWM pins. For the rest of the time I'll listen to the mic, work out when the next beat is and write the appropriate sequence into the buffer at that point.

Is this How You Do It? Or is there a Better Way? If I use Processing, do I get stuff like HSV->RGB conversion "for free" (and maybe even simple ways to make pleasing "pulses" or "heartbeats" of colour and rainbow fades)? What's the best way to do BPM detection, or is there a library for that too?

Have I got the right idea in general or am I missing something obvious?

Cheers, Robert.

This probably means I'm not going to be much help, but what are HSL and HSV?

You should be able to do it all on the Arduino.

I guess you could pick out the beat by smoothing (low pass filtering) the signal and then detecting local maxima. Or, do it in hardware and just have a comparator that picks out the drum or whatever going over some threshold.

HSL and HSV are colour spaces which are much closer to the way humans think about colour than RGB. You can produce a "rainbow" by traveling in one direction in HSV space, instead of having to traverse the edges of the RGB cube as you would if you were thinking in RGB.

And as for low pass filtering yes, I guess that's what I need to do. What I'm not sure about is how quickly I'll need to sample in order to get a good idea of when the beat is.

Cheers, Robert.

What I'm not sure about is how quickly I'll need to sample in order to get a good idea of when the beat is.

The answer to that is that sample as often as you can, while still doing the other stuff you need to do.

What I'm not sure about is how quickly I'll need to sample in order to get a good idea of when the beat is.

Depends on the sampling rate of the music you're listening to. Google "Nyquist Frequency". Basically, Nyquist says to only sample at 1/2 the frequency. If the music was converted to digital, then it's already been sampled, so there's no reason for checking more rapidly than the sampling of the music already. (ie: You won't get any more data resolution out of it... you start overlapping and only sample extra noise into the mix). If you're dealing with analog music, then check out the range of sampling that most mp3's are recorded at. 8khz is about as slow as music sampling goes. Any less than that, it sounds absolutely terrible. Most mp3's are sampled at 128kHz, I don't notice any improvement above that, although I'm not an audio professional. Read the wikipedia article, it's quite good.

, Nyquist says to only sample at 1/2 the frequency

No, Nyquist says to sample at at least half the frequency.

Uh, in any case it's the ambient music I want to sync the lights with; some of it may be digital, some may not be. It looks as if beat detection is quite difficult to do in software (though there are a couple of simplified hacky versions which get you most of the way there). But putting a low-pass filter on the hardware and then simply watching for when it breaks a threshold might be a goer.

Any commentary on the other part, namely a 60Hz interrupt reading the display values out of a circular buffer? Is that the right approach?

Cheers, Robert.

Most mp3's are sampled at 128kHz,

Slight mix-up of terms here. A commonly used bitrate of mp3 files is 128kbit/s, which means how much compressed data can be used for "describing" one second of music. The more data you can use, the more accurately you can describe the original waveform. That's what makes mp3 "lossy". The audio signal itself is still almost always sampled (and later played back) at 44.1kHz, no matter what bitrate is used for mp3 compression.

But that's,of course, a bit off-topic..

For detecting drum beats, one needs to detect relatively low-frequency transients. So I think there's no need to have very high sampling rates -- high frequency components should likely be filtered out anyway.

Well, it may help you out to take a look at what I've been working on recently:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1289765675

It's a realtime spectrum analyzer lightshow jobbie (I use television as output with TVout lib). The display code you wouldn't need, however, the FFT code would work very well for you. As written, it does roughly 500Hz bands x 64, so you cover 0-32kHz. It's very fast and written completely in C (the FFT), and from the forums here. You'll find code links in the writeup. This little FFT code is the heart of several little cute projects I'm working on, I'm sure you can find a ton of interesting ways to use it too!

The data you want would most likely sit in that first band, 0-500hz.

Since the code gives a LOT of usable data out, pick and choose and display how you'd like.. but it at least might take care of the audio processing side of the equation. Though my current version uses TV as the output, I'm also adding a version which will drive a 16x2 LCD as the graphic output. It's all a matter of mining the data in the array. Using the code, you should be able to slice the sound data any way you'd like. Note that the lib can even perform inverse and real-only transformation also, though I've not come up with a cute way to display that yet...

It does help! I just saw this thread the other day actually, that's pretty awesome. I could be a walking VU meter :-).

How much processor time does the FFT take? If I am only interested in the lowest frequency band, can I do something easy to "optimise away" the rest and save myself some cycles?

Cheers, Robert.