Monthly Archive for July, 2010

AVR-Oscilloscope Spectrograph

Sometimes, when you’re working with waveforms, it’s helpful to get a live picture of the frequency spectrum.  Since I’m trying to develop audio visualization algorithms, I thought it would be a good idea to create a tool to plot the FFT of a signal.  I was inspired by this excellent project, which uses an Atmel ATMEGA8 and an LCD to display a waveform and its corresponding FFT with a delay only on the order of milliseconds.  The project designer built a nice FFT library, which I incorporated into my project along with his recommendation for an anti-aliasing filter.

The problem was that I didn’t have an LCD to play with, so I had to settle for something slightly different; I wrote up a quick block to display the FFT data on my trusty Tektronix 335 oscilloscope.

There are basically two parts to the modification: first, I created an 8-bit DAC resistor ladder so that I could represent the intensity of each frequency of an FFT as an analog value.  Secondly, I created a low-frequency clock line that changed with each transition to a new frequency.  Finally, I just needed to trigger on the clock line with the oscilloscope to be able to view the full FFT.  This is easier to explain with a picture:

This FFT from an audio clip shows a large low-frequency component and a smaller mid-range component.  I tried playing some sine waves, sawtooth waves, etc. as well and the output was pretty accurate.  Here are a few pics of my setup (yes, I’m really bad at board layouts):

There are still a few major problems that I need to work through.  The biggest one is due some pretty painful noise coming from the clock lines and what looks to be my computer.  The latter can probably be solved by implementing a decent filter, though I’m not sure how the other project’s designer had so much success with his setup.  The other sources of noise seem to be coming from the clock lines and other lines around the board.  These can be solved by properly implementing this circuit on a PCB like the author did.  I’m seeing a lot of strange low-frequency noise in the FFT as well (the quick fix was to just remove the lowest few bars from the FFT output).  In addition to solving the noise problem, I need to fine tune some of the delay values I have for oscilloscope output to make it look better.

I’ll have code and schematics up in a few days.

ACRIS – A Hardware-Based Audio Visualization Project

I’ve always found audio visualization to be pretty interesting — it combines the complex (hah, pun) mathematics of signal processing with the entertainment of watching cool effects. Many audio players have interesting audio visualizers built-in; others are available as addons. MilkDrop seems to be quite popular.

Funky patterns on a screen changing to music is cool, but for a while, I’ve wanted to create a more entertaining experience. Essentially, my idea has been to create a set of wall lamps powered by arrays of multicolored LEDs. A microprocessor would adjust the color and intensity of the lamps based on audio input.

From a high-level standpoint, this kind of system is not too complicated. A low-latency audio processor takes audio signals as an input, performs some frequency analysis on them, and generates PWM signals. These PWM signals are fed into LED arrays making up the wall lamps. As always, though, the devil’s in the details.

System Design

The final design will use an FPGA with some simple support hardware to do the audio processing. Overkill? Probably… A fast microcontroller is usually good enough for these kinds of things. But, I wanted to make this a hardware project. The FPGA I plan to use is a Spartan 3, available cheaply on this eval board.

To elaborate a bit, I’ll feed an audio signal into a high-frequency opamp, which will buffer the audio signal and send it to an 8-bit ADC, whose output is fed into the FPGA. The FPGA will take an FFT of the data and then, based on the color mixing algorithm I choose, will operate on the frequency data. Finally, after deciding the final desired color, the FPGA outputs PWM signals to the wall lamps, those internal circuitry amplifies and uses those signals to light up the desired color. I’m hoping for a total latency on the order of tens or hundreds of microseconds.

I’d like to put up three or four lamps. One will be on the left side of my room and another will be on the right. These two lamps will be controlled solely by their respective stereo components. The other lamps will be above my desk and will be controlled based on a combination of left and right audio data.

I was originally hoping to make the wall lamps interact wirelessly, but I don’t think that’ll be possible given the price of wireless modules. Also, there is a latency problem as well as a security issue involved with wireless.

Anyways, I’ve had a few ideas for the color mixing algorithm. One was to separate the frequency graph into three large chunks (e.g. “low” frequency, “medium,” and “high”) and then define some sort of color scale for each chunk. Next, for each chunk, the center of mass is determined and is used to locate a color on the chunk’s color scale. The relative intensities are compared and then a final color is mixed. This algorithm is actually very easy to implement. A friend of mine suggested another interesting algorithm (harder to implement, but definitely worth a try): split the frequency graph output from the FFT into octaves and then define the same color scale for each octave. Colors are mixed in proportion to their intensity. This guarantees that all equivalent pitches (across octaves) have the same color. You could also improve the algorithm a bit to make the lower octaves biased toward one color and the higher octaves biased toward another. There will be three multiplexers
to determine the FPGA input. The first will allow switching between 2 or 3 analog audio channels. The second can bypass the ADC and send digital data directly into the FPGA. The third will bypass the FPGA directly and allow some device (e.g. a microcontroller) to send in PWM signals to the LED arrays.

Finally, as a finishing touch to bring out the bass, I’d like to add blue backlighting to the wall lamps that lights up only to low frequency responses.

As for the LEDs to use, an array of Cree MC-Es would be spectacular, but pricey. Another option would be to use a bunch of cheaper chips from DealExtreme.

Current Status

Right now, I’ve ordered and AVR and supporting hardware in order to use this project I discovered as a starting point. Instead of outputting a graph to an LCD, though, I am going to begin testing simple color mixing algorithms with whatever LEDs I can find. Using a microcontroller will allow me to quickly test algorithms, although the latency may be noticeable. In the future, I’ll switch the function of that AVR so that it can take input from other sources and control the lighting system.

As I begin building stuff, I’ll start posting my notes and diagrams.