Boodler: Building Packages

Say you've created a bootest directory which contains a working soundscape called Example. (And if you followed the previous chapter of this manual, you do.) How do you turn it into a .boop package? Easy:

boodle-mgr --import create bootest

Type that, and you'll see this output:

Package created: /home/zarf/com.example.bootest.1.0.boop

(The .boop file will be created in the same directory as you put the bootest folder, actually.)

The boodle-mgr script is for package management, and its "create" command scans a package directory, figures out what's in it, and creates a .boop package.

(The --import option is necessary, for security reasons. Not-yet-implemented security, at that. See the documentation for the create command. Or, just use it and don't fret about why.)

This newly-created .boop file can be installed, same as any .boop that you download:

boodle-mgr install /home/zarf/com.example.bootest.1.0.boop

(Fill in the actual location of the .boop you created, of course.)

You can now play the Example soundscape without using the --external option:

boodler com.example.bootest/Example

Now that you've installed it, Boodler is able to locate the package in your collection. It is no longer relying on the contents of the bootest directory. You could even delete the bootest directory if you wanted. But you shouldn't, because we're going to keep updating it throughout this manual.

Metadata

The creation process figured out that the package name was com.example.bootest. How? By looking in the Metadata file that you created. That contained a line of the form:

boodler.package: com.example.bootest

You can add other lines to specify other information about your package. For example, if you added this line:

boodler.version: 1.1

...then you would be defining version 1.1 of your package. The "create" command would then create a file named com.example.bootest.1.1.boop.

You will usually want to specify your own name in the Metadata file, and perhaps other bibliographic information. You would add lines like these:

dc.creator: Andrew Plotkin
dc.title: Example plinking module

The "dc." prefix refers to "Dublin Core", a common standard for metadata. (In contrast, the "boodler." lines are information that control Boodler's behavior.)

These are the most common "dc." terms:

There are many more Dublin Core metadata terms, but the ones listed here are most useful for Boodler packages. When you browse packages on the Boodler web site, you are seeing their metadata information.

Resources

You've defined a title for your package. But you should also define a title for each soundscape in the package. You do this by creating a Resources file in your bootest directory. Create a file with that name, containing these lines:

:Example
dc.title: Example soundscape

Resources is rather like Metadata, except that it's divided into sections, one for each resource you want to describe. (A resource is a sound or a soundscape that will go into the package.) A line beginning with a colon is the start of a section. In this case, we have just one section, giving the Example soundscape a title.

Try running the soundscape:

boodler --external bootest com.example.bootest/Example

We've gone back to using the --external option, because we want to pick up the changes you just made to the bootest directory. You'll see this output:

16:20:43 (root) located external package: com.example.bootest 1.0
16:20:44 (root) Running "Example soundscape"

Boodler displays your soundscape title, instead of "unnamed agent".

(Yes, you could put any Dublin Core metadata terms into a Resources file. But you usually only need the dc.title. That's because, usually, all the soundscapes have the same dc.creator and so on. If you don't specify a term in the Resources file, the value in the Metadata file is assumed to apply. If you want to put a different modification date on each soundscape, or some such, feel free.)

Building a package with sound resources

You can put sounds, as well as soundscapes, into packages. (You've probably figured this out, given all the sound packages you've installed.) Boodler's native sound formats are AIFF, WAV, and AU.

(Yes, MP3 and Ogg would be nice. But Python doesn't support those formats out of the box, so decoding them would make Boodler harder to build. It would also be slow. Maybe a future version of Boodler will support them.)

It's generally best practice to keep sounds and soundscapes in separate packages. That way, another package can import your sounds without worrying about your soundscapes -- or vice versa.

So, create a second package directory named bootest2. Give it a Metadata file with only this line:

boodler.package: com.example.bootest2

You don't want a boodler.main line, because that defines the location of a Python source file, and this package won't have one.

Now copy some AIFF or WAV files into bootest2.

You have to be careful about filenames, though. A Boodler sound resource must have a Python-legal name. That means letters, digits, and underscores only (and it can't begin with a digit). No other punctuation, except for the ".aiff", ".wav", or ".au" suffix.

Say you've found a foop.aiff file that you want to incorporate into Boodler. Copy it into bootest2.

You now have a valid Boodler package directory. You can use the standard sound-playing tool, org.boodler.play/OneSound, to play it. Type this (all on one line):

boodler --external bootest2 org.boodler.play/OneSound
    com.example.bootest2/foop

Notice what's going on here. We use the --external option to load in the com.example.bootest2 package. That's not where the OneSound agent is -- just where the foop resource can be found. OneSound comes from the org.boodler.play package, which you should have installed already (from the Boodler site).

The argument to OneSound is the full name of the sound resource we want to play: com.example.bootest2/foop. That's available because of the --external option. So it works; the sound plays.

You can define a Resources file for sounds, just as you can for soundscapes:

:foop
dc.title: A foop-like noise

If you put several sounds in the package (which you typically will), you'd have one section per sound resource, each beginning with a line beginning with a colon.

A package with both sounds and soundscapes

I said you generally don't want to do this. But let's pretend that you do, for the sake of documentation.

Copy your foop.aiff into the bootest directory. We'll make that sound directly accessible from the Python code in main.py.

from boopak.package import *
from boodle import agent

bexport()

class Example(agent.Agent):
    def run(self):
        self.sched_note(foop)

The new feature here is the bexport() call. What this means is, look through the sound files in the package directory, and make each one a sound resource in the package. Each one also becomes a variable in the code itself. In this case, we have a resource com.example.bootest/foop which can be referred to from other packages, and a value foop that can be used inside the package. (Which the sched_note call does.)

In sound-only packages -- packages with no Python source -- this resource-exporting process is automatic. You only need the bexport() call when you have Python code and sound files in the same package.

(In fact, you can use bexport() to control which sound files get turned into resources. But we don't need to worry about that here.)

Next...

Tricks with soundscape channels.


Designing Soundscapes

Return to Boodler docs index