C#
Banshee: Like Frankenstein! It rips!
A while ago (I mean when it landed in the FreeBSD ports tree), Banshee reacted when a music CD-ROM was in a CD-Drive: it crashed. Well, not so cool in fact, you had to double-check it was empty before launching the player...
More recently, I was happy to find out that it was not the case anymore: Banshee was simply unable to detect the CD-ROM anymore. Still not so cool: you were still unable to listen to an audio CD, not mentioning ripping it.
For some reason I cannot really figure out (I have spent quite some time in fixing Banshee for FreeBSD and giving it some love), I took a look at this problem.
Obviously, the first rusty part of the chain of tools involved with audio CD was MusicBrainz and more precisely musicbrainz-sharp (a client library for .NET / Mono). FreeBSD having it's own ioctls for managing CD drives, and musicbrainz-sharp having 3 concrete classes for managing such devices called DiscLinux, DiscWin32 and DiscWin32NT, a piece was definitively missing. With a great deal of inspiration, it was called DiscFreeBSD and provides bindings for almost everything referenced in sys/cdio.h. When instanced, this class reads the CD in the drive and computes an ID used to fetch information about the audio CD from the Internet.
Unfortunately, I could not test the library on a system one which it is supposed to work (read GNU/Linux) so I asked a friend of mine, Baptiste (Yes! It works!) [edit: 2009-11-10:12:04 he just told me he has a a-bit-better website where he is playing now...], to tell me how it goes and to help me make the library behave the same on GNU/Linux and FreeBSD. We quickly had some good results:
![]()
Yay! Tracks from Sopor Aeternus' album Les fleurs du Mal are being listed!
Unfortunately, it was not possible to listen to the CD nor rip it... Not so cool once more.
And here takes place the magic of GStreamer!
cd /usr/ports/audio/gstreamer-plugins-cdparanoia && make install
Now, Banshee can play and RIP audio CDs with a single mouse clic!
![]()
Playing Cinema Strange's The Astonished Eyes Of Evening...
![]()
And ripping it (progress in the bottom left corner)...
All this will be soon in your ports tree!
For those who can't wait, patches for musicbrainz-shap are in the project's trac: Add support for FreeBSD in MusicBrainzSharp.
- Romain Tartière's blog
- Login to post comments
Packing structures with Mono or how to fix alignment problems for P/Invoke
This is basically a[nother] note for myself.
I have just spent a while wondering why the size of some data structures in C# was wrong while writing bindings to the CD-ROM control features of the FreeBSD libc.
Considering the following code snippet:
struct msf {
public byte unused;
public byte minute;
public byte second;
public byte frame;
};
[StructLayout (LayoutKind.Explicit)]
struct msf_lba {
[FieldOffset (0)] public msf msf;
[FieldOffset (0)] public int lba;
[MarshalAs (UnmanagedType.ByValArray, SizeConst = 4)]
[FieldOffset (0)] public byte [] addr;
};
struct cd_toc_entry {
byte unused1;
public byte control_addr_type;
public byte track;
byte unused2;
public msf_lba addr;
};
struct cd_sub_channel_media_catalog {
public byte data_format;
public int mc_valid;
[MarshalAs (UnmanagedType.ByValArray, SizeConst = 15)]
public byte [] mc_number;
};
We can compute the size of each structure (MSDN page about types size):
- msf
- A msf structure contains 4 members each of 1 byte long so the whole structure is 4 bytes;
- msf_lba
- This is not more than the union of a msf structure (4 bytes), an int (4 bytes) and an array of 4 byte (4 bytes), so it's 4 bytes long too;
- cd_toc_entry
- A cd_toc_entry structure is composed of an unused byte (1 byte), 2 data byte (1 byte + 1 byte), another unused byte (1 byte) and a msf_lba structure (4 bytes) so it is 1 + 1 + 1 + 1 + 4 = 8 bytes long;
- cd_sub_channel_media_catalog
- A cd_sub_channel_media_catalog structure starts with 1 byte (1 byte), followed by an int (4 bytes), and an array of 15 byte (15 bytes). The whole structure is therefore 1 + 4 + 15 = 20 bytes long.
These results can be checked using Marshal.SizeOf:
Marshal.SizeOf (typeof (msf)) = 4 Marshal.SizeOf (typeof (msf_lba)) = 4 Marshal.SizeOf (typeof (cd_toc_entry)) = 8 Marshal.SizeOf (typeof (cd_sub_channel_media_catalog)) = 24
So the cd_sub_channel_media_catalog structure it 4 bytes long more that expected. This really sounds like alignment problems in C. A quick search on the Interop with Native Libraries page on Novell's wiki does not give any info about such a problem. Switching the two first fields order fix the size (but of course breaks the workability) so it is definitively an alignment problem that takes place here.
After some search, I could find the StructLayoutAttribute.Pack Field (actually I could not find this piece of information using the MSDN search engine, I had to search on the web similar problems and find this one with a reference to « Pack » to find this page in the Microsoft .NET documentation).
Finally, the solution is to write this:
[StructLayout (LayoutKind.Sequential, Pack = 1)]
struct cd_sub_channel_media_catalog {
public byte data_format;
public int mc_valid;
[MarshalAs (UnmanagedType.ByValArray, SizeConst = 15)]
public byte [] mc_number;
};
The MusicBrainzSharp port to FreeBSD can go on!
- Romain Tartière's blog
- Login to post comments
Meta-note-taking with Tomboy
Just wrote a Tomboy add-in allowing the user to keep notes in Tomboy notes. The idea? If just like me you rely a lot on short tags such as TODO or FIXME, you find it convenient to have the editor highlight them. It is exactly what the add-in has been designed for.
Mandatory screenshot:

Editing notes with FIXMEs and TODOs.
For more info and downloads, have a look to the Tomboy-Todo project's page.
- Romain Tartière's blog
- Login to post comments