As many of you know MusicDNS is an acoustic fingerprinting service and a software development kit provided by MusicIP. The fingerprinting client library that looks up and identifies audio files based on existing fingerprints is called libofa. MusicBrainz has a great audio tagger called Picard which can tag audio files by querying this MusicDNS service.
Hence I decided to write my own tool for generating acoustic fingerprints and for querying MusicDNS service. I’ve chosen to use libsndfile to do the decoding as libofa expects raw audio data. libsndfile is a C library for reading and writing files containing sampled sound through one standard library interface. It’s pretty easy to use and its API hides most of the low-level details from the programmer.
Usage is simple:
alip@harikalardiyari> afprint -h afprint-0.1.0-7b17577 audio fingerprinting tool Usage: afprint [-hVv0] <infile> Options: -h, --help Display usage and exit -V, --version Display version and exit -v, --verbose Be verbose -0, --print0 Delimit path and fingerprint by null character instead of space If <infile> is '-' afprint reads from standard input. alip@harikalardiyari> afprint -v sample.ogg [dump_print.294] Format: OGG (OGG Container format) [dump_print.295] Frames: 2188368 [dump_print.296] Channels: 1 [dump_print.297] Samplerate: 44100Hz [dump_print.298] Duration: 49735ms [dump_print.302] essential frames: 5953500 > frames: 2188368, adjusting sample.ogg 49735 ARaJDAgL...
Reading from standard input is tricky because pipes aren’t seekable thus it’s
not possible to calculate the duration of the audio file. For this reason, when
the audio data is fed via standard input, when
afprint saves this data into a temporary file
and reads from it. This makes it possible to calculate acoustic fingerprints of
Mp3 files, which
alip@harikalardiyari> mpg123 -q --au - 01_san_francisco.mp3|afprint -v - [wav.c:388] warning: Cannot rewind AU file. File-format isn't fully conform now. [wav.c:388] warning: Cannot rewind AU file. File-format isn't fully conform now. [dump_print.294] Format: AU (Sun/NeXT) [dump_print.295] Frames: 8000111 [dump_print.296] Channels: 2 [dump_print.297] Samplerate: 44100Hz [dump_print.298] Duration: 181820ms /dev/stdin.au 181820 AQMZN...
--au option passed to mpg123 as
I’ve written a simple Perl script to do the job. The script, which has the name puidlookup, reads audio fingerprints from standard input and queries the MusicDNS server. Optionally it can query MusicBrainz as well to receive the tags.
Here are the requirements:
alip@harikalardiyari> puidlookup -h Usage: puidlookup [-hVv0] -h, --help Display usage and exit -V, --version Display version and exit -v, --verbose Be verbose -0, --null Expect input is null delimited -m, --musicbrainz Look up PUIDs from MusicBrainz (requires WebService-MusicBrainz) -l, --limit Limit results to the given number puidlookup reads filename, duration and audio fingerprint from standard input
--null option responds to afprint’s
--print0 option. These options are useful if filenames have spaces or other
weird characters in it.
By default it only queries MusicDNS:
alip@harikalardiyari> afprint 04sheep.ogg | puidlookup ARTIST='Pink Floyd' TITLE='Sheep' PUID=930806c1-e1e0-588a-b7de-2dacb1b8b11e
--musicbrainz option can be used to query
alip@harikalardiyari> afprint 04sheep.ogg | puidlookup --musicbrainz PUID=930806c1-e1e0-588a-b7de-2dacb1b8b11e TRACKID=431a85dd-e22b-4626-91c9-c0abb8058d3f ARTISTID=83d91898-7763-47d7-b03b-b92132375c47 ARTIST='Pink Floyd' TITLE='Sheep' TRACK=4 ALBUM='Animals'
The output is quoted so it’s safe to pass to
eval, making it easy to integrate
with shell scripts.
Last step is writing a tagger script to tag audio files. I’ve written a shell script
called ofatag which
uses envtag. It recognizes
Mp3 files using the
file command and
mpg123, other formats are directly fed to
Now, to tag your files using MusicBrainz web services just do
ofatag /path/to/music/*.mp3 /path/to/music/*.ogg
I haven’t released a version yet because it’s all pretty new and needs testing. So please test it and report back! Any comments, thoughts, patches are appreciated.