Last year before the Doo Dah Parade in Pasadena, California we at Poo-Bah Records setup a live radio transmission to broadcast what is playing in store, and to start doing live shows. We had an iMac computer donated to us and we used this computer as the base station. Our original plan was to use the Beagle Board and to provide a simple interface a single button to turn on and off transmission — perhaps with even an “on-air” light. The iMac had little memory, we upgraded it, and I installed Debian PowerPC on it. From here it’s been an process of trying many different configurations of software with differing results.

The first successful configuration was using Darkice on the “base station” and Icecast on our webserver — WebFaction allows custom built apps to run. It was a simple setup that didn’t record, it merely connected and broadcast over the Net.
First configuration for Darkice
[general] duration = 0 # forever bufferSecs = 5 # seconds reconnect = yes [input] device = hw:0,0 sampleRate = 44100 # Hz bitsPerSample = 16 # bits per sample channel = 2 # channels [icecast2-0] format = mp3 bitrateMode = cbr bitrate = 92 quality = 0.3 channel = 2 #lowpass = 5000 server = 10.0.0.1 port = 8000 password = ******* mountPoint = listen name = Poo-Bah Radio description = Poo-Bah In-store Broadcast url = http://poobah.com/ genre = Hip-Hop / Various public = yes
Some time later we started to do live shows, The Tom Coston Show with Red Rosie, and we wanted to not only broadcast but to be able to record the show to put the shows up as podcasts. Darkice supported, in addition to connecting to Icecast, writing to disk.
I modified the configuration file to include this feature
[file-0] bitrateMode = cbr format = mp3 bitrate = 256 quality = 0.8 fileName = /tmp/poobah_radio_active.mp3
In addition to this a bash script that would move and rename the file based on a timestamp each time it was started and stopped. Initially we used a less precise timestamp, but because the radio could be stopped and started within the same minute or even within the same second we had the timestamp include nanoseconds so that overwriting a 3 hour recording would not be possible.
Bash script to start the radio and recording
#!/bin/bash killall -9 darkice TIMESTAMP=`date +%F-%a-%Hh%Mm%Ss%Nns` SESSIONSPATH=/home/poobah/Music/Radio_Archive mv /tmp/poobah_radio_active.mp3 $SESSIONSPATH/$TIMESTAMP.mp3
It seemed easy enough, however we discovered a problem with the setup after having a few shows lost because our internet connection was busy enough to cause a lag, and the buffer to skip. The skipping on the outgoing stream was also recorded to disk, so the podcast had the same interruptions as the live show. This was solved by increasing the configuration for the buffer for Darkice.
Addition to the Darkice configuration to increase the buffer
[general] duration = 0 # forever bufferSecs = 40 #seconds reconnect = yes
However there is still the possibility that the Net connection could die, and thus the recording would also fail. We needed a way to separate the processes so that one could fail without effecting the other.
To achieve the separation of the processes we started to use Jackd; it lets us connect several programs to one audio source, in addition to being able to direct the audio output on one program to another. So we setup jack and had Darkice to connect to it instead of the audio device directly, and we turned file streaming off. Then we had arecord connect to jack through an alsa workaround and piped arecord to lame to stream to an mp3 archive on the disk.
Bash script to start the radio with Jack
#!/bin/bash
killall -9 darkice
killall -9 arecord
TIMESTAMP=`date +%F-%a-%Hh%Mm%Ss%Nns`
SESSIONSPATH=/home/poobah/Music/Radio_Archive
jackd -d alsa -r 44100 &
sleep 8
arecord -D jackplug -c 2 -f S16_LE -r 44100 -t wav |
lame --little-endian -q 5 - $SESSIONSPATH/$TIMESTAMP.mp3 &
/usr/local/bin/darkice -v 10 -c /home/poobah/poobahradio.cfg
2>&1 >> /var/log/darkice.log &
This seemed to work very well, however it failed to write more than 183MB of a 128k mp3 file. We lost more recordings because of this. Arecord doesn’t support Jackd natively and we used an .asoundrc configuration to enable support.
.asoundrc file to support Jack in alsa interfaces
pcm.jackplug {
type plug
slave { pcm "jack" }
}
pcm.jack {
type jack
playback_ports {
0 alsa_pcm:playback_1
1 alsa_pcm:playback_2
}
capture_ports {
0 alsa_pcm:capture_1
1 alsa_pcm:capture_2
}
}
So the search was on again for another program. I found one called Rotter that supported Jackd directly. Now we have Jackd, Darkice, Rotter and Icecast running to record and broadcast live shows that can work with or without a live internet connection, that can be as simple as having an on and off switch.
Here is the bash script to start the radio using Rotter instead of arecord
#!/bin/bash
killall -9 darkice
killall -9 rotter
killall -9 jackd
TIMESTAMP=`date +%F-%a-%Hh%Mm%Ss%Nns`
jackd -d alsa -r 44100 &
sleep 8
rotter -a -f flac -L heirarchy -N $TIMESTAMP
-d 336 /home/poobah/Music/Radio_Archive/
2>&1 >> /var/log/rotter.log &
/usr/local/bin/darkice -v 10 -c /home/poobah/poobahradio.cfg
2>&1 >> /var/log/darkice.log &
And to stop the radio
#!/bin/bash killall -9 darkice killall -9 rotter killall -9 jackd
Configuration file for Darkice
[general] duration = 0 # forever bufferSecs = 40 # seconds reconnect = yes [input] device = jack_auto sampleRate = 44100 # Hz bitsPerSample = 16 # bits per sample channel = 2 # channels [icecast2-0] format = mp3 bitrateMode = cbr bitrate = 92 quality = 0.3 channel = 2 #lowpass = 5000 server = 10.0.0.1 port = 8000 password = ***** mountPoint = listen name = Poo-Bah Radio description = Poo-Bah In-store Broadcast url = http://poobah.com/ genre = Hip-Hop / Various public = yes
On the WebFaction server we have Icecast running on a dedicated IP, we built Icecast from source as a custom application.
The Icecast configuration
<icecast>
<limits>
<clients>30</clients>
<sources>1</sources>
<threadpool>5</threadpool>
<queue-size>102400</queue-size>
<client-timeout>30</client-timeout>
<header-timeout>15</header-timeout>
<source-timeout>10</source-timeout>
<burst-on-connect>1</burst-on-connect>
<burst-size>65536</burst-size>
</limits>
<authentication>
<source-password>****</source-password>
<relay-password>****</relay-password>
<admin-user>****</admin-user>
<admin-password>****</admin-password>
</authentication>
<directory>
<yp-url-timeout>15</yp-url-timeout>
<yp-url>http://dir.xiph.org/cgi-bin/yp-cgi</yp-url>
</directory>
<hostname>localhost</hostname>
<listen-socket>
<port>35898</port>
</listen-socket>
<fileserve>1</fileserve>
<paths>
<basedir><base_path>/share/icecast</basedir>
<logdir><base_path>/var/log/icecast</logdir>
<webroot><base_path>/share/icecast/web</webroot>
<adminroot><base_path>/share/icecast/admin</adminroot>
<alias source="/" dest="/status.xsl"/>
</paths>
<logging>
<accesslog>access.log</accesslog>
<errorlog>error.log</errorlog>
<loglevel>3</loglevel>
<logsize>10000</logsize>
</logging>
<security>
<chroot>0</chroot>
</security>
</icecast>
Scripts to start, stop, and check Icecast on the web server
#!/bin/sh cd /home/poobah/webapps/poobahradio/ bin/icecast -c etc/icecast.xml -b
#!/bin/sh
SERVICE='bin/icecast'
if ps aux | grep 'poobah' | grep -v grep | grep $SERVICE > /dev/null
then
pid=`ps -eo pid,args | grep $SERVICE | grep -v grep | cut -c1-6`
kill -9 $pid
else
echo "$SERVICE isn't running!"
fi
#!/bin/sh
SERVICE='bin/icecast'
if ps aux | grep 'poobah' | grep -v grep | grep $SERVICE > /dev/null
then
echo "$SERVICE is up and running!" > /dev/null
else
cd /home/poobah/webapps/poobahradio/
bin/icecast -c etc/icecast.xml -b
echo "$SERVICE was down and has been restarted
automatically. It would be good to check it at this time!"
fi
Adding the following line added to our crontab on the web server
0,10,20,30,40,50 * * * * /home/poobah/webapps/poobahradio/check_daemon.sh
Update:
- I’ve just tested Darkice to see if the file output continues to write without an internet connection on the other output, and it looks like it actually is still writing to disk. I’ve tried running the process both as root as a normal user, and POSIX realtime is possible with root and not as another user, so this may be the source of the skips. So the complexity of using Jack plus the other programs may not be necessary. There is still an on-going issue with the jack server not being stable, and may be also related? Please leave a comment if you you can shed more light on this.
