The Project Stack
- ICOM IC-2SAT
- ASUS EEE PC 701
- Custom AUX cable
- xubuntu 12.04
I’ve had an ICOM portable radio sitting around for several years. It’s a hand-me-down that I received from my dad after he upgraded his portable to a Kenwood TH-K2AT (I think.)
For the longest time, I’ve wanted to make use of the radio, but never had a project in mind or the time to do it. Then I quit my job and got bored.
I started browsing the volunteering section on Craigslist, and found a listing from a gentleman who wanted someone to pick up and stream the Spokane NOAA weather radio.
The goal of the project was simple. Tune a radio to the frequency of NOAA’s WXL86 transmitter. Connect an audio cable from the radio to a computer. Use the computer to capture audio and stream it to the internet.
I gathered the portable, and found it’s wall-wart and desktop charger after rummaging through several bins. For this project, I needed a dedicated computer to handle audio capture and streaming. Since it hadn’t seen any action since I stopped mining Bitcoin last year, I pulled out my ASUS EEE PC 701. I love this laptop. Using it brings back memories of it’s pre-installed Xandros operating system. With it, I got into a bunch of tech. Virtual Private Networks, Virtual Network Computing (remote desktop), and wardriving to name a few. Before everyone knew about remote desktop, I had some fun times pranking roomates.
Me: “Hey play this game on my laptop”
Roomate plays game
Roomate: “AHH WTF MY CURSOR IS GOING CRAZY”
Yep it also had a good run as a portable Sega Genesis emulator. I love me some Sonic, and Avengers!
ANYWAY, this post is not about the laptop. There was one thing I had to take into account when using it, though. There is no LINE-IN audio connection! Most laptops I’ve seen don’t have this, which is fine, but I had to get audio from a line-level device (the radio) to the laptop, which isn’t designed to receive a line-level audio source. If that doesn’t make any sense, I’ll explain it a little more.
Line-level audio is what your average headphones expect. It’s what the average computer/phone outputs on the headphone/speaker jack, commonly colored lime green. In some of my past internet radio endeavors, I’ve connected a computer’s line-out to a microphone jack using an AUX cable. I didn’t know any better at the time, but doing that fried the circuit on the microphone input. From then on, using a microphone had extremely low and muffled audio, and nobody on Teamspeak could understand me!
Not wanting to repeat that history, I did some research. I had a microphone jack to work with, but I wanted to make sure I didn’t fry the laptop’s internal soundcard.
After a quick Ecosia search, I had a schematic to a simple circuit designed to do just what I needed. The circuit used two resistors to lower the voltage of the audio signal from the radio. I tested the circuit on a breadboard before busting out the soldering iron and making it permanent with a piece of Adafruit perma-proto.
Now that the radio was connected to the laptop, I needed to get the laptop streaming to the internet. For this task, I went with Liquidsoap. I gotta take a moment to BIG-UP this software. It’s some really quality open-source software. professional grade, easy to use, fast and efficient. Liquidsoap is a scripting language streaming audio (and more!) Using the documentation, I came up with a simple script to create logs, capture the (pulseaudio) microphone input, transcode the audio to mp3, and stream to wunderground.
Wow, just wow. Since I’m using linux, I was expecting I would need to use five different programs to accomplish all this. In fact, my first attempt at streaming to wunderground, I did just that. In that attempt, I used this radio reference tutorial. The tutorial showed a method of capturing audio with sox, piping to lame for transcoding, then piping to ezstream for streaming. There was nothing wrong with that process, and was a prime example of the Linux way of doing things. (Programs should do one thing really well, and work well with others.)
The reason I abandoned the ezstream method was two fold. Ezstream is old and crashed a lot, and three processes were difficult to start/stop/monitor with Upstart.
I’ll get to Upstart in a moment, but for now, back to Liquidsoap! I created this script, which handled the streaming process:
<strong># mic input</strong>
mic = input.pulseaudio(id = "ICOM via Mic")
audio = %mp3.cbr(
stereo = false,
samplerate = 22050,
bitrate = 16
<strong># stream to wunderground</strong>
protocol = "http",
host = "audiostream.wunderground.com",
port = 8000,
password = "hackme",
mount = "KE7NWL/Spokane.mp3",
name = "Spokane, WA Weather Radio",
description = "NOAA Station WXL86 162.400",
genre = "Weather",
url = "http://www.wunderground.com",
public = true,
icy_metadata = "false",
Bonito! Next, I had to make a way to keep Liquidsoap running at all times. I opted to do things the Ubuntu way™ and use Upstart. Upstart is a program which handles starting and stopping system services. When Ubuntu starts, upstart is what handles starting things like network interfaces, mounting disks, starting bluetooth/printer support, etc. Using Upstart, it’s trivial to add more daemons, or services to your computer.
Here’s the Upstart config I created, /etc/init/liquidsoap.conf
# liquidsoap upstart script
description "start and stop liquidsoap source client"
author "Chris Grimmett <email@example.com>"
# restart if it dies
respawn limit 3 10
# start when filesystems and network device are up,
# stop when powering down or rebooting
start on runlevel 
stop on runlevel [!2345]
sudo -u $RUNUSER pactl set-source-volume 1 12% # set mic level
exec sudo -u $RUNUSER $DAEMON $CONFIG
This config file defines a user to run liquidsoap as, as well as setting a path to the liquidsoap executable, and my liquidsoap script. It tells Upstart to respawn the liquidsoap process in case it dies, and in case the liquidsoap process starts and stops too quickly after being respawned, halts the process so the user can intervene. The runlevels are set to 2-5 which means that Upstart should start the liquidsoap process whenever the desktop is up, and stop whenever the desktop is closing.
The last thing in the config file, the script section, tells Upstart to run as user chris, and adjust the system’s microphone input level to 12% using the pactl utility. I did because I saw an instance where ubuntu would change the audio to 50% after a reboot, which resulted in the audio level being too high and clipping. Finally, the exec line shows Upstart the main process to run, which is sudo running the liquidsoap daemon as user chris, with the path to my liquidsoap script as it’s parameter.
At that point, I was able to run $ sudo service liquidsoap start which started streaming to wunderground. I was able to see my stream showing up on the wunderground info page. (link to stream.) For some reason, my stream isn’t showing up on the directory page. I contacted wunderground about that, but I haven’t heard back from them yet.
Regardless, my stream was online. Great success!
Here’s the github repo I made which has the aforementioned scripts and config files, as well as a setup script. Use them for reference only, and be sure to review them in case you decide to do a similar project. (I offer no warranty!)
I replied to the Craigslist post and got a thank you from the gentleman who requested the service. Turns out he’s part of a community radio station in Chewelah! At that point I was really happy I could help.
I had a lot of fun with this project. I learned about the quality software Liquidsoap, brushed up on Upstart configuration, got to solder again, play with a radio I hadn’t touched in years, and help out the community. This is my favorite kind of work.
Feb 2017 Update
Weather Underground has shut down their weather radio service. Now I am self-hosting a Icecast server, and liquidsoap now streams to it http://wxradio.grimtech.net:8000/KE7NWL/Spokane.mp3.m3u. The community of weather enthusiasts who were previously streaming to Weather Underground have come up with a website to replace Weather Underground’s radio. http://noaaweatherradio.org/