Boodler: The boodler Reference Manual

The boodler script plays soundscapes from your package collection. (To install soundscapes and data in your collection, see boodle-mgr.)

boodler [ options ] package/Agent [ data ... ]

You must usually supply the name of a soundscape (Agent class) to play, in the form package.name/Agent.

Normally, this loads the most current version of the package which is installed. To specify a particular version, you can say package.name:X.Y/Agent, where X and Y are numbers. This locates a version with major version exactly X, and minor version Y or later. (For other ways to specify versions, see this wiki page.) The assumption is that if you want version 3.1 of a package, then 3.2 or 3.10 will be acceptable, but 4.0 is too big a change. To choose an exact version of a package, use two colons: package.name::3.1.37a/Agent

Any arguments after the soundscape are passed along to that soundscape as data. See Soundscape Arguments for the format of these arguments. (If a soundscape argument begins with a minus sign, precede it with --, so that it is not grabbed as a script argument instead.)

This special form:

boodler --testsound

...plays a test melody. This is always available; it does not have to be loaded from your collection.

Type boodler --help or boodler -h for a complete list of options.

Options that control sound generation

--output driver
Select one of the available driver modules. (See below.) The default is oss on Unix, osxaq on MacOSX 10.5 or later, or macosx on MacOSX through 10.4.
--list-drivers
List the driver modules which are available. Any of the listed drivers may be used with the --output option.
--device device
Set the device which Boodler will write to. The details depend on which driver module you have selected. (For a file-writing driver, this specifies the file to write.)
--list-devices
List the devices which are available for this driver module. (Not all drivers provide such a list. For a file-writing driver, any valid filename is a "device", so it makes no sense to list them.)
--rate soundrate
Set the sampling rate (in frames per second) which Boodler will try to use. If the sound device does not support this rate, Boodler will try to fall back upon some sampling rate which is supported. The default depends on the output driver, but is often 44100.
--master volume
Set the master mixing volume for all sounds. The default is 0.5. You should not increase this. If you do, any soundscapes that play more than one sound at a time (most of them) are likely to suffer from clipping noise -- sporadic static. (To increase Boodler's volume, you should use a mixer application to adjust your sound driver, or just turn up your speakers.) If you hear clipping noise in complex soundscapes, try reducing this option below 0.5.
--hardware
Display the capabilities of your sound hardware at startup time. This shows you explicitly what driver, sample format, and frame rate Boodler is using. It also dumps whatever other information about the sound interface might (conceivably) be important.
--define opt
--define opt=val
Pass an option in to the sound driver. The available options depend on which driver you are using. Note that if an =val is supplied, there may not be any spaces before or after the equals sign. See below for the meaning of the many options.

Options that affect printed output

--verbose
Turn on verbose handling of exceptions. Normally, if an exception occurs in the execution of an agent, Boodler just prints the name of the exception and continues running. If you set --verbose, Boodler will print out the entire Python stack trace. Log messages are also more detailed in --verbose mode; you will see the entire log channel name, instead of a summary.
--log level
Set logging to the given level, which may be debug, info, warning, error, critical. The default is warning, meaning that messages of that severity or worse are printed. (In other words, by default, debug and info messages are suppressed.) Set this to debug to see lots of picayune detail about sound generation.
--logconfig configfile
Format log messages according to the given file. This file can control how messages look, which messages appear, and where they are sent. (See the Python documentation for log config file format.) A sample logging config file is distributed in the Boodler source as ./etc/logging.config.
--stats interval
Turn on periodic statistics reporting. At intervals (given in seconds), Boodler will print out a message saying how many agents, channels, sounds, and note are queued up. This may be helpful for debugging soundscapes; if you see a value which increases without limit, you probably have a bug.

Options for locating data

--data directory
Boodler stores all its data in this directory. By default, this is a hidden folder in your home directory. On a Mac, it will be in ~/Library/Application Support/Boodler. On Linux or Windows, it will be a ~/.boodler folder.
--collection directory
Boodler stores downloaded packages in this directory. By default, this is the Collection subdirectory of the --data folder (given above). There is generally no reason to change this.
--external directory
This gives Boodler an additional directory, outside your normal package collection, to search for packages. (You may supply several --external directories if you wish.) This is generally useful only if you are developing a soundscape, and want to test it without packaging it up first.

Options for external control

--listen
Cause Boodler to listen for events on a network socket (incoming port 31863, by default). Soundscapes can pay attention to these events and react to them.
--port port
If --listen is used, this causes Boodler to listen on the given port number (instead of the default port 31863). The port may also be an absolute pathname (beginning with "/"), in which case Boodler uses a Unix domain socket instead of a network socket.
--stdinevents
Cause Boodler to listen for events on standard input. Soundscapes can pay attention to these events and react to them. This option is for programs which want to run Boodler as a subprocess. Not available on Windows.
--prop=opt
--prop=opt=val
Set a property value. Soundscapes can pay attention to these properties and react to them. (Think of them as soundscape-specific preferences.) Note that if an =val is supplied, there may not be any spaces before or after the equals sign.

Environment variables

All of these environment variables are optional. You can set all of this information with command-line arguments. (And command-line arguments override environment variables, if provided.)

$BOODLER_DATA
Boodler stores all its data in this directory. See the --data option.
$BOODLER_COLLECTION
Boodler stores downloaded packages in this directory. See the --collection option.
$BOODLER_PROPERTIES
Set a property value. See the --prop option. To set several properties, set this variable to a comma-separated list of opt or opt=val.
$BOODLER_SOUND_PATH
This is a holdover from Boodler 1.0. An old-style soundscape can load a sound from your $BOODLER_SOUND_PATH, rather than loading it from a package. This is supported only for the sake of old code; no modern soundscapes should rely on it.

Boodler sound drivers

Boodler currently offers these drivers:

file -- write file containing raw sample output

The file will be named "boosound.raw" by default. To change this, pass a filename as the --device.

The file will contain raw PCM sound sample data, two channels, 16 bits per sample, signed (centered at 0). By default the samples will be in the native endianness of your computer, but you can change this with --define end=big or --define end=little.

This driver limits the size of the file. By default, it will only write five seconds of sound data; you can change the limit with the --define time=interval option. If the sound agent stops before the time limit, you'll get a shorter file.

(Note that this driver writes to the file as quickly as possible. It probably won't take five seconds to generate a five-second sound file.)

--define time=interval
Generate approximately interval seconds of output. This defaults to five seconds.
--define end=big
Force the sound output to be written big-endian.
--define end=little
Force the sound output to be written little-endian.

stdout -- write raw sample output to stdout

This is similar to the file driver, but it streams its data to stdout, and there is no time limit. The --device argument is ignored.

The stdout driver, like the file driver, generates sound data as quickly as possible. This will probably be much faster than real time! If you pipe the output to a file, you will have a very large file very soon. This driver is intended to be piped to an application that can regulate its input, such as Ices.

--define end=big
Force the sound output to be written big-endian.
--define end=little
Force the sound output to be written little-endian.

oss -- Open Sound System

This is the default output driver on Linux and other Unixes. Use --device to control which audio hardware device is used; the default is /dev/dsp.

alsa -- Advanced Linux Sound Architecture

Another Unix sound framework. Use --device to control which ALSA device is used; the default is default.

--define buffersize=frames
Define the length of Boodler's generation buffer, in frames. The default is 4096.
--define hwbuffer=frames
Define the length of the ALSA sound buffer, in frames. The default is 16384. If you find that the sound skips when the CPU is busy, increase this value. The hwbuffer should not be shorter than the buffersize.
--define periodsize=frames
Define the length of the ALSA transfer period. This should be a fraction of the buffersize. The default is left up to the ALSA driver; it depends on the buffersize.

esd -- Enlightened Sound Daemon

Yet another Unix sound framework. The --device option defines the hostname to send sound to; it defaults to localhost. If no ESD daemon is running, this will attempt to write directly to /dev/dsp.

pulse -- PulseAudio

Yet another Unix sound framework. The --device option defines the device ("sink") to send sound to. (--list-devices is not currently supported, but you can use Pulse's pacmd command-line tool to get a list of devices; try its list-sinks command.)

--define buffersize=size
Set each write buffer to be size bytes long. The default is 32768.
--define end=big
Force the sound output to be written big-endian.
--define end=little
Force the sound output to be written little-endian.

jackb -- JACK via Bio2Jack

Yet again another Unix sound framework. The --device option defines the name of the JACK client which will generate sound. The default is "boodler".

--define buffersize=size
Generate sound in chunks of size bytes. The default is 32768. (This is not the same as JACK's write buffer size.)
--define connect=none
Do not connect the JACK client to any output devices. (Default.)
--define connect=output
Connect the JACK client to the first two output channels found. (This is a Bio2Jack option; I'm not sure how well it works.)
--define connect=all
Connect the JACK client to every output channel. (This may cause problems if you have, say, a MIDI JACK device. Again, it is included because Bio2Jack offers it, not because it is a good idea.)
--define end=big
Force the sound output to be written big-endian.
--define end=little
Force the sound output to be written little-endian.

osxaq -- MacOSX AudioQueue

This is the default output driver on MacOSX 10.5 and later. It is also compatible with the iPhone OS.

--define buffercount=count
Create a queue of count buffers. If you find that the sound skips when the CPU is busy, increase this value. The default is 3.
--define buffersize=size
Set each AudioQueue buffer to be size bytes long. The default is 32768.
--define end=big
Force the sound output to be written big-endian.
--define end=little
Force the sound output to be written little-endian.

macosx -- MacOSX CoreAudio

This is the default output driver on MacOSX 10.4 and earlier. (It works on 10.5, but is deprecated.)

--define buffercount=count
Create a queue of count buffers. If you find that the sound skips when the CPU is busy (for example, when you're dragging or resizing windows), increase this value. The default is 6.
--define buffersize=size
Set each CoreAudio buffer to be size bytes long. The default is 32768. (Values above 49152 may work poorly or be rejected by the OS.)

vorbis -- write Ogg Vorbis file

This writes a file, like the file driver; but it generates an Ogg Vorbis file. The default filename is "boosound.ogg". To change this, pass a filename as the --device.

--define time=interval
Generate approximately interval seconds of output. This defaults to five seconds.
--define quality=val
Set the Vorbis VBR compression quality, from 0.0 (low bitrate and quality) to 1.0 (high).

shout -- Shoutcast or Icecast source

This generates an Ogg Vorbis stream, and sends it to a Shoutcast or Icecast server (using libshout).

--define shout-server=name
Connect to shoutcast or icecast server name. Can be a domain or an IP address. Defaults to "127.0.0.1".
--define shout-port=port
Use port port on the streaming server. Defaults to 8000.
--define shout-user=name
Login with username user to the server. Defaults to "source".
--define shout-password=password
Login with password password to the server. Defaults to "hackme".
--define shout-mount=mount
With an icecast server, mount the sound on mount. Defaults to "/boodler.ogg".
--define shout-protocol=type
Use type as the protocol. Use "http" for icecast2, "xaudiocast" for icecast1, and "icy" for a shoutcast server. Defaults to "http".
--define quality=val
Set the Vorbis VBR compression quality, from 0.0 (low bitrate and quality) to 1.0 (high).

lame -- write MP3 file with LAME encoder

This writes a file, like the file driver; but it generates an MP3 file. The default filename is "boosound.mp3". To change this, pass a filename as the --device.

--define time=interval
Generate approximately interval seconds of output. This defaults to five seconds.
--define quality=val
Set the LAME VBR compression quality, from 9 (low bitrate and quality) to 0 (high). Yes, it's backwards. The default is 2.
--define fast
Use a faster VBR encoding algorithm. (Reduces quality somewhat.)
--define abr=rate
Use ABR (fixed average bit rate) of rate KBPS. The rate can be from 8 to 320.
--define haste=val
Modify the speed of the encoding algorithm, from 0 (slow and careful) to 9 (hasty). This affects the quality (but not the bit rate) of the output. The default is 2.

Soundscape arguments

Boodler soundscape arguments are specified in a slightly addled S-expression syntax. (S-expressions are the building blocks of Lisp. (Expect parentheses.))

A word about parsing

The first thing to remember is that Boodler wants to parse all of the argument data itself. (We're not talking about the arguments to boodler itself -- those begin with dashes, and are handled in the usual Unix way. We're talking about the soundscape and the options passed to it.)

Unix command-line tools usually get their arguments pre-split into words, but Boodler isn't interested in that, so it will jam all its arguments together and then do its own splitting. That is, the following command lines are exactly equivalent:

boodler pkg/Agent arg
boodler " pkg/Agent arg "
boodler pkg/Agent  "  "  arg

In all but the simplest cases, it's easiest to slap quotes around all of the argument data. That prevents the Unix shell from interpreting the parentheses to mean shell-language. However, in this section, we will ignore that and write all of our S-expressions without shell-quotes.

The syntax of S-expressions

Which is to say, the syntax of Boodler's S-expressions, which aren't really S-expressions, but I don't have a better term handy.

An expression is a string, or a parenthesized list of expressions. The following are all strings:

abc
123
"string with four words"

The following are all lists:

()
(abc 123 "string with four words")
(() 123 (list with four strings))

A list can also contain named entries. Examples:

(x=y)
(pitch=1.0 pan=0.5)
(abc bcd cde one=1 two=() three=(list of (lists)))

That last example contains three positional (ordinary) entries plus three named entries. This extension will look very odd to Lisp habitués, but it's just what we need to specify the argument of a Python function.

The other tedious-but-necessary details: a string can contain any characters, but you have to quote it if you want to include whitespace, single or double quotes, parentheses, backslash, or equals sign. You can quote a string with either single or double quotes, as long as you backslash any of that sort of quote inside it. Backslash backslashes, too.

S-expressions as soundscape arguments

Boodler interprets its soundscape and following arguments as a single S-expression, with the parentheses implied. The command

boodler org.boodler.play/OneSound 
    org.boodler.old.clock/clock_cuckoo pitch=1.5 pan=1

...assembles itself as the S-expression

(org.boodler.play/OneSound 
    org.boodler.old.clock/clock_cuckoo pitch=1.5 pan=1)

The first entry, of course, is interpreted as a soundscape agent to look up. The following entries (and named entries) are interpreted as whatever type the soundscape is expecting for that argument.

This is important, because S-expressions don't themselves have type information (except for "list" and "not a list"). 1 is parsed simply as a string. But the OneSound agent declares that its pan argument needs to be a float. So the 1 is passed to it as the Python float value 1.0. If that argument needed to be an int, it would be passed in as the integer 1; if it needed to be a string, it would be the Python string "1".

This is all straightforward for int, float, and string arguments. Bools aren't much harder; you can enter true or false, yes or no, or single-letter abbreviations of these -- or 1 or 0 -- and they will be interpreted as booleans in the obvious way.

List or tuple arguments are assembled out of S-expression lists. If an argument expects a list of integers, (1 23 456) will become a Python list of length three. Types are checked carefully; (1 xyzzy) in the same place would raise an exception, because the string xyzzy cannot be interpreted as a Python integer.

A sound argument must be a string in the usual form package/resource. In the examples above, org.boodler.old.clock/clock_cuckoo becomes a sound argument to OneSound. (If that package is available!) You can also use the forms package:versionspec/resource or package::exactversion/resource.

Finally, we have soundscape arguments. If an argument expects a soundscape, you can fill in a package.name/Agent string, as usual. You can also fill in a list, of the form (package.name/Agent argument argument...). This creates a soundscape with its own arguments, and passes the entire thing along as the original arguments. The inner arguments are checked in their turn, and so the whole thing is tidily recursive.

Just a couple more special cases. If a soundscape is expected, you can enter a string beginning with a slash. This is looked up with Python's standard module system, rather than the Boodler package collection. You could use /boodle.builtin.TestSoundAgent to locate the class TestSoundAgent in the boodle.builtin module. (This part of the core Boodler engine; it's the agent invoked when you use the --testsound option.)

Finally, if a soundscape is expected, you can also enter the empty list (). This is interpreted as a soundscape which plays nothing and ends immediately. It is, in fact, the same as /boodle.builtin.NullAgent.


Return to Boodler docs index