A free-software, open-hardware, old-timey music player
Years ago, I had this idea for a gimmicky MP3 player. It wouldn’t have a screen
or any buttons; instead, it would play music and podcasts on a pre-defined
schedule. I’d build it into an antique radio so that using it might feel a
little like listening to an authentic radio station.
The idea sat in the back of my mind for many years. The challenge was a bit
outside my comfort zone, so I generally worked on more familiar
the year 2020 arrived. The more fortunate among us found ourselves with a bunch
of unexpected free time. I spent mine building the Magic Radio.
The user interface is intentionally minimal: you turn on the radio and tune to
87.5 FM. You hear whatever’s scheduled for that moment.
The playback schedule (along with all the audio files) is stored on a USB
storage device that’s plugged in to a panel on the back. End users can yank
that out, plug it in to a laptop, and reprogram the “station” with their own
audio files and schedule. They can also configure the broadcasting frequency to
accommodate the authentic stations in their area.
The configuration is a YAML-formatted text file. The
system provides instructions on how to edit the configuration by saving
documentation (another text file, this one with plain English prose) to the
storage device whenever it’s plugged in. The system also writes a log file on
there so users can review a journal of its behavior and learn about any
run-time errors it encountered.
My goal was to empower a non-programmer to operate the radio. While this
solution requires a fair amount of technical fluency, I’m reasonably satisfied
with the result, given the constraints.1
Why would anyone enjoy this?
An honest pitch for this device might go, “It’s like an MP3 player, but worse!”
It’s not for everyone. And honestly, even if you dig the concept, it may not be
that interesting to own. This is the most subtle quality that it shares with
traditional radio: a lot of the “magic” comes from the value of curation.
There’s not much room for serendipity in a device that you’ve constructed and
programmed to behave according to your specifications.
The Magic Radio works best as a gift. If you know someone who would appreciate
the aesthetic, then it makes for an excellent canvas. You can really layer in a
lot of thoughtful content, and your curation will be more meaningful than the
For instance: I gave this to a neighbor who used to love Boston’s
alternative rock station, WFNX. For a few hours every Saturday, it plays 90’s
rock and intersperses old WFNX station identifiers.
Like any good personal project, building this device taught me new things and
reinforced other stuff I only thought I knew.
Don’t optimize early. “This thing has a simple job, so it should be built
with simple hardware.” At least, that’s how I was thinking when I started. I
wanted to use a prototyping board, but not to save money or power; I set that
goal just on principle. Red flag, there. I wasted a lot of time trying to
decide which of the many, many such boards would be suitable. Eventually, I had
to admit that I lacked the experience to make the right call, so I bought a
general-purpose computer–the Raspberry Pi.
Even though I told myself that I’d eventually replace it with a leaner
component, it quickly became clear that this was a good move. The availability
of a high-level scripting language (i.e. Python) let
me experiment with new ideas very quickly, and access to the entire ecosystem
of GNU/Linux utilities (e.g. systemd) saved me from
writing my own hacky solutions to well-understood problems.
And when I did indulge my inclination toward optimization, I sometimes
regretted it. I didn’t want the Raspberry Pi floating around inside the radio,
risking short circuits and other tomfoolery; I needed some kind of enclosure. I
bought this really slick case thinking
it would solve my problem. Unfortunately, it turned out that the other
components (the FM transmitter and the hardware clock) wouldn’t fit inside. The
package it came in, on the other hand…
$15 is a hefty price tag for a cardboard box, but I’ve made worse purchases.
Prototypes can be inspiring. After years of thinking about this, I assumed
I had a pretty good handle on what I was going to build. It wasn’t until I
started actively working on it–buying components, writing code, and testing
subsystems–that I started to get brand new ideas.
For instance, I originally planned to use the radio as a fancy enclosure,
gutting it and installing a new set of speakers wired directly to the computer
inside. It wasn’t until after I’d purchased the radio that I realized how
integrating an FM transmitter would be worlds better. That provides a much
more authentic user experience, from the physical interaction of tuning to the
degraded audio quality (because people need to hear snaps and pops and that
shit). It also preserves the
device’s ability to play local radio stations. And it also means users can tune
to the “magic” station using any other radio they have in range.
Later on, when I heard the end of a day’s programming schedule, I recognized
how abrupt that can feel. From the early days of terrestrial radio,
broadcasters prepared listeners for that lonely silence with “station sign off”
messages. I listened to a handful from the 1950’s (e.g. these beauties from
Cleveland) and recorded one of my
Adafruit is amazing. Adafruit provided all of the
hardware for this project. It’s a 100% woman-owned manufacturing company, a
Minority and Woman-owned Business Enterprise (M/WBE), a
Women’s Business Enterprise (WBE), and
amazingly for an electronics manufacturer in this day and age, it’s based in
the US. If that was all there was to say about the company, I would be a huge
fan. But as you’d expect from a pedigree like that, the company’s products and
services are phenomenal.
Adafruit provides approachable and in-depth documentation for everything it
produces. They offer tutorials written to nurture interest in technology and
empower newcomers, especially those from groups who are historically
under-represented in the tech industry. By giving them your business, you can’t
help but feel like you’re contributing (however minimally) to a good cause. And
since I don’t build many hardware projects, that content gave me the confidence
I needed to finally give this a shot.
Goodwill is an American nonprofit 501(c)(3) organization that provides job
training, employment placement services, and other community-based programs
for people who have barriers preventing them from otherwise obtaining a job.
Additionally, Goodwill Industries may hire veterans and individuals who lack
education or job experience or face employment challenges. Goodwill is funded
by a massive network of retail thrift stores which operate as nonprofits as
Those are all great reasons to support your local store, if you’re lucky enough
to live near one. Unfortunately, as a thrift store, the inventory is pretty
hit-or-miss. While considering other retailers for a vintage radio, I was
psyched to discover that Goodwill operates an online auction site from the
inventory of its stores around the US. I had my pick of affordable pre-owned
radios, with new choices popping up almost daily. That site is my new go-to for
basic household equipment.
Functional testing is critical for physical projects. Most of my personal
projects are based entirely in software. I unit tested the crap out of my code,
naturally, but the real world is a messy place. Building the Magic Radio helped
me appreciate how a physical deployment with actual data is full of unknown
For instance, the Raspberry Pi lacks an internal clock, but I only discovered
this after running a week-long trial. One day, I happened to be futzing with my
home’s fuze box. I temporarily cut power to a circuit which included the device
so I could install a light fixture nearby. Later that day, right around the
time that The
was due to air, the radio was silent. It turned out that the computer’s clock
was half an hour late thanks to the time it spent powered down. This didn’t
occur to me throughout all of development because the device constantly
synchronized with network time while it was connected to my laptop. The
Raspberry Pi and Adafruit came through again, enabling me to buy a component
and plug it in, almost as intuitively as playing with Legos. It would have been
much more of a hassle to diagnose and fix this after giving the radio as a
Or there was the time the radio went silent after playing an episode of Our
Miss Brooks. It was supposed to
play some old
advertisements, though! It
turned out that about 1% of the audio files had faulty metadata. My code
assumed the metadata was infallible, and as a result, the system would refuse
to queue new files even though nothing was actually playing; it was waiting for
the show to end. The fix was to measure the true duration of audio files by
decoding them (an expensive operation, but one that could be optimized through
aggressive caching). I never would have caught this if I hadn’t tried running
the system for a while (and even then, it’s pretty fortunate that I stumbled on
one of the few outliers).
Nostalgia is powerful stuff. This project is pretty sentimental. Maybe that
goes without saying, but I was still surprised at the emotional effect it had
on me–especially considering the years I’d spent thinking about it. Old time
radio, though occasionally marred by sexist or racist themes, is otherwise more
charming than I first realized. Music from my childhood, punctuated by echos of
a long-lost radio station, was even more powerful. It’s given me a better
appreciation of how friction can enhance an interaction. Playing a vinyl record
takes more attention and effort than tapping on an MP3 file, and that makes you
a little more invested. I think the same can be said for the sounds coming out
of this radio: if you don’t pay attention, then you’re out of luck. Knowing
that seems to matter on some subconscious level.
“Wishing you all a good night and a pleasant good morning”
The Magic Radio was tons of fun to build and especially satisfying given how
long it’s sat in the back of my mind. It happens to be the third pet project
I’ve completed using the time I would otherwise have spent in public and
interacting with people (first was a silly cooking
next came a bizarre software legal
I’m grateful for the health and financial security I’ve needed to do this, but
I’ll be glad when spare time is a little harder to come by again.
If you’d like to build something similar for yourself, then check out the
source code (it includes some tips
for getting started), and don’t hesitate to contact me with questions!
Introducing a text-to-speech component would allow the system to
enunciate its state to the user, and immediate audio feedback is more
useful than indirect text-based feedback. The main difficulty from a
design standpoint comes from the variability of the broadcast frequency.
If the system couldn’t parse the configuration, it would be hard to
choose an FM frequency on which to transmit the “error” speech. The user
would have to search the entire broadcast range to find the right
frequency and learn what was going wrong. ↩︎