Radio: Preparing WAV files for cloud-based radio
The team at USC Radio Labs has been working to solve a pretty exciting problem: converting 60k+ audio files from WAV format to something more internet-ready. For context, in the 1990s, many radio stations started moving towards automating their music programming. The benefits were clear: no skips, no repeated songs, no "dead air," and for music directors, a way to plan and strategize their music curation.
If you remember, the 1990s was the decade of Microsoft Windows. Everyone was making Windows applications, and therefore, most of the high-end broadcast software was built on Windows using wav
as their default file format.
For the most part, wav
format is fantastic. It's like the perfect wrapper for storing music regardless of its encoding. For example, if you've ever worked with a zip
file, wav
is very similar to that. You can do much more with wav than just package a song.
The challenge? wav
isn't built for internet distribution. They are big files to send over the web. A 3-minute song can average 40Mb. The second problem is that WAV isn't designed to store metadata information. So there's no way no add song title, composer, genre, year, and all of those other goodies –unless you start getting unnecessarily creative [1].
Going back to my team, as we begin exploring the idea of building a "cloud-based radio station," we thought it would be essential to learn how to convert our existing catalog into a new system that better prepares us for the future.
The goal was to convert wav
to another uncompressed, lossless format that is still high-quality yet capable of handling ID3 data and open source.
The rest of this article will explain:
- How we converted
wav
file toflac
- How we automated the process of finding metadata using our source material.
- How we injected that metadata into
flac
. - How we created Mp4 renditions.
Hello FLAC
FLAC is a technology that offers most of our key benefits, including:
- Lossless audio compression.
- Slightly smaller file sizes.
- ID3 metadata is a first-class citizen.
- License-free
- Mac and PC friendly
- Supported by a robust open-source community
- An excellent suite of command-line tools
Step 1 - Creating a Process
From WAV to FLAC, a love story
One of my first tasks is figuring out converting data from WAV to FLAC. Thankfully, there are many options available, but I chose a tool that would allow me to create a scriptable, automation-friendly process.
As a starting point, I will use ffmpeg
to convert my WAV file to FLAC format.
The only problem is that beets don't do well with WAV files. Therefore, our first step is to use ffmpeg
to convert a WAV file to FLAC. Unfortunately, there is very little WAV support on beets, so we'll need to run this command on its own.
Once you have a FLAC file, you can run some fingerprinting.
Since I'm on a Mac, I installed the ffmpeg
command-line through the Homebrew package manager to help with the conversion.
You must first have Rake and Homebrew installed to use the script below.
Create a file titled Rakefile
and paste this code.
namespace :audio do
desc %Q{ Install ffmpeg encoder. }
task :install do
# https://gist.github.com/predakanga/2376835
sh %{ brew install ffmpeg boost taglib }
end
desc %Q{ Encode WAV to FLAC }
task :convert, [:input, :output] do |task, args|
input = args.input
output = args.output
sh %{ ffmpeg -i #{input} -c:a flac #{output} }
end
end
Download and install ffmpeg
.
rake ffmpeg:install
Convert a WAV file to FLAC.
rake ffmpeg:convert[/path/to/file.wav,/path/to/file.flac]
Here are a few other examples showing you how to convert files to different sample rates
Step 2 - Injecting ID3 data
Now that my WAV files are in FLAC format, I want to figure out a way to find the metadata and inject it into the file.
Considering that I have 60k files, the only plausible way to automate this is to use the fingerprinting technology you see on products like Shazam.
Ideally, I also want to scour the Internet somehow and find the album art for each song. Here's how we can do both using beets.
Getting Started
So here's the deal, Music Fingerprinting is a fantastic technology with incredible benefits, but it requires a little bit of configuration.
Since I work on radio, it makes sense for me to learn the intricacies of creating a Shazam-like tool, but the barrier might be a little too high for most people. Therefore, I've created a script that automatically installs the necessary software for you.
You can choose to install the necessary libraries yourself by visiting the docs
Add these new namespaces to your Rakefile
.
namespace :fingerprint do
desc %Q{ ›› Start Fingerprinting }
task :install => [:dependencies] do
puts "Great! We're ready to get started."
end
desc %Q{ ›› Install Fingerprinting Dependencies. }
task :dependencies do
# Install Chromaprint's tool fpcalc
Rake::Task["fpcalc:install"].invoke("~/Desktop/fpcalc.tar.gz")
# Install flac library
sh %{ brew install flac }
# Install pyacoustic so that we can interact with fpcalc from pythong
sh %{ pip install pyacoustid }
# Install beets
sh %{ pip install beets[chroma] }
end
end
namespace :fpcalc do
desc %Q{ ›› Download fpcalc. }
task :download do |task, args|
source = "https://github.com/acoustid/chromaprint/releases/download/v1.4.2/chromaprint-fpcalc-1.4.2-macos-x86_64.tar.gz"
dest = args.dest || "chromaprint.tar.gz"
# Remove any previous downloads
sh %{ rm -f #{dest} }
# Download it as a new filename
sh %{ curl -L #{source} -o #{dest} }
end
desc %Q{ ›› Install fpcalc. rake fpcalc:install[~/Desktop/tmp] }
task :install, [:dest] => [:download] do |task, args|
dest = args.dest || "chromaprint.tar.gz"
# Unpack store the executable in /usr/local/bin
# -x --extract = extract files from an archive
# -v, --verbose = verbosely list files processed
# -z, --gzip = gzipped files eg. for tar.gz packages
# -f, --file ARCHIVE = use archive file or device ARCHIVE
# -C, change directory
sh %{ tar -xzvf #{dest} -C #{Dir.home}/Desktop --strip-components=1 }
# Move fpcalc to /usr/loca/bin
sh %{ mv fpcalc /usr/local/bin/fpcalc }
# Double check your work.
sh %{ which fpcalc }
# Remove the desktop download
sh %{ rm -f #{dest} }
end
end
Now all you have to do is open up Terminal
and run this command.
The command will install flac
, pyacoustid
, and fpcalc
.
rake fingerprint:install
fpcalc
is an open-source fingerprinting technology is available within a command-line package called fpcalc. If you're on a mac, download fpcalc library and copy the executable file to your/usr/local/bin
.- We need
pyacoustid
package to interact with the Chromaprint library from Python. beets
is a command-line tool for Python that can automatically catalog your collection, transcode audio files, check for duplicates and help you fingerprint songs through chroma print. We are also includingchroma
plugin.
Configuring Beets
Now that we've installed all the necessary packages, we need to configure the beets
application.
You will first need to configure beets so that you can install plugins.
Create a new config.yaml
.
beet config -e
Here is an example of a config file. The file is located in ~/.config/beets/config.yaml
.
# Copy cleaned-up music into that empty folder using beets’
directory: ~/Desktop/my_beets_app/my_music_folder
# Location of Beets music database
library: ~/Desktop/musiclib.blb
import:
# If no data is available, move on
quiet_fallback: skip
# Do not copy songs to another directory
copy: no
# Inject ID3 data into the song if found.
write: yes
# Use the Chroma plugin
plugins: chroma
chroma:
# When you type beets import, auto fingerprinting will begin.
auto: yes
# You can do multiple processes at once. This is somewhat CPU intensive.
threaded: yes
# Show the command line
verbose: yes
Download a WAV file
For this example, let's use a Creative Commons WAV file from Nine Inch Nails titled "999,999".
Music Fingerprinting - Finding a Song's info based on its "sound."
Now that our development environment is ready. Let's try and fingerprint a WAV file that contains no metadata.
Acoustic fingerprinting is a technique for identifying songs from the way they –sound– instead of from their existing metadata.
Step - Import Music
Singletrack
Import a single track and include a log file.
beet import -A -C -s -l my_log_file.txt my_music_folder/album/02.flac
-A
do not auto-tag anything; import the files.-C
do not copy files to a new directory.-s
is the singleton method we should use when we're trying to access a single file.
Entire Albums
Import a single track and include a log file.
beet import -A -C -l my_log_file.txt my_music_folder/album/02.flac
Step - Beet Queries
List out the music you've imported.
beet list
Resources
-
Acoustic ID is a web service that serves as a companion to chromaprint.
-
FFMpeg compilation guide.