My Embedded Music Player and Sound Server

Some months ago, I got a Rasp­berry Pi in the mail and pro­ceeded to install MPD on it. After a few days play­ing with an embed­ded MPD server and fig­ur­ing out what I liked and did­n’t like about the arrange­ment, I decided on a sig­nif­i­cantly more elab­o­rate project to build on it. I wanted to be able to con­trol the play­er, even if all of the com­put­ers in the house were off. I also wanted to run player while using my desk­top, which I could­n’t really do because they shared the same desk­top speak­ers. I ended up with a list of fea­tures for an embed­ded music system:

  1. MPD installed on a Raspberry Pi with a music library stored on a USB attached hard drive
  2. A Pulseaudio server installed on the Pi with computers in my apartment configured to stream sound to it
  3. A physical control panel attached to the Pi, which displayed player information and let me start/stop, mute/unmute, select songs, and change the volume on the device

The first of the fea­tures was already done and had taken all of thirty minutes. The sec­ond was not done and would take longer, but was still easy. The last item on this list how­ev­er, required a bit of phys­i­cal hack­ing to do. I ended up using all of the GPIO pins to do it. Any­way, here’s a pic­ture of the final product:


I think it turned out well. That’s a 16x2 LCD dis­play, two RGB LEDs, two rotary encoders, some wires and a cir­cuit board, embed­ded into a home­made Plex­i­glas and alu­minum frame. Togeth­er, they use up all of the GPIO pins on the Rasp­berry Pi. 1 Putting that together took quite a while and was a bit of trial and error. The orig­i­nal plan was to whit­tle a case out of wood but that turned out to be more labor-in­ten­sive that I desired while I don’t think that an ‘in­ter­na­tion­al-style’ case is as attrac­tive, it still works for my pro­ject.

I wrote the ini­tial code in Python, but found out that the cur­rent Python GPIO libraries were unsuited to read­ing rotary encoders. So I rewrote the project in C using the excel­lent WiringPi library. It actu­ally con­sti­tutes my first return to C in a long while. I had to learn both MPD client library and the ALSA library by read­ing the code.2 In ret­ro­spect, I should have writ­ten it against Pulseau­dio rather than ALSA, but I had­n’t decided ini­tially that that was the direc­tion I wanted to go. In the end it did­n’t mat­ter because I only change the mas­ter vol­ume.

One thing I did learn and had to code for, is that the human ear does not per­ceive vol­ume change linearly, so I had to con­vert it log­a­rith­mi­cally between dis­play and read­ing. This is appar­ently a com­mon prac­tice and is why poten­tiome­ters are com­monly sold which change log­a­rith­mi­cal­ly. I was using a rotary encoder to adjust vol­ume, so I had to do it in soft­ware.

The code for all this is, if you want it, on github.

Mak­ing the phys­i­cal con­trol panel was harder in the end than writ­ing the code for it. I started with a pro­to­type on a bread­board against which I wrote the code:


This worked of course and I could have left it at that, but it was unfin­ished and I had to reach through all the wires to use it. Mak­ing the fin­ished device how­ev­er, turned out harder than I thought it would. I ini­tially started carv­ing wood to make the case but changed my mind after I real­ized that the fin­ished prod­uct would prob­a­bly be pretty ugly. (My whit­tling skills are not where I’d like them to be.) So instead I bought some acrylic sheets, broke them into smaller sheets and cut out room for the com­po­nents to fit using a Dremel tool. It took me three tries to get right.3 I then repli­cated the cir­cuit on the bread­board on a pro­to­board which I could con­nect to the Pi with a 13pin rib­bon cable. I was going to put the whole thing, Rasp­berry Pi and all, together into one bit clear acrylic box, but changed my mind to make the con­trol panel sep­a­rate and con­nect it using riv­ets rather than glue. I wish I could say I did this because it looked bet­ter (it does) but I really did it because it was eas­ier.

I now have the mostly fin­ished pro­duct. I think it’s pretty neat. Here’s a quick demonstration:

  1. The rotary encoders have built-in press switches. 
  2. The ALSA library was by far the easier to figure out because the amixer program was so simple. If you want to write code for ALSA, read the amixer code. 
  3. In retrospect, I could have gotten away with just drilling holes for the rotary encoders and just attaches the LCD and LEDs behind the clear screen. I didn’t think of that at the time. 

Last update: 10/04/2013

blog comments powered by Disqus