Thursday, August 8, 2013

Music Box (Hardware)



In this post, I'll be covering the build details of a project I've recently finished that has ended up as one of the more advanced things I've attempted. In another post, I'll cover some of the programming details, as those were equally as challenging to sort out. The original purpose of this project was to make a small gift for a musician, but it ended up being much more rewarding for myself as the builder/programmer than for the recipient (in my mind).

The original concept was to have a small device that would react to music. Since the device would be given to a violin player, I wanted it to be specifically designed to react to someone practicing an instrument, rather than to regular music being played through speakers. The distinction I make here is that a single instrument (like a violin) being played on its own will create a fairly simple sound wave, consisting of one or two base frequencies as well as a limited set of harmonics, while 'regular' music is a complex mixture of many instruments (possibly including vocals) that create a much more difficult waveform to analyze. There are endless examples on the internet of DIY graphic equalizers that are designed to handle this wide variety of sounds, but I wanted something a little more precise.

At this point I would like to make a note on musical scales, but after a few minutes of research to make sure my language is precise, I realized that I am very much unqualified to give a small lecture on music theory. So I'll keep this short. In modern western music, there are 12 pitches in the chromatic scale that separate each octave (a factor of 2 in frequency). Each of these pitches has a letter name with a possible modifier (ex: D# / Eb). You can also add a number after the name to specify which octave you mean (ex: A4 is 440Hz, A5 is 880Hz). While more traditional tuning is done using various ratios of frequencies to construct the 12 pitches of an octave, a modern approach is to space them out evenly on a logarithmic scale:

f = f_0 * 2^(n/12)

Here, f is the frequency of a note you wish to calculate, f_0 is an initial frequency, and n is the number of pitches away you want to calculate for. So by knowing one frequency (A4 is 440Hz), we can find any other one (A#4 is 440 * 2^(1/12) = 466.13Hz, B4 is 493.88Hz, etc).

In a later post on the software I've written for this project I'll go into more details about how I've used this math to do some clever things, but for now the point I'd like to emphasize is the cyclic nature of the chromatic scale. Every 12 pitches, you return to the same note but an octave higher or lower. It was this idea that led me to think of a circle of 12 lights that would represent each pitch of the scale.

To differentiate different octaves of the same note, I would use RGB LEDs for each light and have each octave glow a different color. To drive these 12 LEDs, I sprang for a couple 16-channel PWM drivers to make my life easier. In order to react to any sounds at all, the device would need a microphone, as well as a fast enough processor to handle the real-time calculations. For the mic I went with a MEMS microphone, and for the processor I sprang for a Teensy 3.0. I've been using one of these Teensy boards for another project and have really loved them. They are fully Arduino compatable, much smaller than most standard Arduinos, and also much faster (overclocking to 96MHz). In contrast to most Arduinos (not the Due), the Teensy is built around a 32-bit ARM Cortex-M4 processor which has a built-in digital signal processor (DSP). I've never used any DSP capabilities before, but I figured this project would be a good one to learn with. As for the aesthetic, I decided to grab a few 6"x6" diffused acrylic panels like the ones used in my water level box project. This way the box will have a nice soft color glow when running and reacting to music.

After testing the PWM drivers and microphone on a breadboard, I went ahead and soldered everything together on a few small protoboards I got for cheap on ebay. While the circuit looks fairly complicated, most of the wires are for daisy-chaining the PWM drivers and linking the outputs to the LEDs. Amazingly, everything seemed to work right off the bat.

At this point I start to wonder if I should plan these circuits before I solder them.

Obviously not done, mostly because the mic isn't connected to anything.

All good things are held together with hot glue and prayers.

While writing the waveform analysis algorithm for this, I realized that I was limiting the usefulness of this device to times when a single instrument is being played nearby. This seemed like a waste of so much soldering, so I decided that the whole device could operate in a few different modes. Some could react to instruments, some to general sound, and some could be oblivious to the environment and just display some pretty colors. In order to switch between these modes, I needed a method of user input. I wanted something sleek, so I went with two small pads of aluminum tape wrapping around the back panel. One is grounded, the other connected to an analog input of the Teensy with an internal pull-up resistor. When the pads are shorted together with a reasonably high resistance object (say, a finger), the Teensy registers a change in the analog read value and the mode is switched.

Gluing everything together.

Once completed, I had a plain white box with 12 individually addressable RGB LEDs in a circle with a microphone and processor to handle the music processing. Power is supplied by a 5V AC adapter dropped to 3.3V with a voltage regulator, and reprogramming can be done right on the Teensy with a micro-USB cable. It actually took longer to write the firmware for the music box than it did to build the whole thing, so I'll cover those details in another post. The goal was to give this box as a birthday gift, and I was pretty rushed to get it done. While I did have it completed in time (neglecting a few coding errors that were fixed post-birthday), I didn't get a chance to take nice pictures of it with my non-phone camera. Hopefully I will have nicer pictures and maybe a video in the next post as well.

Party hard.