Simple Protocol Player

Play store link

Why?

I want to be able to watch movies and videos on the TV, but I want the audio to be heard only through headphones.

And I had a few requirements:

  1. Wireless
  2. Broadcast
  3. Low latency

Wireless

One solution is to run a headphone extension cable from the TV.   But that gets unwieldy pretty quickly for distances greater than a few feet.

Broadcast

I want the audio to be heard by multiple people at the same time through each individual set of headphones.

Low-latency

The audio has to be rendered with the least amount of latency possible so that the video could be watchable.  If the audio is delayed, then the dialog/sound effects/etc wouldn’t be in-sync with the video.

PulseAudio

Since my HTPC is Ubuntu 12.04 running XBMC, I figured I could reuse some existing OSS software to stream audio from Ubuntu to a mobile device.  And since I have an Android phone, I figured I would start there.

This project was really easy to implement because PulseAudio on Ubuntu already supports a TCP stream of uncompressed PCM audio.  The only requirement is to add a few lines (below) to enable the module.

The documentation for the module is at http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Modules/#index20h3

And the Android app simply reads data from a socket and uses Android’s AudioTrack to render the audio.  The app is based on the random music player SDK example.

It’s so glitchy

The challenge is to try to keep the video on the TV synced with the audio.  And that means rendering the audio with the lowest latency possible.

The very first versions of the app do not handle this well.  Basically,  when the app detects it’s falling behind, it simply starts dropping data left and right.  This results in obvious glitches in audio.  It sacrifices quality for latency because delayed audio while watching movies sucks.

Improvements will be made.

Setting up PulseAudio

[Also check out the link to the module documentation above]

There are only a couple of steps:

  1. Determine which source to stream
  2. Edit config files so with the proper parameters
  3. Restart PulseAudio

I am running Ubuntu 12.04.

Determine which source to use

Open up a terminal in Ubuntu and type

pactl list sources short

This will spit out a bunch of text, but what you’re looking for is the ‘analog-stereo.monitor.’  I have edited the output from my machine and highlighted important items in red.

0    alsa_output.pci-0000_01_00.1.hdmi-stereo.monitor    module-alsa-card.c    s16le 2ch 44100Hz    SUSPENDED
1    alsa_output.pci-0000_00_1b.0.analog-stereo.monitor    module-alsa-card.c    s16le 2ch 44100Hz    SUSPENDED
2    alsa_input.pci-0000_00_1b.0.analog-stereo    module-alsa-card.c    s16le 2ch 44100Hz    SUSPENDED

Look for “analog-stereo.monitor” and take note of the index number on the left.  In my case, it’s 1.

Edit config files

You will need to edit the config files to load this module with the specific parameters.  To do so, type (you will need the sudo password)

gksu gedit /etc/pulse/default.pa

Add the following line near the bottom, substituting your source index:

load-module module-simple-protocol-tcp source=1 record=true port=12345

I had problems with the default port of 4711 because it seems to be already in use and so I just choose 12345.

For mono, you can use channels=1 and for a lower sampling rate rate=24000.  The app has been updated to include support for this in an attempt to reduce latency.

Restart Pulse

Restart PulseAudio with the new configuration

pulseaudio -k
pulseaudio --start

And that should be it.

Start up the app, type in IP address/port of the Ubuntu box and stream audio to your Android device.

Windows server

A corresponding Windows server has been published to github.  Please see the following for more information: http://kaytat.com/blog/?p=332