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.
--output driver
oss
on Unix, osxaq
on MacOSX 10.5 or later, or macosx
on MacOSX through 10.4.--list-drivers
--output
option.--device device
--list-devices
--rate soundrate
--master volume
--hardware
--define opt
--define opt=val
--verbose
--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
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
--stats interval
--data directory
~/Library/Application Support/Boodler
. On Linux or Windows, it will be a ~/.boodler
folder.--collection directory
Collection
subdirectory of the --data
folder (given above). There is generally no reason to change this.--external directory
--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.--listen
--port port
--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
--prop=opt
--prop=opt=val
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
--data
option.$BOODLER_COLLECTION
--collection
option.$BOODLER_PROPERTIES
--prop
option. To set several properties, set this variable to a comma-separated list of opt
or opt=val
.$BOODLER_SOUND_PATH
$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 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
--define end=big
--define end=little
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
--define end=little
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 hwbuffer=frames
--define periodsize=frames
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
--define end=big
--define end=little
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
--define connect=none
--define connect=output
--define connect=all
--define end=big
--define end=little
osxaq
-- MacOSX AudioQueueThis is the default output driver on MacOSX 10.5 and later. It is also compatible with the iPhone OS.
--define buffercount=count
--define buffersize=size
--define end=big
--define end=little
macosx
-- MacOSX CoreAudioThis is the default output driver on MacOSX 10.4 and earlier. (It works on 10.5, but is deprecated.)
--define buffercount=count
--define buffersize=size
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
--define quality=val
shout
-- Shoutcast or Icecast sourceThis generates an Ogg Vorbis stream, and sends it to a Shoutcast or Icecast server (using libshout).
--define shout-server=name
--define shout-port=port
--define shout-user=name
--define shout-password=password
--define shout-mount=mount
--define shout-protocol=type
--define quality=val
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
--define quality=val
--define fast
--define abr=rate
--define haste=val
Boodler soundscape arguments are specified in a slightly addled S-expression syntax. (S-expressions are the building blocks of Lisp. (Expect parentheses.))
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.
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.
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
.