CD TOC Reading in Mono

I had been getting bug reports that Banshee was not properly querying CDDB for track information on some discs. After some investigation, these discs turn out to be multi-session discs containing audio and data. It turns out that GStreamer (gstreamer-cdparanoia) does not generate a proper CDDB Disc ID, and even gives a warning about multi-session discs. That’s no good. Last night I set off to write a more direct approach to reading a CD’s Table of Contents.

I now have a mostly managed solution, using the Linux CD-ROM userspace kernel ioctls. However, the cdrom_tocentry struct for the CDROMREADTOCENTRY ioctl was a pain to marshal, so I added some C glue that will go in libbanshee. Ideally I’d like to marshal it and get rid of the glue. Obviously this will only work under Linux at the moment, but there should be no problem porting it to BSD et al. when necessary.

The important part is that the code generates proper TOC offsets for tracks, can calculate a proper CDDB Disc ID for plain audio and multi-session discs, and flags tracks as either audio or data, so the Banshee UI can hide the data tracks altogether.

For those interested, a standalone TOC reader is available. I’ll have this code merged in Banshee for the 0.9.8 release towards the end of the week.

10 Replies to “CD TOC Reading in Mono”

  1. great! great! great!
    i’m developing a cd catalog app, and your TOC code is exactly what i need. please keep it as standalone as possible :)

  2. Feel free to use it, but after today any extra development on the code will go directly into Banshee, as that’s why I wrote it. It will still be easy for others to reuse it though.

  3. Why not use MusicBrainz to get track listings, this way you don’t need to know anything but the device path, the MusicBrainz library does the right thing.

    You also get non-insane metadata…

  4. j36: I should have talked about that in the post. The GStreamer plugin does indeed need to be fixed, and I’d like to contribute at least a Linux fix for it. However, I’d still probably use this code for TOC reading as it’s overall much faster (zero GStreamer overhead, and the CD doesn’t have to spin up). I’m using GStreamer for playback, ripping, and transcoding though.

  5. Ross: yes, I’ll probably just move to MusicBrainz eventually and solve all this craziness. I haven’t looked into it a whole lot, but I assume the library handles TOC reading to generate the Disc ID and frame offsets (or whatever other unique info MusicBrainz uses to query its database)?

    Does it cache query results on disc for subsequent lookups like the GNOME CDDB Slave client does?

  6. No, the library doesn’t cache. I’m planning on writing a re-usable wrapper (as Sound Juicer, Rhythmbox, and Totem both use musicbrainz) which does caching soon.

  7. Note that the musicbrainz server also proxies queries to the FreeDB servers if it doesn’t have any results, so it should never be less useful than direct CDDB lookups (quite often it will have better quality information, actually).

  8. There is another way to fix the TOC reading problem with gstreamer cdparanoia… Switch to using cddasrc gstreamer plugin and you end up with a much better and actively supported solution that uses the excellent and portable libcdio library. That does not require a single new line of code :)

Comments are closed.