ONLamp.com    
 Published on ONLamp.com (http://www.onlamp.com/)
 See this if you're having trouble printing code examples


Big Scary Daemons

Ripping MP3s

09/13/2001

I never got into the MP3 thing. The wholesale swapping of music online just makes fair use look bad. Plus, my home computer is comfortably situated in the nexus of several speakers attached to a high-quality home stereo. Why would I trade several hundred CDs and high-fidelity recordings for tinny computer speakers? However, as my work schedule shifted, I found myself having a greater need for lugging CDs to and from work. This seemed to be a decent application for MP3s.

Ripping CDs to MP3 is a fairly straightforward process that is ripe for automation. You need the artist, title, and song list from each CD. This information is freely available online through a number of online music databases. CDDB is the best-known example. Armed with this information, you copy the audio track to your hard drive using a "ripper." FreeBSD includes several different rippers, and the core OS actually has the ability to rip audio tracks. You then "encode" the ripped file to MP3. Finally, you label the MP3. There are several other trivial functions that can be added to this process to make life later a little simpler, such as writing .m3u index files, but these are the basics.

My goals were simple: to drop a disc into the laptop's CD tray, type a command, and walk away until the rip finished. It can't be that hard; people barely capable of booting their computers can do it. It certainly wouldn't be worth a column.

Thus began a week-long saga of trying to rip CDs on FreeBSD. My eventual success shows some of the pitfalls of free software, and how to avoid or solve them.

A quick search of the FreeBSD ports tree led me to /usr/ports/audio/ripit, which is a basic Perl script that automates the ripping, conversion, and labeling process. "This looks perfect," I thought, and installed the port. It installed a few dependency ports, and I was ready to go.

# ripit.pl
Getting CDDB info...
Fatal: Cannot open configuration file "/usr/X11R6/lib/X11/xmcd/config/cdrom".

Fatal: Cannot open configuration file "/usr/X11R6/lib/X11/xmcd/config/cdrom".
TOC ERROR: No Artist Found at /usr/local/bin/ripit.pl line 297.
#

Well, this looks simple enough. One of the programs that ripit requires, xmcd, isn't working. I tried running that program at the command line and sure enough, it didn't work. Browsing the xmcd directory listed above, I found quite a few configuration files and a shell script, config.sh. The top of the script said that it configured xmcd, so I ran it. It asked me for my CD-ROM device name (/dev/acd0c) and a few other basic bits of information, then wrote out some configuration files.

The xmcd program now ran, and pulled up the contents of any album I put in. So, I tried to rip again.

# ripit.pl 
Getting CDDB info...

And it hangs. And hangs. Why? Well, let's check the documentation.

# man ripit
No manual entry for ripit
#

Fine, be difficult. See if I care. At least ripit is in Perl. Almost any Unix admin can read Perl. I open the file in emacs and browse through it until I find the "Getting CDDB info..." message. Whatever's broken is beyond that.

sub get_cddb {

  print "Getting CDDB info...\n";

  system("rm $tocfile >/dev/null 2>&1");

  system("cda -dev $cddev on >/dev/null 2>&1") ;
  system("cda -dev $cddev toc >$tocfile") ;
  system("cda -dev $cddev off >/dev/null 2>&1") ;

  if ( ! -r $tocfile ) { die "$tocfile is missing"; }
}

Perl is running the program cda. The arguments include whatever is in $cddev. Looking at the top of ripit.pl, I see that we can set all sorts of useful variables. The script expects to have the CD-ROM be available as /dev/cdrom. That's a useful, common convention, so I create it. I also loosen the permissions on /dev/acd0c, so a regular user can read from the CD-ROM drive. I'd rather not have to rip as root, after all!

# ln /dev/cdrom /dev/acd0c
# chmod +r /dev/cdrom
#

I also set the directory where I'd like the final MP3s to be entered. Now, let's test those commands.

# cda -dev /dev/cdrom on
Initializing...
CD audio daemon pid=34680 dev=/dev/cdrom started.
# cda -dev /dev/cdrom toc
Accessing CDDB... 

Genre: Rock -> General Rock *
Front Line Assembly / Tactical Neural Implant

 01 06:03  Final Impact*
 02 05:51  The Blade*
 03 05:04  Mindphaser*
 04 05:46  Remorse*
 05 05:26  Bio-Mechanic*
 06 05:23  Outcast*
 07 06:22  Gun*
 08 05:09  Lifeline*

Total Time: 45:06
# cda -dev /dev/cdrom off
CD audio daemon pid=34680 dev=/dev/cdrom exited.
#

So cda starts, can read a disc table of contents, and stops. (Although I don't know anyone who calls Front Line Assembly "General Rock.") I rip once more:

# ripit.pl
Getting CDDB info...
TOC ERROR: No Disc ID found at /usr/local/bin/ripit.pl line 241, <CDTOC> chunk 1.
#

Well, at least it's a different error message. Here's the code.

sub get_cdinfo {

 local $recnum = 0;
  
 open(CDTOC, $tocfile) || die "Can't open $tocfile: $!"; 
  
 while (<CDTOC>) {
  
  chop;
   
  $recnum++ ;
  
  # Get genre and DiscID
  if ($recnum eq 1) {
   if (/Disc ID:/) {
    ($tmp1, $tmp2, $genre, $discid, $otherdiscid) = split ;
   }
    else {
     die "TOC ERROR: No Disc ID found";
   }
  }

ripit is looking for a file it calls $tocfile. It expects the first line of this file to contain the string Disc ID:. A search for that string shows that this file is actually /tmp/cdtoc.cdrom. It's complaining about the first line of this file. I "cat" it, and it's just the output of cda -dev /dev/cdrom toc above. If you look there you'll see that yes, "Disc ID" does not appear on the first line. Let's try another CD. Perhaps my Front Line Assembly disc is unique in not having a disc ID. The file /tmp/cdtoc.cdrom now contains

Accessing CDDB... 

Genre: Rock -> General Rock *
Blue Oyster Cult / Secret Treaties

 01 03:59  Career of Evil*
...

No CD ID here either. (And Blue Oyster Cult is not "General Rock," it's classic heavy metal, dang it!) The man page for cda offers no help, and I play with various command-line options without success. At this point, I give up and start searching the FreeBSD mail archives.

Oddly enough, nobody else seems to have this problem. This seems to work for everyone in the world, except me. A quick email to multimedia@FreeBSD.org asking for a recommended ripping tools actually nets me a few pointers. Back to ripit!

So, something has changed. The output from cda doesn't match what ripit is expecting. Either ripit has changed, or cda has. Let's track that down.

My first suspect is cda. It's obviously a dependency port of ripit, but which port? We can find out with the -W flag to pkg_info(1).

# which cda
/usr/X11R6/bin/cda
# pkg_info -W /usr/X11R6/bin/cda 
/usr/X11R6/bin/cda was installed by package xmcd-2.6_1
#

cda is part of xmcd. Let's check out the FreeBSD CVS repository and see if the port has changed lately. There's a friendly Web interface available that lists all changes ever made to the FreeBSD source repository. Select "ports," "audio," and "xmcd." There you can see all changes made to any file in the port.

Aha! Four weeks ago, the FreeBSD Security Officer updated this port to a new major version. No wonder it works slightly differently. The commit message says that the old version had various security issues, none of which are of any importance whatsoever on my laptop. (They would be exploitable on a system used by multiple users, however.)

I'm running 4.4-RC3. 4.3-RELEASE had the older version. I downloaded this package from a FreeBSD FTP site, deinstalled the existing xmcd package, and installed the one from 4.3-R. And at last I got:

# cda -dev /dev/cdrom toc
Disc ID: rock 9110da0a *
Noise Unit / Decoder

 01 06:00  Bahnhof*
 02 07:54  Innerchaos*
 03 06:12  Protector*
 04 08:40  Paradise (Dis)*
 05 05:17  Firing Line*
 06 08:36  Escape*
 07 07:10  Elixure*
 08 09:38  Biosphere*
 09 06:21  Ascent*
 10 06:06  Falling*

Total Time: 71:56
#

MP3: The Definitive GuideMP3: The Definitive Guide
By Scot Hacker
March 2000
1-56592-661-7, Order Number: 6617
398 pages, $29.95

Note the difference between the first lines of the output in this older version of cda, and the output of the newer version of cda. The ripit utility ran fine. I now have two dozen CDs on my laptop, and even my Nurse With Wound albums don't sound too bad in MP3.

The lesson here is that you need to solve problems on your own. ripit worked fine for everyone who had a version of xmcd more than a month old. I'm sure other people have had this problem and have either given up or decided not to worry about it. It's also something of a flaw in the Unix philosophy of "many small, independent tools"; changes in one tool can affect others in unsuspected ways.

Now if I could just get my circa-1982 Throbbing Gristle cassettes onto MP3, I'd be all set.

(The author would like to thank the various folks on freebsd-multimedia@freebsd.org who assured him that he wasn't crazy, and this really was supposed to work.)

Michael W. Lucas


Read more Big Scary Daemons columns.

Return to the BSD DevCenter.

Copyright © 2009 O'Reilly Media, Inc.