Arduino Project 6: Web-controlled music player

Arduino Project 6: Web-controlled music player

 

APC's arduino netplay breadboard
Our NetPlay project is built on a standard breadboard.

In our previous Arduino masterclass we briefly introduced the Ethernet Shield an Arduino expansion board that adds Ethernet connectivity plus microSD card storage. We used that storage as the basis of a simple one-button digital audio player. It was functional but limited to 8-bit mono WAV files with a 19kHz sample rate. We also gave you the software to create those specific files. The audio quality was a bit better than AM radio level which is good enough for audiobook and basic music playback.

Several weeks on and we’re continually astounded by this little Arduino Uno board and just what software developers are able to scrape out of its 16MHz/8-bit ATMEG328P microcontroller.

Thanks to recent online work by Lutz Lisseck it’s now technically possible to push this little chip to pump out 16-bit stereo audio with a 31.25kHz sample rate – that’s basically FM radio – with little more than six resistors and a couple of capacitors. We’re going to combine the Ethernet Shield with Lisseck’s work to create a stereo 8-bit audio player that comes with its own web server we’re calling NetPlay.

Getting around limitations

The ‘SimpleSDAudio‘ library makes it possible to push the boundaries of the Arduino Uno and create a standalone project that leaves us gobsmacked.

Unfortunately it’s not possible to combine the Ethernet Shield’s Ethernet function with 16-bit stereo audio – basically there just aren’t enough pulse-width modulated (PWM) outputs to go around. However we’re taking one of Lisseck’s ‘SimpleSDAudio’ examples and creating a stereo 8-bit audio player with 15kHz bandwidth that you can control via a web browser on your PC tablet or smartphone.

The $10 Ethernet Shield you can grab from eBay contains a Wiznet W5100 Ethernet controller chip that comes with its own TCP/IP stack. Combined with its microSD card slot which supports up to 32GB of storage and it’s a seriously impressive little add-on board. It’s enough to create your own little web server that can dish up web pages to a browser on your PC laptop tablet or smartphone. More importantly it’s a web server you can use to control the outputs of the Arduino Uno and get it to do some seriously cool stuff.

WebLED

To give you a taste we’ll start this month with a simple example: turning an LED on and off over your home network. Using the Ethernet library bundled with the Arduino 1.0.3 IDE it’s reasonably simple to create a web server that waits for incoming traffic and spits out HTML code back to the client. Using an HTML form our little WebLED sketch accepts data back from the client to control the digital output D5 to switch an LED on and off.

Sure it’s pretty simple but use your imagination and some extra electronics and that LED could be a motor an emergency beacon a video recorder model railway coffee machine or a water pump. You’ve also got up to 21 digital outputs you can individually control via the web exponentially expanding the possibilities.

The circuit is about as simple as you can get: a 470ohm current-limiting resistor and an LED. Go through the ‘APC_06_WebLED.ino’ sketch (download it from apcmag.com/arduino.htm under Project 06) to see how it works. You need little more than half a dozen lines of code to create a web server. In fact most of the code (and there’s not much of it there) is setting up the web page and parsing the response from the client.

This will give you a taste not only for the possibilities but also for how our NetPlay stereo audio player works.

$10 Arduino Ethernet Shield
The $10 Arduino Ethernet Shield provides microSD storage Ethernet and built-in TCP/IP stack.

Building NetPlay

Building our NetPlay project isn’t much more complicated than building the WebLED. In fact it’s pretty similar to the last project’s audio player.

Again we’re using the Arduino’s PWM outputs to turn digitally sampled audio back into an analogue voltage approximation. These outputs appear at the D5 and D6 pins on the Ethernet shield. (The Shield doesn’t do anything at this point – these outputs are feed-throughs from the Arduino board underneath.)

These are fed through a resistor divider network which doubles as a basic first-order low-pass filter to knock off some of the PWM clock signal to just leave the audio signal we want. If you’ve built the audio player in the last project you can use the same 3.5mm stereo socket so there’s no more soldering required.

Once you’ve programmed the NetPlay sketch into the Arduino you can power the project by using a USB charger straight into the USB port of the Arduino board. Plug an Ethernet cable into the Ethernet Shield and the other end into a spare port on your ADSL modem/router. Plug the Ethernet cable in first and then apply the power as the project will be up and running within a second or two of that power being applied.

Creating NetPlay audio tracks

While NetPlay can’t handle standard 44.1kHz/16-bit stereo WAV files (well not yet at any rate) we’ve made decent progress from the previous audio project jumping from 19kHz sample rate/8-bit mono PCM audio playback to 31.25kHz/8-bit stereo PCM.

Thanks to Nyquist’s Theorem a 31.25kHz sample rate gives us a practical audio bandwidth of around 15kHz which as we said before is FM radio territory and much better than the 9kHz bandwidth we were talking about in the last project.

However we still need to create these files so we’ve modified the Auduino Windows audio converter app from the last project to create a NetPlay version – it’s a Windows registry key file that integrates the encoding commands straight into Windows Explorer’s right-click context menu. When activated it converts any audio file into NetPlay stereo format using a combination of FFmpeg and SoX open-source audio converters.

Like in the previous project we also need to keep the files in an 8.3 DOS file naming format and our NetPlay audio converter does this automatically.

APC's NetPlay overlay diagram
Follow this overlay diagram when building our NetPlay project.

Install the converter

To install the NetPlay audio converter simply launch the ‘installnetplay.reg’ registry key file. It adds a key for the menu text you’ll see on the right-click menu as well as the commands we want those menu options to carry out. The ‘uninstallnetplay.reg’ file removes those registry keys and the menu entries.

First grab the ‘netplay.zip’ file from dl.techlife.net/apps/netplay.zip. Unzip it to your C: drive where it will automatically create the C:netplay folder and dump the contents there.

We use a combination of FFmpeg to convert audio files into a standard 44.1kHz/16-bit stereo WAV format and feed that into SoX to create our 31.25kHz/8-bit stereo raw PCM files. FFmpeg can also create these files but unfortunately it has fixed steps in its audio bandwidth settings that are locked irrespective of the sample rate you choose. For example create a 19kHz audio file with FFmpeg and the audio bandwidth is no better than 7.5kHz – the same bandwidth you get when creating a 16kHz file. Do it with SoX and a 19kHz sampled file gets a bandwidth closer to 9kHz which sounds much better. The same thing happens creating a 31.25kHz sample rate audio file – you get 10kHz bandwidth with FFmpeg but 15kHz with SoX.


Launch the ‘installnetplay.reg’ registry key file to install the audio converter.

 

How NetPlay works

The key to NetPlay is Lutz Lisseck’s ‘SimpleSDAudio’ library. What makes this library impressive is that it greatly increases the sample rate/audio bandwidth possible from an Arduino Uno board. The key to that is the speed of data processing and it’s only made possible by using large dollops of Assembler programming rather than the standard Arduino C++ derivative programming. It’s also impressive because it uses what little RAM the Arduino Uno’s ATMEGA328P has (just 2KB) and manages to create a loopback buffer that continually reads the audio file data from the microSD card slot into two 512-byte segments – while the data is being played from one it’s being loaded up into the other.

The circuit for our NetPlay audio player
The circuit for our NetPlay audio player.

 

Limitations

In order to get the comparatively high sample rates we’re using the microSD card slot on the Ethernet Shield has to run at half SPI speed at least. The diode-based level translation circuit we used in the last project with that cheap $2 SD card reader won’t work (at least not reliably). You’d need to add a CMOS 74HC4050 level translator chip and do the translation properly. Thankfully the Ethernet Shield has this covered so you can use any microSD card and it should work perfectly well.

The other limitation is a little more serious and prevents us from playing back 16-bit stereo audio. The Ethernet port and the microSD card reader both operate using the SPI bus so only one device can be accessed at a time. Given the way our NetPlay audio player works that’s not too much of a problem. More importantly the Ethernet port uses pins D10 through D13.

Lisseck realised that by using two PWM outputs and combining them with a simple 256R-R resistor ladder you could approximate 16-bit audio output. The problem is the ‘SimpleSDAudio’ library requires the two primary PWM outputs to be D9 and D10 with the secondary two as D5 and D6. With D10 being locked up by the Ethernet port it means not only can the Ethernet Shield not deliver 16-bit stereo you can’t even get 8-bit stereo.

The fix

While there’s no way at present around the problem of D10 being locked up it is possible to re-route the primary PWM outputs to D5 and D6 so that we can at least get 8-bit stereo. We’ve applied these modifications to the ‘SimpleSDAudio’ library we’ve included in our sketch package so we can at least get 8-bit stereo happening. Unfortunately the library doesn’t yet support 16-bit mono which would’ve been nice…

However there’s one extra task you must do that we can’t. In our ‘netplayarduino.zip’ file (available at apcmag.com/arduino.htm under Project 06) you’ll find a ‘wiring.c’ file. This has to replace the one inside the Arduino 1.0.3 IDE which you’ll find under hardwarearduinocoresarduino. Rename the original file as ‘wiring_orig.c’ and then copy the new version across.

In short this enables the swapping of these PWM outputs (D9/D10 to D5/D6) as well as changing the function of the interrupt timer that some of the back-end functions use. Note that in order for other Arduino project sketches to work correctly you’ll need to swap the original ‘wiring.c’ file back in when you’re done with this one.

Ethernet/SD card code

Lisseck has also added in a basic FAT32 file system reader for the microSD card to the ‘SimpleSDAudio’ library which makes it pretty trivial to read the contents of the card and play audio files from it. By bringing in the Ethernet library as well you can use the ‘SimpleSDAudio’ library to automatically read the filenames from the card and output them as part of HTML code. The Ethernet library turns the Arduino Uno into a basic web server you can access via any PC laptop tablet or smartphone on your home network.

Making things simple Lisseck provides an example sketch for doing exactly this in his library. However because of the D10 issue he’s limited the example to 8-bit mono audio files only through the D9 output. We’ve modified the library and the example to handle 8-bit stereo through outputs D5 and D6 instead (you must still make the ‘wiring.c’ file substitution in the Arduino IDE folder) and improved the web server code so you can choose different songs and stop playback at any time rather than having to use the browser’s ‘Back’ button all the time.

The ‘SimpleSDAudio’ library is so CPU efficient that we’re not even using half the capacity of the ATMEGA328P processor. As it’s capable of playing 16-bit stereo at the same 31.25kHz sample rate there’s room left over to add your own extra functionality (within reason) and still get stereo audio happening.

APC's WebLED network-controlled LED overlay diagram
We’ve modified Lisseck’s example with a ‘play and stay’ web interface and stop link.

How you use it

First build the project following the circuit and overlay diagrams. Next grab the ‘netplayarduino.zip’ file unzip it to your C: drive and copy the ‘SimpleSDAudio’ library to your Arduino IDE’s libraries folder. Next back up the original ‘wiring.c’ file we mentioned before and copy in the new one from the ZIP folder.

Fire up the Arduino IDE and load in the ‘apc_06_netplay_v4.ino’ sketch file. The most important thing here is to change NetPlay’s IP address to one that suits your home network. It’ll need to match the first three 8-bit numbers of your network; for example if you live on a 192.168.0.xxx subnet pick a spare address from that same subnet. Change the sketch save it and program the Arduino Uno board.

After that using NetPlay is pretty easy: create a bunch of audio files using our NetPlay audio converter and copy them to a microSD card slot. Load them into the Ethernet Shield and start it up. On your client enter the Arduino’s IP address into your browser and you’ll see a list of filename hyperlinks. Click on one and that file will begin playing through NetPlay and your powered speaker system. Click on another at any time and the new track will start. Click the ‘Stop Playback’ link to stop.

In the end the Arduino Uno controller does double-shift as an audio player and web server in one.

Give it a try

Granted there’s not much in the way of hardware but this is still a pretty complex example of what the Arduino Uno is capable of. The fact that it can do all this with just a handful of components makes it even more impressive. While we all love our GHz-powered computers and tablets hopefully this is a good reminder that not every application needs more than 16MHz of CPU clock speed and a huge operating system to run it. When you build for a specific application you might be surprised at just how little processing power you actually need to interact with the real world.

APC's WebLED network controlled LED circuit diagram
It doesn’t get much simpler than this for a network-controlled circuit. 

 

Abit about 8-bit audio

Much of today’s music is so dynamically compressed that you don’t need the dynamic range afforded by having 16 bits of sample depth. Basic 8-bit audio gives you 48dB of dynamic range which is often more than enough for R&B rock and hip hop. For classical music it’s woefully inadequate because you’ll clearly hear the background noise during quieter passages – a reason why 16-bit/96dB dynamic range audio came alive with the first audio CDs.

For upcoming Arduino projects follow us on facebook twitter or RSS.

 

 

  • Marty Boroff

    Darren I seem to be having problems using a UDP client or Ethernet client and playing a file. I took the example with the helper and started to add my time get client that uses UDP. as soon as I start the service the sounds stops.

    And suggestions on how to narrow the problem down besides adding one line of caode ar a time?

  • http://darrenyates.com.au Darren Yates

    Which design are you using – the SD card module or Ethernet module? What you describe (start service, sound stops) is what can happen with the SD card module if you use the resistor level translator (as I mentioned in the story, not all cards work with this method).
    Cheers,
    Darren.