The albumlib project presents the concept of storing music tracks
bundled together as albums, using existing open file formats,
This format is similar to the OpenOffice formats, the data are bundled
in a zipped archive file with a xml "header" (manifest).
The album.xml (manifest) file holds the album track list, track
timing, track lyrics, album cover, lyrics, weblinks.
I'll ask you back: Why is ripping track-oriented? Almost all
material originates from albums, album-orientation is natural.
And why should the tracks (only) be tagged in a binary way: xml is better suited, better defined and - much - more accessible.
I propose introducing album-orientation plus xml-tags (as an addition to the existing tags).
An added benefit: bundling tracks together in .album files makes for
much fewer file on your disk, which makes backing
up/copying your music collection substantially faster (the added
complexity of reading a track from inside an archive should not in principle make the player any less responsive).
It's a 'new' file format for rippers and players to handle, but as the implementation
is simple and builds on existing
file formats, it's not that much work to support it.
It need not have any impact at all on the way the tracks (playlists) are presented by players to their users.
The albumlib executable is an encoder, it reads up all files
with the designated extension in a directory (which hopefully makes up
an album), for instance
"album-encoder.exe mp3" means read all mp3's in current dir and make an .album archive out of it.
The file structure in principle:
albumname.format.album (actually uncompressed .zip)
01 - Future Legend.mp3
02 - Diamond Dogs.mp3
03 - Sweet Thing.mp3
04 - Candidate.mp3
05 - Sweet Thing (Reprise).mp3
06 - Rebel Rebel.mp3
07 - Rock 'N Roll With Me.mp3
08 - We Are The Dead.mp3
09 - 1984.mp3
10 - Big Brother.mp3
11 - Chant Of The Ever Circling Skeletal
12 - Dodo (Previously
unreleased track recorded in 1973).mp3
13 - Candidate (Demo version recorded in
album.xml: Each track entry holds both the track's file name (eg. "01 - Title") and the
proper track title ("Title" = tag from inside the file)
- The zip file is uncompressed ("stored") as music files are heavily
- Zip is chosen over tar because zip is the most WinXP-friendly.
- 0.9.1: Less namespace pollution on Linux (xdirent.h). MSVC 2005 compliance + workspace.
- 0.9.0: Initial release
- albumlib project page
- albumlib downloads
- albumlib cvs
- Example album.xml file
- Example .album file
- Different takes on albums: cue sheet, album wrap, album in a mp4
encoder/main.c: Encoder demo app.
album/include/album.h: Definition of albumlib ('encoder') interface.
album/source/album.c: Actual albumlib implementation.
is inflexible (handles diskbased files only, not memory/sockets nor
anything else), so I write all my I/O code using Gilles Vollant's
ioapi. One drawback of Vollant's implementation of ioapi is that it is
32 bits only (using uLong, not fpos_t or off_t). It is not a problem in
this little project but for good measure I'm including my hacked
32/64 bits version of ioapi too
Other drawbacks: No get/setlength functions. The open function itself
(I'd rather keep char/wchar_t stuff away from the interface struct).
My own zip 'lite' implementation: Only uncompressed ("stored") zip archives is implemented, write only.
This can be said to be a scaled-down implementation of the scaled-down MiniZip implementation of Info-ZIP.
Not implemented yet: Reading. Big-endian struct handling (compilation on non-Intel platforms).
Probably not to be implemented: Compressed archive.
My own tar implementation. If you absolutely wants to, (uncompressed) tar can be used instead of (uncompressed) zip.
Note: The implementation of opening a file inside an archive for reading is slightly
weird - but highly efficient (pointer to file name is cast
fseek-implementation used by zipstore.c and tar.c.
Implementation is probably somewhat incomplete.
makepath/splitpath-implementation. Implementation is probably somewhat incomplete.
A little piece of code that I'm very happy with; it combines [the elegancy of]
opendir/readdir/closedir with [the portability of]
stat and [the usefulness of]
In other words,
opendir/readdir is too basic as
readdir (basically) only returns the filenames, while
_findfirst/_findnext is too cumbersome as it requires
path+filter (often you have just path in hand and then needs to add *.*
) and it returns a rather platform-specific set of attributes (and
often you want just the filename).
This should look familiar to
dir = xopendir(path, XDIRENT_NODOTS);
struct stat st;
const struct dirent* element = xreaddir(dir, &st);
if (element == NULL) break;
xreaddir(dir, &st) with
xreaddir(dir, NULL) if you want only the file names.
xopendir_match if you want a filtered list (if you have path+filter).
xreaddir_impl if you after all wants to get the platform-specific set of attributes.
xclosedir takes the address of the handle in order to clear it.
xreaddir returns a
album/include/bool.h: Definition of C-compatible boolean type,
bool is not really C/backwards compatible).
Burn all makefiles and compile in CodeBlocks (album_win.workspace, album_linux.workspace: gcc 3.4.5), MSVC6 (album.6.dsw), MSVC 2003 (album.7.sln) or MSVC 2005 (album.8.sln).
Note: In CodeBlocks, check Settings|Compiler and
debugger|Other|"Explicitly add currently compiling file's directory to
All support modules are zlib. The actual file format and album.c are GPL for the time being.
- [mp3] ID3V2 tag reading
- [flac] Tag reading
Modified: June 14th 2006