Motivation

Isn't it a pity that we need to stretch the audio cable when we travel with our laptop from the desk to the sofa? And isn't it bothering that we need such cable at all? And how much better that would be if we could move our standalone loudspeakers away from the desk? All these issues would be solved if we had a "virtual sound card" on the network, where we could stream our music, and then the other machine could receive the samples and turn them into sound using a physical sound card.

Fortunately all this has been already developed and is known as pulseaudio sound system. The only thing which we need is a small, headless machine which can act as a server, so that we can set it up somewhere in the corner of the room, and forget about it. One of the great options here is an OpenWRT capable router. The steps to make this option working have been described below.

How To

1. Obtain the hardware

What you need is:

  • Router
  • USB Hub
  • USB Sound Card
  • USB Flash Drive
  • Active Loudspeakers

Many options are available. Before purchasing the router make sure that it's OpenWRT compatible. Please also note that it should be possibly computationally efficient. E.g. TL-WR1043ND v1 seems to be too slow, while v2 works fine. Additionally if your host PC doesn't have COM port, you may find it useful to have RS232 to USB converter if you want to debug OpenWRT configuration using serial port of the router.

2. Connect everything

According to the common sense:

3. Install OpenWRT on the router

http://wiki.openwrt.org/toh/tp-link/tl-wr1043nd

4. Enable USB Storage

http://wiki.openwrt.org/doc/howto/usb.storage
You can skip this and following step if your router has enough flash to install all the drivers required by the application.

5. Move filesystem to external flash drive

http://wiki.openwrt.org/doc/howto/extroot
Two methods are available. "pivot overlay" is recommended, however "pivot root" looks more straightforward. Don't use "sync" option in fstab for rootfs. It makes writes to flash drive very slow on. Use async option instead.

6. Mount swap partition

http://wiki.openwrt.org/doc/howto/storage
You can skip this step if your router has enough RAM to load all the drivers. In the setup described here, this step is optional. Remember to modify fstab in order to make the changes permanent.

7. Enable USB audio devices

http://wiki.openwrt.org/doc/howto/usb.audio

8. Install pulseaudio

http://wiki.openwrt.org/doc/howto/pulseaudio
If pulseaudio cannot access your hardware, you may need to give SUID to /usr/bin/pulseaudio

# chmod u+s /usr/bin/pulseaudio

You may also want to simplify resampling method which will unload CPU of your router significantly:

# vi /etc/pulse/daemon.conf
# resample-method = trivial

9. Configure the network

...according to your preferences. It's convenient to use LuCI interface for that. My configuration uses another router to provide wireless access to the local network. However it's also possible to use the same router for both, audio processing and maintaining LAN/WLAN network.

10. Configure your host machine

All you need is pulseaudio client which is preinstalled for most of the modern linux distributions. You don't need to configure anything.

Usage

After accomplishing all the steps, your USB sound card should be available in the network as pulseaudio sink. Now, for each application you should be able to select whether you would like to use local, or remote sink. In order to make this selection, please use pavucontrol:

Known issues

Normaly it should be avahi daemon who let everyone in the network know that there is a remote sink available in the network. The way how pulseaudio plugin pulseaudio-module-zeroconf communicates with avahi is by taking dbus into use. Since dbus has been replaced by ubus in OpenWRT, there are difficulties with having all three components working together. As an effect, I decided to not use avahi at all and inform my host machine manually about the sink on the network. The command which is required is:

$ pacmd load-module module-tunnel-sink server=192.168.1.202

Where 192.168.1.202 is IP address of my OpenWRT.