Building a Wifi Radio – Part 5, Let’s Make Some Noise!

This is the fifth part of an ongoing series at mightyOhm about building a low cost, open source streaming internet radio.  If you haven’t already, check out the previous parts below for some background about the project.

Building a Wifi Radio – Part 1, Introduction

Building a Wifi Radio – Part 2, Choosing an Embedded Platform

Building a Wifi Radio – Part 3, Hacking the Asus WL-520GU

Building a Wifi Radio – Part 4, Installing OpenWrt

Note:

The instructions that follow assume that you have an Asus WL-520GU wireless router with the following modifications: an externally accessible serial port, OpenWrt installed and working, and a configured network connection on the router.  If not, check out the previous parts of the series to learn more.

Using opkg to customize OpenWrt:

OpenWrt includes a utility called opkg that allows the end user to easily add and remove optional software packages.  These packages include functionality that is not a part of the OpenWrt base image, such as hardware drivers (including USB), optional software, and utilities.  Most packages are not installed by default (after all, the router only contains 4MB of flash storage).  The OpenWrt Community Wiki includes a very helpful page about Packages that contains a lot of useful information about configuring and using opkg.

Before we can use opkg we need to configure it.  The file /etc/opkg.conf contains a few options, including the URL of the server opkg uses to find and download packages.  We need to change this server from the default by modifying the config file:

root@OpenWrt:~# vi /etc/opkg.conf

Modify the first line to look like this:

src/gz snapshots http://mightyohm.com/files/kamikaze-2.4/packages/mipsel 
dest root /
dest ram /tmp
lists_dir ext /var/opkg-lists

You can also download the complete set of packages and set up a server of your own for opkg to access.  I have had great success using the apache server included with OS X, but I won’t cover the setup here.

The following command tells opkg to fetch a list of available packages from the server:

root@OpenWrt:~# opkg update

You should see the following response:

Downloading http://mightyohm.com/files/kamikaze-2.4/packages/mipsel/Packages.gz
Connecting to mightyohm.com (72.32.209.132:80)
Packages.gz          100% |*******************************|  8326  --:--:-- ETA
Inflating http://mightyohm.com/files/kamikaze-2.4/packages/mipsel/Packages.gz
Updated list of available packages in /var/opkg-lists/snapshots
Signiture check for snapshots skipped because GPG support was not enabled in this build

Now we can start installing packages.  To access our USB-audio converter, we need to install USB 1.1 (OHCI) support and some sound drivers:

root@OpenWrt:~# opkg install kmod-usb-audio kmod-usb-ohci

This should automatically install kmod-usb-core and kmod-sound-core, but if not you can also install them manually with the opkg install command.

At this point you should insert the USB-audio converter if you haven’t already.  Then reboot the router:

root@OpenWrt:~# reboot

As the router is booting again, watch for new status messages like these:

...
usb-ohci.c: USB OHCI at membase 0xb8003000, IRQ 6
usb-ohci.c: usb-00:03.0, PCI device 14e4:471a
usb.c: new USB bus registered, assigned bus number 1
usb.c: registered new driver audio
audio.c: v1.0.0:USB Audio Class driver
usbaudio: device 2 audiocontrol interface 0 has 1 input and 1 output AudioStreaming interfaces
usbaudio: device 2 interface 2 altsetting 1 channels 1 framesize 2 configured
usbaudio: valid input sample rate 48000
usbaudio: valid input sample rate 44100
usbaudio: device 2 interface 2 altsetting 1: format 0x00000010 sratelo 44100 sratehi 48000 attributes 0x01
...
usbaudio: registered dsp 14,3
usbaudio: constructing mixer for Terminal 6 type 0x0301
...

If you see this, the USB-audio converter is most likely working and the correct drivers have been loaded.  At this point the green LED inside the USB-audio converter should be lit, another sign that everything is working correctly.

Installing mpd:

To actually play some tunes we need to install some additional software.  We can use opkg to do this, as follows:

root@OpenWrt:~# opkg update

root@OpenWrt:~# opkg install mpd mpc

This command installs mpd, the music player daemon.  mpd is an open source music server that can be accessed locally or across a network by using a variety of clients, which are available for many different platforms.  This includes the command line client mpc which is also now installed on the router.

mpd requires some setup before we can use it:

root@OpenWrt:~# cd ~
root@OpenWrt:~# mkdir .mpd
root@OpenWrt:~# mkdir music
root@OpenWrt:~# mkdir .mpd/playlists
root@OpenWrt:~# vi /etc/mpd.conf

Scroll down and look for the audio_output section of the mpd configuration file, and change the reference to /dev/dsp to make it look like this:

# An example of an OSS output:
#
audio_output {
        type                    "oss"
        name                    "My OSS Device"
        device                  "/dev/sound/dsp"
        format                  "44100:16:2"
}

There are many other options you can play with; mpd is very powerful.  There is a list of features here and a lot more information on the mpd wiki.

Exit vi, saving the changes to mpd.conf.  Now launch mpd with the following command:

root@OpenWrt:~# mpd

The player should start silently, without errors.  Run mpc and verify that it can talk to the server:

root@OpenWrt:~# mpc
volume:100%   repeat: off   random: off

If you see this, good news, the server is running and we have the ability to control it with mpc!

Now would be a good time to connect speakers or headphones to the USB-audio adapter’s headphone output.  Warning – the initial volume can be VERY LOUD. Don’t wear headphones during testing!  PC speakers with a volume control are best.  Start at a low volume.  (My ears are still ringing!)

We can add a streaming radio server to the playlist by executing

root@OpenWrt:~# mpc add http://relay3.slayradio.org:8000/
adding: http://relay3.slayradio.org:8000/

And finally, the moment of truth:

root@OpenWrt:~# mpc play
http://relay3.slayradio.org:8000/
[playing] #1/1   0:00/0:00 (100%)
volume:100%   repeat: off   random: off
root@OpenWrt:~#

If all goes well, within a few seconds you should hear Slay Radio playing on your headphones or speakers.  The Air light on the router should flicker as traffic crosses the WiFi interface, and the green light on the USB-audio converter should flash repeatedly to indicate that audio is being sent to the device.

If you’ve made it this far, I recommend celebrating with your favorite beverage and enjoying some tunes!  Congratulations!

You can add other servers to the playlist by executing the mpc add command again, and then play them with the mpc play n command, where n is the position of the server in the playlist.  mpc playlist will display the current playlist. mpc help will give you a list of available commands.

One very powerful feature of mpd is that it operates as a server on port 6600 of the router, so it can be controlled from any other device on your local network.  If you download an mpd client such as Theramin, you can control the router remotely from your desktop computer.  There is an excellent client for the iPhone too.

That’s it for part five.  I hope you have enjoyed the series thus far.  In part six, we’ll start writing some scripts to control mpd and talk about options for a user interface.  If you are building a Wifi Radio of your own, I’d love to hear about it – leave a comment below!

Update: Part six is now available.

83 thoughts on “Building a Wifi Radio – Part 5, Let’s Make Some Noise!”

  1. The serial port on the router. What finally got communication between the AVR and the router working was tweaking the bitrate on the AVR. I was getting extended ascii characters for most of my letters, so I thought it was something like this. I ended up “slowing down” my bitrate from (nominally) 115.2k to 110k. I’m not sure if my oscillator (20 mhz crystal) is running fast, if the router is running slow, or none of these – all I know is that it works now.

    Both were able to talk to my computer at both speeds, which is made everything a little more confusing. I guess my computer is just a little more flexible than the router.

    Thanks so much for posting this project, I am having a lot of fun with this platfrom, and probably would not have even heard of openwrt otherwise.

  2. I forgot, there is another strange thing going on with my router: the “AIR” LED is a lot less bright than the other ones, due to it being pulsed rather than lit all the time (see oscillogram at the URL in my other comment, I think it was 1ms/div and 1V/div, measured voltage directly across the LED). Anyone else experience this? Anyone know what is going on with that LED? It’s like that all the time, even if manually activated by executing
    echo 1 >/proc/diag/led/wlan
    Only when restarting the router, just before the hardware actually reboots, the LED is lit up at full brightness for a few seconds.

  3. Hi,

    I spent the last few days trying to build a web radio, too! I followed your instructions for a start, then continued on my own once everything was more-or-less working. After I finally got the WLAN connecting reliably (it wouldn’t always work with the default settings, but after removing the WAN interface and a lot of unneccessary and potentially interfering packages (e.g. the DHCP server), it’s now working perfectly.

    I am planning on doing an AVR based user interface with an LCD displaying the currently playing title and a lot of keys (at least 10 keys for presets) and, later, also an IR receiver. The available streams can be configured via a web interface which basically already works, but still needs a few improvements and extensions.

    Now for a few questions:
    I would really like to have a simple command-line mixer app on the router to be able to control all channels, not just PCM (e.g. set master to 50% or something at boot-up instead leaving it at the ridicuously loud 100%, so the entire PCM volume span can be used. I couldn’t find anything on that subject though, it doesn’t seem there is one included with openwrt. Any ideas how to get one?
    In addition, I will link to my scripts and changed config files below. As you can see, there is a lot of redundant stuff in the web interface scripts which I would really like to do with loops instead of writing it out flat, any idea how to use an array or dynamically-generated variables in a shell script (e.g. $n contains a number, say 42, how do I put something into a new variable called $preset42)? Can it be done at all, or will I need to resort to a ‘proper’ programming language?

    I uploaded some important files and some photos too here:
    http://elektronik-kompendium.de/public/arnerossius/temp/webradio/
    maybe some of that stuff will be useful for someone else building a web radio, too. The most important changes are of course the web interface (/www is empty by default), the scripts in /root (make sure to use my /etc/profile too so /root will be included in the path!) which will later be called by the AVR which will be connected to the serial console, the modified network configuration (note that the “wan” section is commented out and the switch config is changed so all 5 ports are in the same vlan) and the list of installed packages (compare that with the packages on a default installation and you will notice that I have removed a few packages).

    Any suggestions on how to improve anything will be appreciated. Thanks, and thanks for the great instructions here!

    Best Regards,
    Arne

  4. I’m up and running. The cheap USB audio interface from DX works fine, but only at 48000. And it doesn’t sound that great.

    As a fun little thing to occupy this until after finals, I built a little gadget that tells the world when I turn my lights on and off.

    twitter.com/hithisishal

    CdS cell –> comparator –> AVR –> router serial port.

  5. Is anybody else having problems communicating between the router and an AVR? Any ideas about terminating/filtering/better drive? Or better yet: did anybody find a way to lower the terminal transmit speed from 115.2k?

  6. paladinx – I have seen that project before, it is well done. I’m planning to take a slightly different approach but I like what he did too.

  7. Pavlos – The process for the Hammer would be a lot different because I don’t think you could run OpenWrt on it (without a lot of work). You would probably have to compile your own mpc/mpd and any other software you needed. You also might have some challenges getting Wifi and the USB audio converter working because the Hammer’s version of Linux may not have the same drivers available as OpenWrt. On the flip side, the Hammer is made for doing stuff like this so you would have a good chance of getting technical support from Tin Can Tools along the way.

  8. I found this site online where someone has done a very similar project with a different router. He’s managed to implement a serial lcd onto his. I’d like to try something similar that maybe works like an alarm clock.

    http://devices.natetrue.com/musicap/

    I am really looking forward to reading part 6 since the other blog leaves you at roughly the same spot you are at now.

  9. Hey people. I am kind of noob in these things but i was wondering if i would like to build this wifi radio from scratch using other embedded platform for example “Tin Can Tools Hammer” what is the process i have to follow? It will be the same? Thanks a lot in advance

    Pavlos

  10. Well, quick update. I figured out the reason for the crash on launch – I had enabled the “state” file update on close, but it was not happy. I disabled it and all is good. I’m still working on a master playlist, but it seems stable now with things broken into smaller playlists.

    I’ll check back for part 6, as well as share any additional tips I may discover along the way. Thanks again for finally getting me to get this thing finished! I’ve been tossing around the idea forever!

    Durin

  11. I’m not expecting part 6 to be up for a couple weeks. The radio is taking a back seat to a few other projects I’m working on. This is a good break point, actually – the good news is that parts 1-5 will get you a functional Wifi radio with a command line or network interface, which isn’t too bad! I pushed very hard to get 3-5 up quickly because I know a lot of people wanted to see the OpenWrt stuff. Part 6 and on will be more about customizing the radio to do what I want, and I definitely encourage you to decide for yourself what you want the radio to be in the meantime.

    By the way, I see a lot of great ideas in the comments here – cuecat barcode scanners, IR control, mass storage devices. You guys are awesome!

  12. Well, for those who are in the same boat, here’s what I’ve done so far and what works and doesn’t.

    I attached a 2GB USB thumb drive and got it mounted pretty easily. I tried using ‘dd’ to create a swap file on the drive, but dd failed everytime. Rather than troubleshoot that too much, I just used ‘cat /dev/zero >> swapfile’ and let it run for awhile until the file reached approx. 32 megs. I don’t know if it’s necessary it be EXACTLY a multiple of 8, but I went over slightly and it doesn’t seem to be a problem.

    after installing swap-utils, I was able to use mkswap and swapon to enable the new file as a swap location. all seems to be good there.

    mpd was then able to create the full database without any troubles and much more quickly than previous attempts. next, i tried to make a mega playlist of all songs using ‘mpc ls | mpc add’ or different variations on that scheme. failure. everytime the mpc processes died. I finally started to make smaller playlists and that seemed to work.

    shortly after that, however, mpd crashes shortly after startup. ARGH! That’s where I’m at now, trying to figure out why mpd is crapping out and how I can convince it to lovingly work again. wish me luck!

    Durin

  13. USB IR remote:
    http://www.dealextreme.com/details.dx/sku.14380

    Sorry if I sound like an advert, but you can get all sorts of wacky stuff like this really cheap from dealextreme. I kind of love them.

    I just bought a router and the $3 DX USB-audio adapter. I’m excited to build my own! I have the same problem as you – I would like music in my basement without a laptop.

  14. After several reinstallations, I’m finally MOSTLY working. Audio output is great – took your advice and installed your OSS-based mpd instead of using ALSA, my USB thumbdrive is connected, and I can mount my CIFS/Samba shares where my music collection lies.

    My biggest problem now seems to be getting mpd to make the database without crashing. I’ve had success a few times, but then it causes all sorts of issues on subsequent launches. the database file came to around 5 megs in size so I’m wondering it it’s a memory issue. Does mpd load the entire database file into RAM?

    I’ve been trying to have it store the database file ON the Samba share, which I felt may also be a problem, but my latest attempts to store it on the usb thumbdrive have been less than successful. (it tends to lock up, after which telnet/ssh is screwy for some time!)

    Anyways, getting closer! I’ve definitely learned a lot and hopefully I can stop neglecting my wife and kid soon 😉

    Thanks,
    Durin

  15. kuangeleven – I haven’t seen a USB IR receiver before, but would not be surprised if such a thing existed. What is missing is probably any driver support on OpenWrt. I would go the serial IR route, that sounds perfect. You can actually add more serial ports to the router by using a USB to serial converter and loading the kmod-usb-serial (I believe) package. The FTDI cable I used for the serial console actually works in reverse – if you plug it into the USB port of the router now you have a 2nd 3.3V serial port. It works with a hub too.

  16. Success! I’ve updated the mpd.conf to point at the usb memory stick and I’ve managed to create a database of a small number of files (80 mp3’s) and play these back with no problems. I haven’t tried a larger collection or cifs yet.

    I was also able to get automount working so that the stick is mounted at boot. I’ve also linked the mpd init script into /etc/rc.d — which by default starts playing songs from the mpd databasse at starup.

    I’m looking forward to part 6 and controlling this gizmo with something other than a terminal. I’m wondering if some variant of the serial IR receiver I built for lirc might work, although I bet there are man handy (and cheap!) USB IR receivers out there these days, any suggestions?

  17. thanks. I may do that tonight.

    I’ve got everything CLOSE to working, but after having mpd create the database – which is stored on the mounted CIFS drive due to its size – mpd crashes on startup. I’m wondering if perhaps there’s not enough memory to load the database file? I’ve launched it in verbose mode and it seems to finish, says “daemonized!” which I assume means it’s finished with its startup procedure, but after a minute or two the process is no longer running.

    I’ll share whatever I figure out. Thanks again.
    Durin

  18. Durin –

    Try installing the mpd package I’m hosting here, it should work without alsa-lib. I was able to compile it without alsa by modifying the mpd Makefile. Using OSS instead of ALSA saves a couple hundred K of flash that you can use for other things.

    You can temporarily point your opkg.conf to my site for the mpd intall or download the .ipk file instead.

  19. I had some problems building my own, so I grabbed the squashfs.trx file directly from openwrt.org and installed that. after installing the alsa-lib package in order to get mpd to function, i was able to mount cifs and samba shares properly. Setting up fstab to mount those folders on boot to the ~/music folder, and I should be good to go! I’ll let you all know how it goes and pictures of the finished unit after I get the barcode system setup.

    Durin

  20. Wow, that was easy. The only slight hiccup was that found that I had to re-run ‘opkg update’ once I had rebooted the router after I had installed the kernel modules. Otherwise, opkg would complain that mpd and mpc did not exist.

    ‘mpc volume -80’ brought the volume back down to a more reasonable level for testing. It’s surprising how loud it is!

    I managed to get a usb stick mounted. I hooked up a powered usb hub to the router and inserted the audio adapter and the memory stick. After doing: ‘opkg install kmod-usb-storage kmod-fs-vfat’ and rebooting, I was able to get the stick to mount using ‘mkdir /mnt/usb; mount /dev/scsi/host0/bus0/target0/lun0/part1 /mnt/usb’. I wasn’t immediately able to get mpc to add a file from the stick to the playlist, but I imagine it just a matter of figuring out how mpc works to properly do so. Streaming audio worked fine despite having the usb audio adapter plugged into a hub.

    In poking around at the modules available (I built openwrt locally and I’m running a local package repository), I noticed that there are a number of modules for usb-serial adaptors. I’m wondering if for someone who did a blind install of openwrt as Durin has suggested in a previous post, one of these might be used for a console or to attach a control panel to the router. Of particular interest was the kmod-usb-serial-ftdi module, which might work with the same cable and work nicely for interfacing with a ttl level serial connection.

    At some point I’m going to look at getting last.fm radio working with this setup — lately the accuracy of their personal radio has impressed me. Similarly to pandora, the use a flash widget to play music, but Amarok also can play the last.fm streams. There’s probably enough documentation out there on the net to get something working for this setup. I don’t use pandora personally, but a similar situation might exist for that as well.

  21. Oh, and Andrew – as far as I know, pandora won’t work because they use a proprietary player (to force you to watch their ads).

  22. I haven’t tried yet – but it’s on my list of things to do on a rainy day. Playing files on a USB stick would nice too. If you figure it out, definitely post your findings!

  23. any advice on getting Samba/CIFS shares mounted? I can use smbclient to view the share, but i am STUCK getting it to mount! No luck and no resource I find online seems to work.

    Thanks all,
    durin

  24. Well, hot damn! That ended up being a much simpler installation than I was making it yesterday. needed far fewer packages installed.

    This is great! I’m excited to build upon this. My intent is to wire up a :CueCat barcode scanner and print a card with each of my albums. Then I just slide the card into the NOW PLAYING slot, the corresponding playlist is launched and tunes get played!

    Thanks again. It made linux configuration much less scary and I’m sure you’ve helped Newegg move some product 😉

    Durin

Leave a Reply