|
|
| A simple WinTV radio server | You: 38.107.179.220 | Friday May 25, 2012 10:39PM PDT | boston: Saturday May 26, 2012 1:39AM EST/EDT |
|---|
A while back, I purchased a WinTV video/FM tuner card for my home workstation. I love it, but I could barely hear it from the other rooms in the house. The old pc that acts as a router between the home ethernet and the dialup network, also has a wirelss card (for the laptop and the iPaq ). I decided to make the FM radio available over the network.
Rather than reinvent the wheel, and spend a lot of time programming,
I decided to make use of existing tools. Fortunately for me (depending
on how you look at it), I wasn't aware at the time that the radio's
output was sent to
Luckily, I finally happened across the kernel doc's for the btaudio
module, and noticed that it referred to The following instructions begin with the basic configuration, and progress to an explanation of all the pieces required to install the setup as a full-blown server on a system.
Other systems like sun or sgi handle sound differently, so I cannot comment on them. I will update this information with any feedback received.
As was mentioned, only three simple tools are needed to make this work. The first,
The second, netcat, has begun to accompany many distributions. If not installed
by default, it can usually be obtained using the package management tools
(
The third tool that you'll need is The following instructions assume that the tools are installed in their standard locations (whatever those are). The basic configuration does not require root access as long as one has read access to the audio device. If you can listen to the card, you should be allright. My workstation with the radio card is named ibm on the local net. That is the name that will be used in all the examples.
Assumptions are that the tuner card's output appears as
The easiest way to get the output of the tuner card to another machine is to simply pipe it there through a network socket. First, set up a process to listen on a port and feed it the output of the card:
This says: "pipe the output of the soundcard into netcat which is listening for network connections on tcp port 55555." Now, on the receiving end (the other computer), connect to netcat using this command:
Voila! You should hear the output of the radio on the other computer. What does it all mean? Use netcat to connect to the host named ibm on tcp port 55555, then pipe what you receive into the program named play and tell play the format of the incoming sound data. "Hold on! You never mentioned 'play'!", you say. You're right. It's an alias to the sox program that gets installed when you install the sox package. You can do the same thing with:
So, what are all those parameters, and what do they mean? They tell sox about the format of the sound coming from the WinTV card:
Though this method works, and it's great for testing and for one-offs, there are some drawbacks. For instance, every time you want to connect, you first have to launch the server. That means typing the entire command line for a ssh connection. The server also has the annoying habit of dying after every single connection. (Well, that's what we told it to do, after all.) It also won't work for multiple connections because the second server will complain that the port's already in use and die. We'll address the second issue in a minute, but first, let's make it easier to launch these programs. I don't know about you, but I'd need a cheat sheet to remember all those command line switches a couple of weeks down the road...
Ok, for the next step, let's automate all this just a little and save our memory for more important tasks. We can wrap the server in a script that contains a loop so that it will launch a new listener whenever a client disconnects with a shell script like so:
Save this somewhere in your path with a meaningful name like
$HOME/bin/radiod. Change the permissions to make it executible
( Something similar for the client would look like:
Same thing; put it in your path and make it executible so that you can launch
the client with something simple like
There are a couple of niceties added to this script. The line
"But, I can just background it from my current session.", you say. Sure you can, but what happens when you log out of that window? This method keeps the client running even if you log out of that session.
The
If you've tried the methods above, you'll soon notice that though the music has pretty good fidelity, there's quite a bit of network traffic, and the cpu of the receiving machine keeps pretty busy just to play our music. My gkrellm display hovered at 94% to 99% cpu utilization, and the sound dropped out with almost every disk access. Since the workstation with the tuner card has a 600mhz processor, I decided to let it work a little harder to reduce the amount of data getting sent to the network. That way, the pc acting as a router doesn't work as hard, network utilization is reduced (more important over wireless where the connection is more like 2mbs than the theorectical 11mbs), and the poor little laptop with a 133mhz cpu doesn't turn the battery into a lap warmer (burner). To accomplish this, sox is pressed into service on the server side before sending the signal to the netcat daemon. By using sox to convert the sound from stereo to mono, we cut the data rate in half. By dropping the data rate from 32khz to 8khz, we cut it by another fourth. Admittedly, 8khz is more suited for voice than music, but the speakers on my laptop aren't exactly studio monitor quality, so I opted for the additional reduction over signal fidelity. All references to 8000 can be changed to 16000 in the following to improve the sound quality with an associated increase in network traffic. Here is what the server looks like with these changes:
The client would now be:
Ok, this reduces traffic and client overhead, but can't we make this act like a real internet server? Sure, piece of cake. W'ell use the internet super server, inetd (nowadays, xinetd seems to be a popular replacement). This will require a change to the server script to remove the loop, and an addition to the /etc/inetd.conf file. For xinetd, we'll create a file to put into the /etc/xinetd.d directory. But first... just to be thorough... We'll add our server to the list of internet servers that is kept in the file /etc/services. This is a a necessity for inetd, not for xinetd. Do this by adding the following line to the end of the file (must be root): radio 55555/tcp # my radio server If your system uses inetd, add this line to the /etc/inetd.conf file: radio stream tcp nowait root /usr/sbin/tcpd /PATH_SPEC/radiod Two things to notice - this assumes that tcp wrappers are installed on your machine. Hopefully, they are. If so, don't forget to update /etc/hosts.allow to allow connections to the server. PATH_SPEC must be changed to match the full path to the program. This is the configuration file that I use for xinetd:
Note that you can limit the hosts who can connect to this server by adjusting the only_from directive. Also notice that the full path specification is required for the server program. Whether using inetd or xinetd, some consideration might be given to the fact that I run these as root. I see no problem with it since there is no input to the daemon. There are those, however, who would argue that it is dangerous to run any server as root. I tend to be rather paranoid, but perhaps I'm not sufficiently paranoid. As with many of these things, Your Mileage May Vary... Don't forget to launch/relaunch the inetd server:
Since we're now launching out of the super server, we no longer want the loop in the server script. If we incorporate the throttling via sox, the server script now looks like:
All these features now make the server run automatically at boot, and the
client is easy to start and stop via Note that this program sports a couple of extra features. I use the radio command line program to control the tuner. Since I have my internal network configured to allow ssh connections using RSA/DSA authentication without passwords, I added the ability to tune the radio card across the network. This works by assigning the list of stations and their frequencies to the drop-down menu, and including them in the command sent via ssh to the machine with the tuner card. This saves an extra ssh connection just to change the station. It also allows me to control the speaker output on the remote box. I don't usually need the sound output in the kitchen if I'm sitting on the front porch with my laptop. The command invoked looks like:
This sends the command via ssh to the host with the tuner (ibm), and tells the radio program to change the station to 89.7mhz, mute the speaker, and quit. The program can be used without the remote tuner features. The On, Off, and Exit buttons toggle the radio reception and quit the program.
This web page, all of these programs and source code are copyright by
Generally, these may be freely distributed and used as long as all headers are are retained, and all modifications are clearly indicated. The author makes no promise of technical support. However, bug reports, suggestions, questions, and comments are welcome. All will be answered via electronic mail as time allows.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DAVE CAPELLA OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
...dave
|
|
Top of Page | FEEDBACK Comments, Corrections & Questions welcome |
|