Airplay Audio Amplifier



I launched this project because I wanted to grow a better understanding of a few topics, which included creating a custom linux distribution, rerouting kernel connections through the device tree, and diving into creating custom PCB designs for the hardware I would be using. I knew I wanted some combination of the above topics which is why I choose to create a custom airplay amplifier for either a multi-room stereo system or even a single unit running in mono mode.

The end result of the project incorporated a SBC which was chosen to be the beaglebone black running a custom yocto linux build, that incorporated airplay modules for iOS/MacOS devices to stream directly to. The beagle bone was then connected to a UDA1334 audio DAC for audio input from an I2S stream. The DAC was then connected to a TPA3116D2 class-D audio Amp for analog sound to be played out a set of speakers.

Test Image


I began looking into what would be a good starting point where I could allow an audio stream to flow out of a simple MCU onto a speaker. I had both a beaglebone black (BBB) and a raspberry pi from past projects and thought it would be really convenient to utilize one of them for this endeavour. I decided to go with the beaglebone black mostly because of the sample rate of I2S but also because the master clock on the RasPi isn’t accessible which would require any form of DAC to operate asynchronously.

After choosing the BBB, I then wanted to test out the I2S by using a simple class D amplifier which was chosen to be the MAX98357A. I was able to setup a small circuit that allowed the BBB to be flashed with “Volumio”, which was a library I found to allow an airplay connection to be streamed through I2S to the DAC and then played out a speaker.

Test Image Test Image Test Image

I then began digging first into what I might need on the firmwares end, which is where I stumbled upon Yocto. Yocto would allow me to create a custom linux build for my needs but definitely seemed a little overkill for this project. There were other platforms out there that would allow me to create a custom build with not nearly as much overhaul but Yocto seemed to really allow the user to get down to very specific details especially if any form of cross platform would come of the future. It also seemed to be a well known tool and I would be bound to come across it again at some point, so why not learn now.

Looking into a lot of what Yocto has to offer, I was able to realize quickly that BBB’s firmware was able to be embedded into a Yocto image in a relatively seamlessly way based on the large user base from the open source community.

After trying to build a simple image for my BBB, I quickly found out I needed to get a better grasp on the bitbake tool if I wanted to allow for any form of custom builds later on. I found it really interesting to see how using simple layers and configurations, you are able to create such a powerful deployment tool in a relativity fast way.

Next, I moved onto finding an efficient way for casting an airplay stream onto the board through the local network. The objective of the project was not to create my own form of airplay protocol but could be an interesting project for another time. This led me to find a library called “shairport-sync”. This would allow airplays protocol to be utilized through another protocol called “avahi”, which I could then send through an I2S connection as long as a local network would be connected to my BBB.

After running through multiple tests, I began to notice a large amount of cutouts in the sound from time to time. Using a few debugging techniques I narrowed the problem down to the processor overheating from the stream itself. After long periods of time with the shairport-sync stream open, the cpu would actually throttle itself back which would cause a cutout in the audio stream. I solved this pretty quickly by incorporating a small heatsink onto the board. After testing with my setup from before, it was shown to work and I moved onto the next phase.

These next steps seemed to be the most challenging, mostly due to my lack of knowledge in actually getting my hands dirty within any form of a device tree before. I knew only what the device tree allowed, which was a way for the kernel to understand the hardware paths used at boot up but also for any custom peripherals to be activated or deactivated. I began researching a lot to understand not just the BBB’s device tree design but also general topics that could pertain to other embedded devices.

I was able to find a powerful structure that was called “overlays”. Introduced in the 3.8 Linux Kernel, these overlays would allow you to make changes to the pinmux without having to change the baseline device tree or even reboot your machine. Since the beaglebone black has multiple functionalities on each pin, I was able to use custom overlays to disable certain pin configurations such as hdmi video/audio. This was done because the I2S route on the board uses the hdmi audio as a beginning routing path but then leads off to certain pins on the P9 header. The reason why I disabled the hdmi video/audio was to allow a screen to be hooked up to the board but also keeping the I2S connection. If that overlay was not in place, the I2S connection would be overridden by the audio streamed in from the hdmi audio.

While building out a lot of the firmware, the process of creating an amplifier was also in place. Eagle was used to do both the schematic and board design mostly because of the free tier of software that they offer. I then used a digital to analog converter (DAC) to allow the I2S signal to be transferable for the speaker. I went with one of TI’s DACs, which was the PCM5100 and the NCP2811 from On Semiconductor. Both of these parts were picked because they had a good baseline functionality, the audio amp was from a class D category, and the power consumption of both could be powered through the beaglebone without needing an external supply load.

Test Image

Test Image

Future Expansion:

To allow this project to be further improved, I would like to add a signal processing unit into the mix to allow a more in depth control over the audio stream. With this integrated into the scheme, I would be able to utilize filtering and depth control to allow a more unique perception of the sound to be routed. I would also want to incorporate a small LCD touch screen for the beaglebone or even use bluetooth with a mobile application to allow connecting to a network be more seamlessly integrated.

Utilizes: C, Python, Yocto, Linux, Eagle, PCB Design, Beaglebone Black, I2S Protocol