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

--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.
--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 drivers

Boodler currently offers these drivers:

stdout -- write raw sample output to stdout

Streams data to stdout containing raw PCM sound sample data, two channels, 16 bits per sample, signed (centered at 0), little endian.

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.

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