Introduction: Smartphone As WiFi Headphone (for Kodi)

I have XBIAN (kodi on Debian) running on my rPi2 (Raspberry Pi 2) attached to a 27" monitor with inbuilt speakers. I chose this distribution as I wanted to tweak Debian settings a bit in order to use bluetooth (BT) controller and headphones (in the future). I had my BT controller working and things were running smooth.

Soon, I needed a way to wirelessly stream audio (living with a baby in an apartment) and I struggled a lot with BT headset. It paired fine but would disconnect immediately. I decided not to waste any more time on BT headset and instead started looking into uPnP. Some reading revealed that uPnP won't let me stream audio from whatever I have running on my kodi at any time. So, I needed a point-to-point solution over wifi for audio as BT did not work for me.

The idea is to have something setup on XBIAN (rPi2) and connect to it from smartphone (Android/iOS) which will act as Wifi headphones. This is a software based solution with very little scripting. We are going to install Linphone on both XBIAN machine (rPi2) and the smartphone (Android) and stream audio directly between them.

Pros: 1-WiFi has better range than BT. 2-$0 solution. 3-No custom software. 4-No additional hardware required. 5-Audio remains in you local network. 6-Uses generic mobile App which can also be used to make VOIP calls.
Cons: 1-Consumes slightly more battery than BT. 2-DIY.

IMP: The kodi machine and the smart phone should both be on the same network(LAN). While the phone will use WiFi, the kodi can use either WiFi or ethernet cable.

Step 1: Install Linphone (at Kodi)

Exit kodi to go to the console/command prompt and run these commands:

To become root so you don't need sudo for almost every command.

xbian@xbian ~ $sudo su

Prompt should change from $ to #. Now, Install non GUI version of linphone

root@xbian:~# apt-get install linphone-nogtk

Run linphonec to see if it works

root@xbian:~# linphonec
Ready
Warning: video is disabled in linphonec, use -V or -C or -D to enable.
linphonec>
linphonec> quit
Terminating...
root@xbian:~#

We can ignore the warning about video.

Step 2: Autostart Linphone As a Daemon (at Kodi)

We want linphone to start automatically when system boots up. We also want it to be in auto answer mode and start sending whatever it hears on the loopback/fake snoop device added in step below.

root@xbian:/home/xbian# vim /etc/init.d/linphone
#! /bin/sh
# /etc/init.d/linphone
### BEGIN INIT INFO
# Provides: linphone
# Required-Start: $local_fs $syslog $remote_fs dbus snd-aloop
# Required-Stop: $local_fs $syslog $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start linphonec daemons
### END INIT INFO
# The following part always gets executed.
echo "Linphone"
# The following part carries out specific functions depending on arguments.
case "$1" in
start)
echo "Starting linphonec daemon"
linphonecsh init -a
echo "linphonec daemon is alive"
;;
stop)
echo "Stopping linphonec daemon"
linphonecsh exit
echo "linphonec daemon is dead"
;;
*)
echo "Usage: /etc/init.d/foobar {start|stop}"
exit 1
;;
esac
exit 0

Save file and exit vim.

Now, we start linphone manually to check if above script works. We'll soon make it start automatically on reboot.

root@xbian:~# /etc/init.d/linphone start
Linphoned Starting linphonec daemon
linphonec daemon is alive

Now, check whether linphone daemon is waiting for connections:

root@xbian:~# netstat -ntulp | grep linphone
udp 0 0 0.0.0.0:5060 0.0.0.0:* 22101/linphonec

Lets make this script run at startup & reboot, so we'll have the daemon always running:

root@xbian:~# update-rc.d linphone defaults

Lets reboot and check linphone daemon is waiting for connections again using:

netstat -ntulp | grep linphone

Step 3: Setup Capture Device to Snoop Audio (at Kodi)

Confirm that rPi does not have any capture device (source of sound e.g. a mic). This helps in identifying when a capture device is added below.

root@xbian:~# arecord -l
**** List of CAPTURE Hardware Devices ****

So, there are no capture device by default.

Now add fake capture devices:

root@xbian:~# modprobe snd-aloop

Verify that it succeeded:

root@xbian:~# arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: Loopback [Loopback], device 0: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
... #2 to #6
Subdevice #7: subdevice #7
card 0: Loopback [Loopback], device 1: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
... #2 to #6
Subdevice #7: subdevice #7

Finally, lets make this change permanent:

root@xbian:~# vi /etc/modules

This will open the modules file. Go to end of this file and under the exisiting line that says snd_bcm2835 add snd-aloop on a new line. This will automatically add the capture device on a reboot.

Lets reboot now:

root@xbian:~# shutdown -r now

After it reboots into kodi, exit codi again and run this command to verify it survived reboot:

arecord -l

Step 4: Audio Plumbing (ALSA at Kodi)

We need to do some plumbing to make kodi/xbmc sound output flow to the loopback capture device. It will then be picked up by linphone to be sent over WiFi. Since XBIAN uses ALSA (no PulseAudio) we'll use that.

First, we create the config file for this:

root@xbian:/home/xbian# vim /etc/asound.conf
# default device
pcm.!default {
type plug
slave.pcm "loop"
}
# output device
pcm.loopout {
type dmix
ipc_key 328211
slave.pcm "hw:Loopback,0,0"
}
# input device
pcm.loopin {
type dsnoop
ipc_key 686592
slave.pcm "hw:Loopback,1,0"
}
# duplex plug
device pcm.loop {
type plug
slave {
pcm {
type asym
playback.pcm "loopout"
capture.pcm "loopin"
}
}
}

Save text & quit the editor.

Now we need to reboot:

root@xbian:/home/xbian# reboot

When it comes back and we exit to the console, we first verify that the plmbing is in place:

root@xbian:/home/xbian# aplay -L | grep loop
loopout
loopin
loop


Step 5: Change Audio Output (at Kodi)

We need to tell kodi to start sending audio to the loop device instead of HDMI/Analog as we created during plumbing.

Go to kodi home or main screen.
Goto SYSTEM -> settings
Goto System
Goto Audio output
Click on Audio output device -> select ALSA: Loopback (loopout), Loopback PCM

Exit back to home and then try to play a stream, there should be no sound from HDMI/Analog.

Step 6: Install Linphone App (on Smartphone)

We are going to install free Linphone App on Android and call our linphone daemon on xbian to listen to live audio of the stream playing on kodi.

Install Linphone app from Google Playstore. (I think there is an iOS version available to Apple users).

We are going to place a direct call between the app and the daemon running on rPi/xbian or the kodi machine. Lets assume it has IP address 192.168.1.3

Launch the app. Don't create an account if it asks to. we don't need to login to any VOIP server. The app should show Not registered on left top corner.

Now, tap on Number or address field of the app and type sip:192.168.1.3 and press call button on the app.

The app should now get connected and you should hear the audio of the kodi stream. It might be low, so you would have to bring the phone near your ear to hear it. You could tap on the speaker icon on the app to activate speaker phone and it should be louder. You could also connect earbuds for private listening.

Step 7: Tips

Voice out of sync with video?
This setup like any other network based streaming might introduce some delay making audio & video a bit out of sync. Fortunately, kodi has an Audio offset setting that if set to ~ 0.200s will make video & audio in sync again.

Echo?
Keeping the mic on the App muted will avoid hearing yourself or other noises.

No Audio?
If you forward/reverse your video at kodi many times, the sound might stop even if the app is in call with kodi. If it happens, try play/pause video a couple of times and you should have the sound back.