So, I had a use case where I wanted to listen to a local FM radio station that isn’t online and doesn’t have a great signal when I’m at work.
I’d seen and heard a bit about Software Defined Radio (SDR) – in fact I have a Pi running one already as an ADS-B feeder for ADS-B Exchange and Flight Aware. Anyways, I figured that I should be able to use a cheap RTL-SDR from ebay for about $20 with a pi. I thought it should be pretty well supported.
So, rtl-fm seemed to be pretty common when talked about on the web. Well, I got it to work without too much problem to prove that my hardware worked. One limitation, is that it only does mono. Better than nothing, but why sacrifice stereo. One nice feature though was that a forked version for Air Traffic Control recordings, uses the wideband feature of the hardware and allows the monitoring of several frequencies simultaneously! Like real-time scanning. It takes the whole bandwidth the SDR can receive, then by processing strips out the multiple narrowband frequencies. Intriguing, perhaps I could rebroadcast multiple FM stations one day???
My next attempet, was Airwaves-FM. I got this to compile, with a little help – but had other issues trying to run it. I felt like a squirrel and was quickly distracted.
Forward Progress using the dongle
A promising project – airspy-fmradion – stereo wideband fm for the RTL-SDR. So, the git project gives several dependencies. Initially I found several of these pacakged with apt on raspbian stretch. However, I soon found that several of these were out of date and required rebuilding. The packages I ended up using apt for were:
apt-get install tmux sox soxlib-dev libusb-dev libudev-dev libbz2-dev libasound2-dev libsoxr-dev ezstream icecast2 gcc cmake make binutils build-essential
With these packages installed I then started the lengthy process of building these packages
boost, libusb, rtl-sdr, airspy, airspyhf, airspy-radiofm (A couple of hints, you need to build the boost libraries because of the way they are used. I also needed to set the environment variable
CPATH=/usr/local/include to find the boost header files. I’m not sure I needed to, but for good measure I ran ldconfig several times 😀.
Once that is all built, you can test airspy-fmradion – Note I found that I had to blacklist the dvb drivers. Took me a while to find the exact way of doing that. The file had to be .conf file and located in
/etc/modprobe.d/ so mine is
/etc/modprobe.d/dvb_rtl.conf and contains:
blacklist dvb_usb_rtl28xxu blacklist dvb_usb_v2 blacklist dvb_core
If you have audio on your pi, you can try
airspy-fmradion -t rtlsdr -c freq=100000000,agc – I didn’t to start with so I added
-W test.wav, ran it for a few seconds then scp’d it to my windows machine. Incidentally, I added Airspy SDR# to my windows machine so I could visualize some good FM stations to test with.
Streaming the output
After more research, it definitely seemed that icecast2 was the way to go. The package in apt works great it turns out. I guess there are multiple ways to feed a stream to icecast, but the aptly named ezstream seemed to work well – again the package from apt does the job nicely. Lastly, I needed something to feed ezstream – again the popular choice seems to be lame – happily again the apt package works great. I found this page helped a lot. One caveat though – for icecast to start, you need to edit the file
/etc/default/icecast2 and set the last line to
ENABLE=true; I also changed my config file to not list my stream – it’s only for me! I basically used the example file for streaming an mp3. One thing of note though, the icecast2 page defaults a .m3u playlist extension (
http://10.192.168.150:8000/stream.m3u) . At the very least that didn’t work for me. If I use
http://10.192.168.150:8000/stream – it plays in the browser.
Automating the process
Having got this to work, I needed a way that it would start up as a normal service for running airspy, lame and ezstream. These days, rasbian is using systemd. So, I took this upstart example page and this systemd page and combined them so my
/etc/systemd/system/stream.service file calls a script that loops until netcat can make a connection to icecast on port 8000
Port forwarding / firewall
If you just want intranet access, then you probably don’t need this. But – if you want to access the stream from the internet, it will need to be visible. So, you will need to forward a port on your cable modem / router.
There’s a good chance you are running (or should be?) a firewall on your pi. If so, that will probably need configuring too for access to icecast’s port.