An Eccentric MP3 Player

1. General Information

This page describes Ambient version 1.1, dated 22-August-2009.

Ambient is an eccentric MP3 music player program for Linux. Note that this page describes the Linux version of Ambient. There is also a Mac OSX version that is substantially independent code and is described at

The official source for Ambient is maintained at:

At the moment, I'm only distributing this application in source form, open sourced under the MIT license.

Bug reports, flames, questions and other feedback should be directed to:

2. Background

Ambient is an MP3 music player program for Linux. It was created for two purposes. First, to give me a music player that satisfied my own admittedly somewhat eccentric feature desires. Second, to teach myself to use GTK, which at the time was the least obnoxious GUI toolkit I'd thus far encountered.

The idea for Ambient came about because I bought a big disk drive, ripped my CD collection (about 400 discs) and found myself with 6,000 or so MP3 files on my hands. The various MP3 player programs I tried out seemed to waste a lot of code on useless features like "skins" while not giving you a great handle on managing a big collection of music files (this was way before the advent of iTunes, which, though loaded with cool features, I still find unsatisfactory on a number of dimensions). Also, the way the MP3 world has developed, there seems to be a strong bias towards thinking of individual songs as the granularity of packaging, whereas CDs and other traditional recording media are structured around the album. This is not to say that the album is a better way to organize music, but simply that that is the way the corpus at hand is already structured artistically so it makes sense to be able to think of things that way when you want to. Finally, I wanted a way to characterize the music in my collection according to various traits that correspond more to mood than to genre: I mostly listen to music while working, and I find that the kind of music that is good for coding by is entirely different from the kind of music that good for debugging by, which is in turn entirely different from the kind of music that is good for writing by, and so on. So I wanted a program that I could just instruct, for example, "I'm debugging now" and have it queue up appropriate material. Then when I shift to writing, tell it so and have it seamlessly shift the mood of what it's playing accordingly. That's a big part of what Ambient does.

3. Installation

1. Download the Ambient tarball from

2. Make sure you have two other prerequisite pieces: GTK, for the GUI, and either XAudio or FMOD, to actually make the sounds come out of the speakers.

GTK is a GUI toolkit originally developed for the GIMP image editor, but which has since evolved into a major piece of work in its own right. GTK is included by default in most Linux distributions, notably Red Hat 7 (which is what I was using when I first wrote this code). If you don't have GTK, you can obtain it from the usual sources for open source stuff. The authoritative source is

XAudio is an MP3 codec that has a very, very nice API. It is, unfortunately, not open source software. However, I haven't found anything else for the job that is nearly as easy to work with and I'm just not interested in the hassle involved with integrating something else (though you, of course, are welcome to undertake this task if that's what floats your boat). Though oddly encumbered from an intellectual property standpoint, it is available to anyone for no charge. (The XAudio folks also offer a cost free redistribution license, but I have not yet had the time or motivation to go through the bureaucratic effort involved in obtaining one, hence the XAudio library is not included as part of the Ambient distribution.) You can obtain the XAudio library yourself from and install it. The Makefile included here assumes a standard Linux XAudio install.

FMOD is a newer audio package that is used by a lot of game software. Like XAudio, it is a non-open source commercial product, but also available for free for non-commercial use. I haven't jumped through the licensing hoops, so, like XAudio, you'll need to download and install it yourself prior to building Ambient. It can be obtained from

If you wish to build Ambient, you will probably have an easier go of things working with FMOD rather than XAudio, as the company that owns XAudio keeps waffling on availablity of the SDK and consequently it tends to unpredictably phase in and out of being obtainable.

3. Unpack the tarball into a location of your choosing and cd to the ambient-1.1 directory containing the package's source code.

4. Type make to compile the package. It will produce an executable named amb.

5. Copy the executable to wherever you put your installed executables.

4. Supported Platforms

This program has been tested on and is known to work on (and indeed is used daily on) x86 Red Hat Linux 5.2, 7.0, 7.1 and 7.2, as well as Fedora versions 3 through 11.

I see no particular reason why it shouldn't be able to build and run on any sane Unix platform that is supported by GTK and XAudio or FMOD (which is quite a large list), but I don't make any promises. It could probably even be ported to, uh, Windows, but I'm certainly not going to mess with that.

There is also a Mac OSX version of Ambient that is a nearly complete rewrite in Objective C. It represents the fruit of my teaching myself the Cocoa application framework. It has a number of advantages, including a much spiffier UI, the ability to play other audio formats besides MP3 files, and it is not dependent on XAudio or FMOD, though it is still dependent on the funky CDDB-driven metadata used by the Linux version (which means you can play the music on your Mac but you still need a Linux box to rip and maintain the music library). It is available separately at

5. Use

(This is a fairly terse and somewhat disorganized summary of the operation of Ambient. Eventually I ought to produce superior documentation, but in the interest of not further delaying its public release I'm going to let it go with just this for now.)

5.1 What it does

Ambient is an MP3 player. It sits on top of a collection of MP3 files, shows you what's there, and lets you play stuff. There are three sources of information that Ambient uses to manage the MP3 collection:

The basic operation of Ambient is:

1. Read the .amb file (usually)
2. Do stuff (e.g., play music)
3. Write the .amb file (usually)
4. Exit

Naturally, all of the interesting activity happens in step 2. What actually happens depends on the command line options Ambient is started with, but broadly speaking, there are batch mode operations and there is interactive mode. Interactive mode, in turn, can interact with you via one of two different UIs: text or GUI.

5.2 The data model

Ambient's model of the world is a three-level hierarchy of artist/album/track. The MP3 collection is a directory containing one sub-directory for each artist. Each of these in turn contains a directory for each of that artist's albums, which in turn contain a set of .mp3 files for the individual tracks on the album. Artist and album directory names are generated from the artist's or album's name by mapping all "funny" characters (basically, everything except alphanumerics, period (`.'), hyphen (`-') and comma (`,')) to underscore (`_') but preserving letter case. The .mp3 file names are generated from the track title using a name of the form NN.TITLE.mp3, where NN is the 2-digit track number and TITLE is the title of the track mapped the same way artist and album names are mapped.

For example, one little bit of my file hierarchy has:


Note that this hierarchy and set of name mapping rules is the natural form produced by the CD ripping program I use, Grip (, or at least it was when I stared using it. Grip has in the meantime changed its name mapping rules slightly, but I've not yet modified Ambient correspondingly. (If you are using a newer version of Grip you may need to do some manual file renaming to make Ambient happy; sorry.)

5.2.1 Comma mangling

Ambient maintains a more legible representation of this hierarchy in its database. It remembers the unmangled form of the artist, album and track names and generates the file names for the .mp3 files as it needs them. Actually, that's not 100% true. Ambient treats commas in artist and album names as a special case. Ambient's GUI presents these in alphabetic order, but before actually displaying them it rearranges stuff between commas for legibility. Thus:

Mozart, Wolfgang Amadeus
Nuclear Whales Saxophone Orchestra, The

display as:

Wolfgang Amadeus Mozart
The Nuclear Whales Saxophone Orchestra

respectively, but alphabetize in the Ms and Ns rather than the Ws and Ts. The comma rearrangement rules also allow for embedding with two commas:

Petty, Tom, And The Heartbreakers

displays as:

Tom Petty And The Heartbreakers

but alphabetizes in the Ps instead of the Ts. Finally, the case where a comma legitimately appears in a name is handled by appending an extra comma on the end of the name. Thus the album title

Past, Present And Future

which would incorrectly render as:

Present And Future Past

can be forced to display properly by stating its title as:

Past, Present And Future,

Yes, this is a hack.

5.3 Using Ambient with Grip and CDDB

As I mentioned above, I rip CDs using Grip. Grip makes use of the CDDB database at (*see footnote). When you feed a CD to Grip, the first thing it does is query FreeDB using the CDDB protocol, which more often than not will return a listing of the disc's artist, album and track information, saving you the trouble of entering it all yourself (though you will often have to fix typos, spelling errors and creative use of letter case before using this data -- you are dealing here with the Internet hive mind at its simultaneous best and worst). If the CDDB query doesn't turn up any data, then you just have to enter it all yourself after all. Also, I locally modify the artist and album names to follow the comma-mangling conventions described above, which differ from FreeDB's preferred rules for naming things. In any case, the information about the CD is saved in a file which Grip maintains (normally in the directory ~/.cddb).

[*footnote: <rant>Alas, the original CDDB database at has been usurped by a company called Gracenote, who have asserted private ownership over the collective product of thousands of individual Internet users who cooperatively contributed to the CD database over the years. This is one of the uglier sides of the Internet revolution, the bald-faced seizure of assets by people whose position seems to be that they can get away with it because nobody else's individual interest is large enough to justify the cost of stopping them. These people are thieves and you ought not to associate with them. </rant>]

Ambient gets its notion of the names of things, as well as other information such as track lengths, by reading the files in Grip's CDDB cache. This is how you tell Ambient about the arrival of new files in the MP3 collection: you tell it to reread the CDDB cache, from which it will update its .amb file accordingly.

5.4 Actually using Ambient

5.4.1 Some general concepts

Ambient has two ways of deciding what it should play: stepping through a playlist, or selecting randomly based on "mood".

The playlist is fairly straightforward. It's just a list of tracks to play. You can add to it by selecting individual tracks, whole albums, or an artist's entire corpus. Once in the playlist, entries can also be selectively removed, or the whole list shuffled or cleared.

The entire "mood" mechanism, on the other hand, is a bit peculiar and requires further explanation. The desire to have this mechanism is what motivated my writing Ambient in the first place. The basic idea is that there is a collection of "moods", which are simply symbolic attribute tags that you can define and then attach to particular tracks, albums or artists. (Actually, I'd prefer a different term than "mood", which has some other flakey connotations I'd rather not be associated with, but until a better word pops up this term will do.) You can do a search of the music collection by mood or by an arbitrary boolean expression of moods; the result of the search can be examined to satisfy your curiosity or it can be added to the playlist. Finally, and most importantly, you can indicate an "ambient mood" (or, once again, a boolean expression of moods) to the program and it will select tracks at random that match that mood and play them (and though the tracks will play in random order, they won't repeat until they've all been played). This is good for situations that just want to have appropriate background music, like programming or writing.

A couple of other minor features:

You can link one track to another, so that selecting the first track for play will automatically select the track it is linked to as well. Multiple tracks can be chained together in this fashion. This is useful for something like a symphony, which is typically spread over multiple tracks but really wants to be treated as a single unit (unless you are the kind of person who always prefers listening to selected individual movements, which I'm not).

You can mark tracks as "don't play". This will prevent Ambient from playing the track when it is told to play the larger collection (album or artist) that contains that track. This is mainly useful for telling it to avoid things like CD-ROM tracks which don't actually correspond to files in the MP3 collection. It's also useful for skipping empty tracks that record producers sometimes put in when trying to be artsy (for example, on The Why Store's eponymous 27-track CD, tracks 13 through 26 are empty for no obvious reason). In fact, when taking in new info from the CDDB cache, Ambient will automatically mark any track entitled CD-ROM Track or Empty as "don't play", though you can undo this if somebody actually created music with one of those titles. You can also use the "don't play" feature to skip the occasional utterly horrible abomination that sometimes crops up in the midst of otherwise reasonable music (my prototypical example of this phenomenon being the Pet Shop Boys' piece "The sound of the atom splitting" which appears on the first disc of their "Alternative" album. This is a disc which I otherwise adore, but this particular track makes me involuntarily jump out of my chair while my blood pressure spikes dangerously; in a way it's actually a remarkable artistic achievement, but I don't want to experience it again without deliberation. This one track was the spur that caused me to implement the "don't play" feature.)

5.4.2 GUI interactive mode

Ambient's normal mode of operation is via its graphical interface. The vast majority of the interface is presented in a single window that comes up when you start the program. I haven't had the time or energy to incorporate any screen shots into this document, so you will either have to follow along with the rest of this section while using the program, or use your imagination. The music collection frame

At the top of the window is a large pane which displays the music collection, sorted alphabetically by artist. You can select a particular artist by clicking on the line containing their name. If you double-click on an artist, the list expands to include that artist's albums, which in turn can be selected by clicking on them or expanded via double-click into lists of the tracks on those albums. You can also move the your selection up or down by using the up or down arrow keys, or scroll up and down by fiddling with the scrollbar using your mouse. You can also randomly skip to a particular artist by typing the first few characters of their (last) name.

Below the music list is a frame containing controls related to whatever artist, album or track is currently selected. This frame displays summary information about the selected item: in the case of an artist, the artist's name and the number of albums; in the case of an album, the artist's name, the album name, the number of tracks, the total playing time of all the tracks, and the name of the CDDB hash tag (this last is mainly for debugging and can generally be ignored); in the case of a track, it displays the artist name, album name, track title and number, and the playing time of the track. To the right of the summary information is box showing the attached moods associated with the selected item, if there are any; these may be individually selected by clicking on them.

The controls here include four buttons, and a checkbox: The Moods Dialog

The Moods Dialog is used to manage the collection of defined moods. It consists of a list of the currently defined moods and four buttons. A mood can be selected from the mood list by clicking on it. The four buttons are as follows: The play mode frame

Below the music collection frame and its associated controls is a display showing information about the currently playing track: it shows the artist name, album name and track title, plus a real-time counter showing the current elapsed playing time on the track.

Below this display are a pair of radio buttons and two regular buttons: The Playlist Dialog

The Playlist Dialog is used to view and manipulate the playlist. It consists of the playlist itself and four buttons. A track in the display list can be selected by clicking on it. The four buttons are as follows: The Set Ambient Mood Dialog

The Set Ambient Mood Dialog lets you set the current ambient play mood. It presents a box into which you can type a mood expression (see below). The "OK" button accepts this new mood; the "Cancel" button dismisses the dialog and leaves the current ambient mood unchanged. The miscellaneous frame

Below the play mode frame and its associated controls (i.e., at the bottom of the window) are a number of other controls. On the left are three buttons:

On the right are a box displaying the current ambient mood (if there is one) and a set of conventional CD-player style control buttons: The Patterns Dialog

Patterns are simply named boolean expressions of mood names and other patterns. They can be used for making more complicated selections of music. The Patterns Dialog lets you manipulate the collection of currently defined patterns.

The main body of the dialog window is a list of the names of all the currently defined patterns. A pattern can be selected by clicking on it. Below this list is a box that shows the mood expression corresponding to the selected pattern; this expression may be edited. Below this are four buttons: The Find Dialog

The Find Dialog lets you use mood expressions to search the music collection. At the bottom of the window is a text box in which you can type a mood expression. Below this are three buttons: Mood expressions

At several points above (setting the ambient mood, defining patterns, and using the Find Dialog), reference was made to "mood" expressions. These are boolean expressions which are used to match tracks to particular combinations of mood settings. The syntax of mood expressions is simple and primitive:

expr & term
expr | term


! term
( expr )

A bit more explanation:


An alphanumeric symbol should be the name of either a mood or a pattern. If it is a mood, it evaluates to true or false for a particular track depending on whether or not the named mood is attached to the track or its enclosing album or artist. If it is a pattern, then it evaluates to true or false for a particular track according to whether or not the pattern's associated expression evaluates to true or false for that track.

&, |, and !:

The boolean operator symbols &, |, and ! correspond to AND, OR and NOT respectively. If you don't know what this means, you shouldn't be using this feature.

Thus, for example, I have defined the pattern ok to be:

listenable | chip_fave | one_good_song

which identifies something I'm generally willing to listen to: either something that I've marked as sort of blandly normal (my listenable mood), or something marked as one of my favorites (my chip_fave mood), or the all too common case of the one good song on an album that otherwise sucks (which I mark with the one_good_song mood -- are you beginning to see why "mood" is maybe not the best word for these markers?). Given this, I then defined a pattern ok_pop to be:

ok & !classical

which is all the stuff that matches the first pattern minus all the stuff marked as classical music.

5.4.3 Text interactive mode

Ambient also has a text mode (command line) interface. This can be used if you don't have an X display or if you just prefer this sort of thing. I mainly used it when I was debugging the player logic and hadn't yet written the GUI, but I left it in just in case it might be useful some day.

You can start up Ambient in this mode with the --command-line option. Ambient then begins accepting commands from the standard input.

One additional concept needs to be explained to understand the command line interface. This is the idea of a "context". This corresponds to a position in the music collection rather like the idea of the "current working directory" in Unix. The context at any point is some particular track, album, artist, or the whole database. You can move around from context to context, much as you would do a cd command in Unix. The current context is an implicit parameter controlling the behavior of many of the commands. One difference is that context "path names" contain ordinal integers rather than symbolic names as a file hierarchy would; this is because the name of a context is the artist, album or track name, which you really don't want to have to type when moving around in the tree.

The commands it knows are:

alias name

Assign alias name to the current context.

ambient [ expr | off ]

Set the ambient mood and play according to it.


expr: pattern match expr to identify mood to be played. Any tracks currently in the play queue will be discarded, but any track currently playing will finish before the new mood takes effect.

off: cease ambient playing and flush the play queue.

With no arguments, all tracks descended from the current context will be played ambiently.

defmood name [ comment ]

Define a new mood named name with optional comment comment.

Note that if name is already a defined mood, this will change its comment but will not alter the set of elements associated it. If you wish to create a new mood with the same name but a different set of associated elements, you must first use the undef command to eliminate the current definition of name.

display [ moods | aliases | patterns | all | symbol ]+

Display the definitions of one or more symbols.


moods: display all the mood definitions
aliases: display all the alias definitions
patterns: display all the pattern definitions
all: display all defined symbols
symbol: display the definition of symbol

With no arguments, all symbol definitions will be displayed

enqueue [ expr ]

Add tracks to the active play queue.


expr: pattern match expr to identify tracks to be enqueued.

If expr is omitted, all tracks descended from the current context will be enqueued. Note that this command will not start the player playing if it is not already doing so. Use the start command to begin playing the queued tracks.

find [ -t ] expr

Find elements matching expr.

If the flag -t is given, finds all tracks that match expr or are descended from an artist or album that matches.


Empty the play queue and stop playing.

generate [ expr ]

Generate and display a playlist (without enqueueing it).


expr: pattern match expr to identify tracks to be playlisted.

If expr is omitted, all tracks descended from the current context will be playlisted.

go path

Go to the context specified by path.

A path consists of a sequence of 1 or more path elements separated by / characters, in the style of Unix pathnames. A path element may be one of the following:

Paths are normally relative to the current context. However, you may precede the path with a / character to denote a path relative to the top (database) context.

help [ commands | cmd ]

Provide help information.


commands: list a synopsis of all available commands
cmd: describe the particulars of command cmd

With no arguments, general help will be given


Display information about the current context.

link [ album ] [ track ]

Link current album or track to another.


album: an album alias to link to
track: a track number to link to

With no arguments, links to next sequential track or album

ls [ -atlmn ]

List the current context.


-a: list down to level of albums
-t: list down to level to tracks
-l: show detailed information, not just names
-m: show moods associated with contexts
-n: show aliases associated with contexts

mood mood

Attach mood to the current context.


Go to the next context at the current level.

pattern name expr

Define a pattern matching expression.


name: a symbolic name for the expression

expr: a boolean expression in terms of mood symbols. You may use the operators & (and), | (or), and ! (not), as well as parenthesis for grouping. Expression evaluation is strictly left to right with no operator precedence.


Pause the currently playing music.

play [ expr ]

Play a playlist.


expr: pattern match expr to identify tracks to be played.

If expr is omitted, all tracks descended from the current context will be played.

Any tracks currently being played will be discarded from the play queue.


Go to the previous context at the current level.


Exit Ambient.

rename name

Change the name of the current context to name.

set continue | noplay

Set the current track to have a particular attribute.


continue: only play this track when following a link
noplay: don't play this track when playing its container


Display the current play queue.


Randomize the order of the play queue.

skip [ n ]

Skip ahead in the play queue n tracks. If n is omitted it defaults to 1.


Begin playing the current play queue.


Display current system status.


Stop playing music, if playing.


Synchronize the database with the current CDDB collection.

undef name

Remove the definition of alias, pattern, or mood name.


Remove any link from current album or track.

unmood mood

Detach mood from the current context.


Resume playing after a pause.

unset continue | noplay

Remove an attribute from the current track.


continue: ok to play this track other than when following a link
noplay: ok to play this track when playing its container


Go to next higher context.

5.4.4 Batch mode

In batch mode, Ambient skips the stage where it presents either the GUI or the text mode interface to the user. It simply starts up, optionally reads the .amb file, does some operation (as specified by the command line options), optionally writes the .amb file, and exits. Batch mode is typically used for diagnostic purposes rather than as a normal mode of operation.

Four batch mode operations are supported:


causes Ambient to do a rigorous cross check of the information in the CDDB cache, the contents of the .amb file, and the contents of the MP3 collection, and print out a report (to stdout) of any inconsistencies it finds (missing files, name conflicts, and so on).


causes Ambient to print a listing (to stdout) of the contents of the MP3 collection.


causes Ambient to print a listing (to stdout) of the information contained in the CDDB cache.


causes Ambient to read the information in the CDDB cache and generate a new .amb file containing the corresponding information. This is typically only used the first time you import a CD collection into Ambient.

6. amb Command Reference

The executable for Ambient is named amb


amb [ option ]...

The program accepts the following options:


Audit the correspondence between the MP3 file collection, the information in the CDDB cache, and the information in the Ambient database file.


Execute non-interactively (this option is implied by any of --audit, --dump-mp3,
--dump-cddb, or --cddb-to-amb).

-c dir
--cddb-base dir

Set the directory root for the CDDB cache to dir (default is ~/.cddb).


Dump a listing of the MP3 collection.


Dump the information in the CDDB cache.


Use a graphical interface (normally this is the default).


Display a summary of the command line options and exit.

-i ifile
--in-file ifile

Read the Ambient database (.amb file) from ifile (default is ./music.amb). Use - for standard input (in which case --batch-mode is implied).


Use a command line interface instead of the graphical interface.

-m dir
--mp3-base dir

Set the directory root for the MP3 file collection to dir (default is ~/Music).

-o ofile
--out-file ofile

Write the Ambient database (.amb file) to ofile (default is to use the same file as was used for the input). Use - for standard output.


Don't write to the .amb file on exit.


Generate lots of messages.


Generate the .amb output from the CDDB data.

7. Bugs & Todo

There should be a proper man page. In general the documentation could be better.

There should be a way to save and load playlists separate from the rest of the database.

It would be great if an open source alternative to XAudio or FMod could be had.

XAudio sometimes hiccups a bit going from one track to the next. Supposedly there is a way to fix this but I haven't been able to.

The Find features and the mood features could be better integrated.

There are some bugs when you define patterns in terms of other patterns. The expressions don't necessarily get written to the .amb file in dependency order, so they may fail to load properly later due to undefined expression terms.

Non-mouse operation of the GUI could be friendlier.

Arguably it would be better to actually use some kind of random-access database instead of rewriting everything on program exit. Life is full of trade-offs.

The mapping to .mp3 filenames could be more tolerant of different conventions for handling letter case and non-alphabetic characters.

It would be nice to be able to edit the names of things from inside the GUI, rather than having to manually edit the .amb file or one of the CDDB cache files.

There should be a way for the GUI to link non-consecutive tracks. The text mode interface and the underlying player mechanism supports this but there are currently no GUI controls to make use of this feature. (On the other hand, it's not at all clear that this would be a terribly useful feature. YMMV)

The time counter displayed while playing with XAudio does a bad job of tracking the actual playing time.

Chip Morningstar (