Or: How Robert Damphousse and I re-invented the phone using two EeePCs and an ad-hoc wireless network.
The first prototype of Music for Lovers was wireless: Robert Damphousse and I did the following little experiment to bidirectionally stream binaural audio between two EeePCs in realtime. Well, something sort of like realtime.
We had two Asus EeePCs 701 running Debian and decided to use the Icecast2 streaming server, Ices2 as the streaming source, and mplayer as the client. On each machine, Ices2 would feed audio to the Icecast server on the same machine. The mplayer client on the respective other machine would then pick up that stream. All networking was done through an ad-hoc wireless network, which means that data was sent peer-to-peer, and there is no dependence on a router or any other network infrastructure but the wireless cards of the EeePCs themselves.
Getting audio input working on EeePC under Debian
My own machine suffered from a non-working audio input. Note that I had installed from the adopted EeePC Debian image available and described here. Neither line-in nor the internal microphone would work. After a bit of research, we found out that the problem was an amixer setting which cannot be set in the alsamixer GUI:
amixer set 'Capture' unmute cap
did the job. I can't quite remember where we got that information from, unfortunately.
Icecast2 streaming server installation and setup
sudo aptitude install icecast2
I then had to add myself to the 'icecast' group:
usermod -a -G icecast my_user_name
Also, some read/write permissions needed to be fixed for successful logging:
chmod -R g+w /var/log/icecast2 chmod -R +r /var/log/icecast2
And in the configuration file - which we copied from /etc/icecast2/icecast.xml and modified for our needs - we had to change these settings from 'nouser' and nogroup':
<security> <chroot>0</chroot> <changeowner> <user>my_user_name</user> <group>icecast</group> </changeowner> </security>
Icecast2 then needs to be run as root; e.g. with the default configuration file:
sudo icecast2 -c /etc/icecast2/icecast.xml &
Ices2 streaming source installation and setup
sudo aptitude install ices2
Complained about not being able to write to a non-existing directory, so we did
sudo mkdir /var/log/ices
Ices2 then needs to be run as root, e.g. for live input streaming using an example configuration file:
sudo ices2 /usr/share/doc/ices2/examples/ices-alsa.xml &
Picking up the stream with mplayer
To pick up the stream set up above on your local machine, one can tye
Or on a remote machine:
Ad-hoc network setupAs Robert found out here, the madwifi driver which Robert and I used for our EeePC's network cards does not support the ad-hoc network mode from as it comes. In order to set up an ad-hoc network, you need to type:
sudo wlanconfig ath0 destroy sudo wlanconfig ath0 create wlandev wifi0 wlanmode adhoc sudo iwconfig ath0 essid my_ad-hoc_network
We then simply assigned ourselves different IPs on the same subnet, e.g. on my machine:
sudo ifconfig ath0 192.168.1.2
I then could pick up Robert's stream from his machine at 192.168.1.3:
and vice versa. In case you want to change back later to a regular, router-based Infrastucture ('managed') network without rebooting, type:
sudo wlanconfig ath0 destroy sudo wlanconfig ath0 create wlandev wifi0 sudo iwconfig ath0 essid my_infrastructure_networkAnd retrieve your IP by whatever method the network provider supports (e.g. DHCP through 'sudo dhclient').
We used the default icecast2 config file from /etc/icecast2/icecast.xml as a starting point and adopted it to our needs Here is the full configuration file we came up with. In particular, we focused on the following settings:
This is the default queue-size value. Decreasing this doesn't seem to drastically decrease the latency, but keeping it high can help to increase the
quality (higher samplerate, stereo rather than mono, etc.) of the stream without breaking it.
Deciding not to burst-on-connect brought down the latency from 15 to 5 seconds in a test where source, server, and client were all running on one machine.
We did not change anything here, but it might be worth to stick to only one client, which is all we'll need.
We did not change anything here either, but it might be worth to limit ourselves to the one source we require.
We started of from /usr/share/doc/ices2/examples/ices-alsa.xml and adopted it to our needs, focusing mainly on the settings which define the audio quality of the stream, which we wanted to push up towards 44.1kHz stereo. Here is the full configuration file. In the <encode> section, we changed the settings as follows:
<encode> <quality>0</quality> <samplerate>44100</samplerate> <channels>2</channels> </encode>
We also set <downmix> to zero:
And put in the following in the <resample> section:
<resample> <in-rate>44100</in-rate> <out-rate>44100</out-rate> </resample>
We tried to set mplayer cache down to 32 kBytes, but that didn't seem to improve things drastically. This setting can either be set in ~/.mplayer/config, or by calling mplayer with the -cache flag. When the cache is set too high (e.g. 5000 kBytes), mplayer won't pick up the stream at all.
Latency test results
With the setup as described above, we got about 5.2 seconds latency when streaming audio between ourselves.