All Room Home Audio System - Notebook

My latest project is an all room home audio system. Why and how has this come about? It's something I have always wanted to do but has never been at the top of that very long list. Recently it has climbed the ranks, though, because I've just bought my first home - and now I want things exactly how I have imagined they would when I first bought a house. What am I trying to do? I want to be able to listen to any any (reasonable) audio source in the house from any room, or all the rooms, or a combination of the two! Let's say I am cooking, but also working on some other crazy experement in another room....I want my music in both rooms so as I move about the house I don't miss out on my favourite songs! Or I'm watching a film with friends but need the toilet...I want to pick up my wireless headphones and keep up to date with at least the audio while I am gone! I know, I'm crazy and most people aren't interested in such a pointless(?) system, but for me this is a pressing matter!! One important requirement of this project is that I need all "recievers" to be playing exactly (to the human ear) in sync with each other, this is not the norm for audio/video streams. If two people stream a BBC radio station from thier website, they will actually be listening at two different points in the steam, possibly seconds appart. That is fine in this case, because they live in different houses, but if they were in two adjoining rooms that would be encredibly annoying!

Here is where I'm going to document what I am up to:

20th April 2016

Today I have created a new virtual machine on my server which is going to be the "transmitter" for this system. This machine doesn't have a sound card at all, so to get external sources (TV, radio, phone etc) streamed is going to be impossible with this machine currently - I will either buy a sound card with lots of inputs for it and pass it through to the VM or find another host for the "transmitter" but it will do for now. I didn't give the machine much in the way of power - it's allowed a single core of my octo-core Intel Avoton CPU, 2GB RAM and has 16GB of disk space allocated to it. I've installed Ubuntu server (12.04 I think?), enabled SSH and hooked it up to my "Home" NFS share...which happens to have all my music on it which I can test with. The machine is nothing special and we won't worry about that much from now.

Now, most instances of Ubuntu Server in the wild don't really tend to need sound drivers, so I had to install them:

sudo apt-get install pulseaudio

The forum post I was following says that you need to edit the /etc/init.d/pulseaudio file, but I found that most of it was correct in the first place, what I did change was the line below:

PULSEAUDIO_SYSTEM_START=1

This was previously set to 0. I think this starts Pulseaudio when the machine boots up, but if I'm honest I haven't actually rebooted the machine a single time since the OS was installed yet! I will do some tests later...if I remember.

Next I needed to disable the Pulseaudio module module-suspend-on-idle. This is done by simply commenting it out in /etc/pulse/system.pa:

#load-module module-suspend-on-idle

This module would disconnect our audio sink from pulseaudio if there was no audio playing. Disabling this option on an audio streaming server sounds good to me. I think it's because the stream might stop when pulse audio goes idle, but I haven't tested this - I would also like to look into it at some point.

While still editing /etc/pulse/system.pa I added the following two lines:

load-module module-null-sink sink_name=rtp_andrew format=s16be channels=2
load-module module-rtp-send source=rtp_andrew.monitor

This adds a new audio sink to pulseaudio, which is a network streaming sink - exactly what I want. I've given it a name, because the final plan is to have a couple of "radio stations" in the house, one for me and one for my wife. Currently, I'm just playing with one though! Pulseaudio will, by default, multicast the steam to 224.0.0.56, but you can change this by adding the following to the module-rtp-send line above:

destination=224.0.0.57

For me, the default is fine..at least for now.

Once all this config was saved, I tailed the syslog (sudo tail -f /var/log/syslog) so I could see if there were any errors when I started pulseaudio:

sudo service pulseaudio start

I was amazed because everything looked happy in the log! Now I want to see if I can play this back on another machine. For now I'm just going to try playing it back in VLC as a quick solution to see if the "transmitter" is actually, well, transmitting!

Before I can play the stream in VLC I need to work out what the address of the steam is. I found a nifty command for doing this:

tcpdump -n net 224.0.0.0/8 -c 10

This will list several lines all of which followed the same sort of form as this:

20:58:49.672990 IP 10.1.10.22.40491 > 224.0.0.56.46718: UDP, length 1292

So, the first IP address and port is the source of the audio stream, on the virtual machine I am working on. The second IP address and port is the multicast address and port of the audio stream - this is what we want. I'm not going to go into what multicast is here, because it will take a long time, and I'm definitely not the best person to ask..google is. From the above though I now know what to stream from VLC - I added the following to my VLC playlist on my local computer:

rtp://224.0.0.56:46454

This will be different for you, if you're doing the same thing - you will need the tcpdump command above to find your address/port. My VLC seemed happy with this, but interestingly the time counter still sat at 00:00 as if it wasn't playing anything. To be sure I went to "Tools" -> "Codec Information" and saw that I was indeed streaming a 16 bit PCM stream.

Now, obviously I can't hear anything despite everything seemingly working because the transmitter isn't actually playing/recieving any audio. Next, I needed to play something on the server and see if it came out of the speakers on my local PC. For this I decided to use mplayer as it's easy to use and can be terminal based. First it needed installing:

sudo apt-get install mplayer

According to the Ubuntu version I am running there is also an mplayer2, but I don't know what the difference is and I only need to play a simple audio file for testing so I went for mplayer. Once installed I typed the following command to play an audio file:

mplayer -loop 0 BBCRadio1AladTranslatingFrench.mp3

This failed claiming I didn't have permission to open the pulseaudio device (or any of the failover audio devices it tried to open). The error was printed on the screen, but also in the syslog printed by pulseaudio. After some googling I found out that each linux user needs to be added to some audio groups before it has permission to actually use the sound devices:

sudo gpasswd -a andrewcornford pulse-access
sudo gpassed -a pulse audio

Once this was done I ran the same mplayer command and BOOM, instant sound coming from the speakers on my computer...a completely separate machine to the source of the audio!! The audio was very very choppy, but I think that is my shockingly terrible wireless router handling multicast traffic. My computer is also on a different subnet to the VM and there is a NAT between the VM and the computer with VLC, so I need to look into this and how to solve it. I'm fairly sure it's not the server struggling to stream the audio, because a simple top tells me that the machine is only using 2% of it's virtual CPU. I will need to play around with this.

I then got my work laptop out, opened VLC and got it to also stream the audio. It was very very choppy too, and I'm not sure the audio is in sync, but it is hard to tell with such bad audio. At least I can stream to two devices!

Things I still need to do/look into:

Resources