# Boodler: Playing Soundscapes

First, make sure you have downloaded Boodler and installed it. (See Installing Boodler.) This command should play a little test melody:

    boodler.py --testsound

If that doesn't work, none of the rest of this will.

## Installing packages

Aside from that one test sound, all Boodler sounds and soundscapes are found in packages, which you must download and install from the Boodler web site. The package collection is at http://boodler.org/lib/.

If you take a look, you'll see a long list of files ending with ".boop". (For "Boodler package", right?) For example, `org.boodler.play.1.0.boop` indicates a package named "org.boodler.play", version 1.0. Package names look like reverse domain names (or like Java package names). This makes it easy for people to add new packages without accidentally choosing the same name. `org.boodler` packages are core Boodler code; `com.eblong.zarf` packages were created by your humble servant. (To be sure, I also wrote the `org.boodler` packages. But I keep a distinction between work I do as part of the Boodler engine and Boodler soundscapes that I design.)

A package can contain sound samples, soundscapes, or both. But to facilitate sharing, most packages contain only one or the other. So when you want a soundscape package, you will typically have to download both that package and the sound packages it relies on.

(Some future version of Boodler will figure out these dependencies, find all the required packages, and download them automatically. Until that's written, though, you'll have to do it manually. We apologize.)

You download packages using the `boodle-mgr.py` script. To begin with, try this:

    boodle-mgr.py install http://boodler.org/lib/org.boodler.old.crow.1.0.boop

This is a sound package, a collection of squawking crow samples. (It's filed in `org.boodler.old` because it was part of the sound library for Boodler version 1. I reorganized all those samples into `org.boodler.old` packages.)

You should see this output:

    Loading....
    Package: org.boodler.old.crow    Version: 1.0
    Title: Original Boodler crow collection

You have now downloaded and installed the package named `org.boodler.old.crow`. The files have been stashed in your home directory. On a Mac, this will be in `~/Library/Application Support/Boodler`. On Linux or Windows, it will be a `~/.boodler` folder.

Now install the soundscape which uses these crow samples:

    boodle-mgr.py install http://boodler.org/lib/com.eblong.zarf.crows.1.0.boop

The `com.eblong.zarf.crows` package contains two soundscapes. Here's how to run the one named `ParliamentOfCrows`:

    boodler.py com.eblong.zarf.crows/ParliamentOfCrows

You always run `boodler.py` by naming a package, followed by a slash, followed by the name of a soundscape in that package. You should hear a continual (and non-repeating!) stream of squawking noises. The soundscape will continue to play until you kill it, by hitting ctrl-C.

If you see a "package directory does not exist" error, then you didn't install one or the other of these packages. Install them both, and the soundscape should play.

## Managing your packages

The `boodle-mgr.py` script can do much more than download packages. It is a complete toolkit for managing your package collection. Try this:

    boodle-mgr.py list

The "list" command shows all the packages you have installed. You should see:

       com.eblong.zarf.crows
       org.boodler.old.crow
    2 packages installed (ignoring multiple versions)

See the `boodle-mgr.py` reference for complete documentation of `boodle-mgr.py`. But it's worth mentioning a few tricks here:

The "contents" command shows the contents of an installed package:

    boodle-mgr.py contents com.eblong.zarf.crows

This will list the sounds and soundscapes ("agent" means a soundscape) in that package:

    Package: com.eblong.zarf.crows    Version: 1.0
    Resources: 2
       ParliamentOfCrows [agent]
       SomeCrows [agent]

The "describe" command shows metadata about a package: title, author, licensing, what packages it requires. The "delete" command, unsurprisingly, deletes a package. The "help" command lists all the available `boodle-mgr.py` commands.

You can install a ".boop" file that you have saved locally, as well as installing by URL. You could have installed the `org.boodler.old.crow` package by downloading http://boodler.org/lib/org.boodler.old.crow.1.0.boop in your web browser, saving it as a file, and then typing:

    boodle-mgr.py install org.boodler.old.crow.1.0.boop

Finally, `boodle-mgr.py` can be run as an interactive command-line tool. If you simply type `boodle-mgr.py` by itself, you will see a prompt, and you can type any of the above commands:

    Welcome to Boodle-Manager. Type "help" for a list of commands.

    > list
       com.eblong.zarf.crows
       org.boodler.old.crow
    2 packages installed (ignoring multiple versions)

    > describe com.eblong.zarf.crows
    Package: com.eblong.zarf.crows    Version: 1.0
    Metadata entries: 5
       boodler.main: main
       boodler.package: com.eblong.zarf.crows
       boodler.requires: org.boodler.old.crow
       dc.creator: Andrew Plotkin
       dc.title: The crows

    > contents com.eblong.zarf.crows
    Package: com.eblong.zarf.crows    Version: 1.0
    Resources: 2
       ParliamentOfCrows [agent]
       SomeCrows [agent]

    > quit
    <exiting>

## Passing arguments to soundscapes

Some soundscapes take additional options, which you can add to the command line after the soundscape names. If you just want to hear what the creator set up, you don't have to read this section. But options can let you customize your Boodler experience in all sorts of ways.

Here's an example. Install these two packages:

    boodle-mgr.py install http://boodler.org/lib/org.boodler.old.clock.1.0.boop
    boodle-mgr.py install http://boodler.org/lib/com.eblong.zarf.clock.1.0.boop

`Tick` is a very simple soundscape which plays a ticking clock:

    boodler.py com.eblong.zarf.clock/Tick

But this soundscape also accepts a numeric argument, which modifies the speed of the ticking. The default value is 1; higher values speed up the clock, and lower values slow it down. Try:

    boodler.py com.eblong.zarf.clock/Tick 1.3
    boodler.py com.eblong.zarf.clock/Tick 0.7

You can try other values. But be moderate. Lower than 0.2 or higher than 5 will be distorted or difficult to hear.

(This is a simple resampling technique which changes both the pitch and the speed of the sound. Boodler does not offer fancier audio-editing capabilities like changing the pitch while holding the tempo constant.)

In fact the `Tick` soundscape accepts two options. The second is a "pan" argument, which controls where in stereo space the ticking seems to come from. 0 is the center, -1 is the left channel, 1 is the right channel. So:

    boodler.py com.eblong.zarf.clock/Tick 1 0.75

...will generate ticking of the normal speed, but mostly (not entirely) shifted to the right channel. You may have to plug in headphones or stereo speakers to hear this effect.

You may notice that a negative value, for the left channel, doesn't actually work. It generates a confusing "no such option" error. This is because of the way Unix apps parse command-line options. You can work around it by either putting "--" before the soundscape name, or by putting all of the arguments in quotes.

    boodler.py -- com.eblong.zarf.clock/Tick 1 -0.75
    boodler.py "com.eblong.zarf.clock/Tick 1 -0.75"

(Yes, you can give pan values greater than 1 or less than -1. These shift the sound source past the left or right speaker. It will still come from that side, but fainter, because it is "more distant".)

What if you want to specify just the pan value, rather than both numbers? You can often give an argument by name. For example:

    boodler.py com.eblong.zarf.clock/Tick pan=0.75

This gives a rightward stereo shift, as described above, but leaves the speed at the default value (1). The speed argument is called `pitch`, so you could also do:

    boodler.py com.eblong.zarf.clock/Tick pitch=0.75

...to play a slow, center-field sound.

(How do you know what options a soundscape takes, and what they're named? The `Tick` soundscape accepts `pitch` and `pan`, but other soundscapes want different arguments, or none. Unfortunately, there is no current way to do this, except for examining the source code in your package collection. A future version of `boodle-mgr.py` will allow you to examine a soundscape and list its options.)

## Passing sound arguments to soundscapes

We've seen soundscapes make use of sounds from other packages. Some soundscapes accept sounds as arguments. Here's a handy trick; install this package:

    boodle-mgr.py install http://boodler.org/lib/org.boodler.play.1.0.boop

Then try:

    boodler.py org.boodler.play/OneSound org.boodler.old.clock/clock_cuckoo

This plays a "cuckoo" sample from the `org.boodler.old.clock` package you installed above. (If you see an "unable to load" error, go install it.)

The `OneSound` soundscape can play any sound file from any Boodler package you have installed. Use the "contents" command (in `boodle-mgr.py`) to list the packages you have, and explore the sounds that are available. `OneSound` also has `pitch`, `volume`, and `pan` arguments, so you can alter the sounds as you play them:

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

The `org.boodler.play` package has several tools for playing particular sounds. `SoundSequence` lets you play several sounds in a row:

    boodler.py org.boodler.play/SoundSequence org.boodler.old.clock/clock_tick
        org.boodler.old.clock/clock_chime org.boodler.old.clock/clock_cuckoo

(That should be typed all on one line, by the way.)

`RepeatSound` plays a single sound over and over. You could say:

    boodler.py org.boodler.play/RepeatSound org.boodler.old.clock/clock_tick

...and, in fact, this is essentially how the `com.eblong.zarf.clock/Tick` soundscape works.

## Passing soundscapes to other soundscapes

Some soundscapes make use of other soundscapes -- not just sound samples. Some soundscapes accept other soundscapes as arguments. This lets you play all sorts of interesting tricks.

Install these five packages. (You may have already installed the crows from the earlier example.)

    boodle-mgr.py install http://boodler.org/lib/org.boodler.old.crow.1.0.boop
    boodle-mgr.py install http://boodler.org/lib/com.eblong.zarf.crows.1.0.boop
    boodle-mgr.py install http://boodler.org/lib/org.boodler.old.weather.1.0.boop
    boodle-mgr.py install http://boodler.org/lib/com.eblong.zarf.basicwind.1.0.boop
    boodle-mgr.py install http://boodler.org/lib/org.boodler.manage.1.1.boop

The `crows` and the `basicwind` give us a nice assortment of Halloweeny soundscapes:

    boodler.py com.eblong.zarf.crows/ParliamentOfCrows
    boodler.py com.eblong.zarf.basicwind/Windstorm

It would be nice to play the crows and the wind simultaneously. You could learn soundscape design and write a soundscape that blended them -- and I encourage you to do that. But the capability is already available, in `org.boodler.manage/Simultaneous`:

    boodler.py org.boodler.manage/Simultaneous
        com.eblong.zarf.crows/ParliamentOfCrows
        com.eblong.zarf.basicwind/Windstorm

(That should be typed all on one line.)

The `Simultaneous` soundscape takes a list of soundscapes as arguments, and plays all of them. You can even include arguments to the soundscapes on the list:

    boodler.py "org.boodler.manage/Simultaneous
        com.eblong.zarf.crows/ParliamentOfCrows
        (com.eblong.zarf.basicwind/SteadyGale 0.8)"

`SteadyGale` takes a `pitch` argument, and this example lowers it to 0.8. The parenthesized list wraps up the soundscape and its arguments, and presents them to `Simultaneous` as a unit. Sadly, Unix treats parentheses specially, so you have to quote all the arguments, or use a lot of backslashes. (The "--" trick won't work here.)

Some other varied examples:

    boodler.py org.boodler.manage/Sequential 6 8 2
        com.eblong.zarf.crows/ParliamentOfCrows
        com.eblong.zarf.basicwind/Windstorm

As you might expect, `Sequential` plays several soundscapes in sequence -- in this case, it alternates between the crows and the wind. The numeric arguments tell it to switch every 6 to 8 seconds, with a two-second crossfade.

    boodler.py org.boodler.manage/Limit com.eblong.zarf.basicwind/Windstorm

`Limit` plays a soundscape for a limited time -- 30 seconds, by default -- and then cuts it off. (Notice that when all soundscapes have ended, Boodler shuts down by itself.)

    boodler.py org.boodler.manage/Limit com.eblong.zarf.basicwind/Windstorm 10 5

The two arguments are the length of time to play, and a fadeout time (in seconds).

    boodler.py org.boodler.manage/VolumeModulateAgent com.eblong.zarf.crows/ParliamentOfCrows delta=0.6

`VolumeModulateAgent` plays another soundscape, but shifts the volume up or down roughly once per minute. If you let this run for several minutes, you'll hear the crows fade in and out a bit.

Return to Boodler docs index