It has become fairly common to attach an FM tuner or other device to a computer soundcard and use that then as the platform for recording FM radio. For my part, I do this to allow both time- and location-shifting of my radio listening. At the same time, devices such as the Squeezebox from Slim Devices or uPNP clients such as the Philips Streamium provide the infrastructure for moving digital audio (and video) around the home.

The problem arises, therefore, as to how to stream audio from a soundcard to such devices, thus making it possible to listen to the same audio in the living room, kitchen, bedroom, or wherever.

One approach is to install software packages such as Icecast and DarkIce. While there's nothing wrong with this approach, these packages were designed for more demanding streaming applications, and the configuration can seem a little daunting to some potential users.

This page describes a very simple approach to soundcard streaming for Unix-like operating systems including in particular FreeBSD, other BSDs and Linux. What is described here is so simple it barely warrants its own page. However, I have not seen it described elsewhere.

Although the focus here is on streaming audio, I have used the same approach for streaming live video from a video card — this requires only a couple of very small changes to the approach described below.

Software Requirements

The third-party software packages that are required are:

Many Linux systems will have perl, lame and possibly sox installed by default. I use esound, but it should be possible to use other sound systems such as Alsa (although I myself know nothing about Alsa).

The little piece of magic glue is the tcpserver program that is part of Dan Bernstein's ucspi-tcp suite. This listens on a TCP port and, when a connection is established, invokes an arbitrary command. It splices together the standard input and output of the command with the output and input, respectively, of the socket. This is a very useful little utility.

All of the software mentioned above is part of the FreeBSD ports collection, and likely available as packages for other operating systems too.

A Shell Script

I use a shell script called soundcard.sh. If you read it over, it's really very simple. It reads an HTTP request and generates some headers — a fake HTTP server, if you like. It then calls esdrec, sox and lame to generate the mp3 audio itself:

soxraw="-t raw -s -w -r 44100 -c 2"

raw () {
   case "€url" in
      * )
         esdrec
         #
         #  or possibly:
         #
         #  sox -t ossdsp /dev/dsp €soxraw -
         #
         ;;
   esac
}

raw                        |
   sox €soxraw - -t wav -  |
   €post

This part of the script should be changed to meet your own needs. Just drop any code in here that generates mp3 on standard output.

Invocation

The final step is to arrange to call this script over the network, and capture its output. This is where tcpserver comes in.

Specifically, the server is started with:

tcpserver -U -c 10 0 8080 /bin/sh <...path-to...>/soundcard.sh

This starts a process listening on port 8080, and invokes the soundcard streamer whenever a client connects. It can be tested with something like:

xmms http://localhost:8080/radio.mp3

For the most part, the script itself doesn't care about the filename part of the URL. As given, the script generates mp3 for any filename not starting /wav — for which it generates wav output (which I use for recording).

To listen to the stream on a networked device such as a Squeezebox, simply create an appropriate playlist. In my case, this is:

#CURTRACK 0
#EXTM3U
#EXTINF:-1,Cable-UFM Radio
http://192.168.3.2:8080/radio.mp3

in a file called Cable-UFM-Radio.m3u.

Reboot and Startup

An easy way to arrange that this is called after every reboot is to add the line:

@reboot tcpserver -U -c 10 0 8080 /bin/sh <...path-to...>/soundcard.sh

to your crontab file. If the "@reboot" shortcut isn't supported on your system, then I'm afraid you'll have to write an initialisation script.

And Video Too

I have used the same approach for streaming video from a video card to a Philips Streamium uPNP client. The only changes are to the HTTP content type (from audio/mpeg to video/mpeg-2), and the data-generating commands at the bottom of the file. In my case, with a Hauppauge PVR-350 on FreeBSD, this is simply:

cat /dev/cxm0

End Note

For issues or questions regarding this page, I can be reached at this email address.

This page was generated with AsciiDoc.
This server runs publicfile and FreeBSD.