Boodler: Programming Reference

Herein are described four classes.

Okay, three classes and a module.


Agent: base class for boodler agents


sched_note(sample [, pitch=1, volume=1, delay=0, chan=self.channel]) -> duration

Schedule a note to play. The sound is loaded from the file sample (which is relative to $BOODLER_SOUND_PATH). The pitch is given as a multiple of the sound's original frequency; the volume is given as a fraction of the sound's original volume. The delay is a time (in seconds) to delay before the note is played. The channel, if None or not supplied, defaults to the same channel the agent is running in.

This returns the expected duration of the sound, in seconds.

sched_note_pan(sample [, pan=0, pitch=1, volume=1, delay=0, chan=self.channel]) -> duration

Schedule a note to play, panning the stereo origin of the sound. The pan value defaults to 0, meaning no shift in origin; -1 means all the way left; 1 means all the way right. The value may also be an object created by the stereo module.

The sound is loaded from the file sample (which is relative to $BOODLER_SOUND_PATH). The pitch is given as a multiple of the sound's original frequency; the volume is given as a fraction of the sound's original volume. The delay is a time (in seconds) to delay before the note is played. The channel, if None or not supplied, defaults to the same channel the agent is running in.

This returns the expected duration of the sound, in seconds.

sched_note_duration(sample, duration [, pitch=1, volume=1, delay=0, chan=self.channel]) -> duration

Schedule a note to play, extending the original sound sample to a longer period of time. The duration is given in seconds.

The sound is loaded from the file sample (which is relative to $BOODLER_SOUND_PATH). The pitch is given as a multiple of the sound's original frequency; the volume is given as a fraction of the sound's original volume. The delay is a time (in seconds) to delay before the note is played. The channel, if None or not supplied, defaults to the same channel the agent is running in.

This returns the expected duration of the sound, in seconds. Due to the way sounds are looped, this may be slightly longer than the given duration.

sched_note_params(sample [, param=value, param=value...]) -> duration

Schedule a note to play. This method understands all the arguments used by the other sched_note methods, but they must be supplied as named keywords. The arguments may be in any order. For example: "self.sched_note_params(snd, volume=0.5, pitch=2)"

The valid arguments, and their default values:

post_agent(agent [, chan=self.channel])

Post an agent to watch for events; the agent will be scheduled to run whenever an appropriate event occurs. The channel, if None or not supplied, defaults to the same channel that self is running in.

The posted agent must be an instance of the EventAgent class. It must have a watch_events field, which lists the events which it is interested in. This field must be a string, a list of strings, or a function such that agent.watch_events() return a string or list of strings.

send_event(event)

Send an event. Boodler interprets the event just as if it had been received from the outside world. Any agents that are posted watching for that type of event will run. (Due to the way the scheduler works, there may be a short delay before they run. The delay is not predictable. For reliable scheduling, use sched_agent(), not send_event().)

The event should be a tuple of strings, or a string (which will be split into a tuple at whitespace).

sched_agent(agent [, delay=0, chan=self.channel])

Schedule an agent to run. This may be the current agent (self) or a newly-created agent. The delay is a time (in seconds) to delay before the agent runs. The channel, if None or not supplied, defaults to the same channel that self is running in.

resched([delay, chan=self.channel])

Reschedule the current agent (self). The delay is a time (in seconds) to delay before the agent runs again. The channel, if None or not supplied, defaults to the same channel that self is running in.

If delay is not supplied, it defaults to the delay used when this agent was first scheduled. Note that if this value was zero, you will probably cause an infinite loop.

new_channel([startvolume=1, parent=self.channel]) -> channel

Create a new channel. The startvolume is the volume the channel is initially set to; this will affect all sounds played in the channel and any subchannels. The new channel will be a subchannel of parent -- if None or not supplied, it will be a subchannel of the channel that the agent (self) is running in.

new_channel_pan([pan=stereo.default(), startvolume=1, parent=self.channel]) -> channel

Create a new channel, panning the stereo origin of its sounds. (See the stereo module.) The startvolume is the volume the channel is initially set to; this will affect all sounds played in the channel and any subchannels. The new channel will be a subchannel of parent -- if None or not supplied, it will be a subchannel of the channel that the agent (self) is running in.

get_root_channel() -> channel

Return the root channel of the channel tree.

run()

Perform the agent's action. Each subclass of Agent must override this method.

getname() -> string

Return the name of the agent. This defaults to returning self.name, if that is defined.


EventAgent: base class for boodler agents that listen for events

See Agent class definition for inherited methods and fields.


run()

By default, this calls post_agent(self). In most cases, you will not want to override this.

receive(event)

Perform the agent's action when an appropriate event arrives. Each subclass of EventAgent must override this method. The event is a tuple of one or more strings.

unpost()

Remove self from event-watching post.


Channel: a class for creating hierarchical trees of sounds and agents

Channel objects should be created via Agent.new_channel() and destroyed with the channel.stop() method.
stop()

Stop the channel immediately. All sounds playing in the channel (or any subchannels) are cut off; all sounds and agents scheduled to run are discarded.

If any notes are playing with non-zero volume, their termination may cause undesirable clicks and pops. It is best to set the volume of a channel to zero before stopping it. (The FadeOutAgent class can be used for this.)

Due to the way sound generation is buffered, when an agent calls channel.stop(), the channel may be stopped slightly later than it ought to be.

get_root_channel() -> channel

Return the root channel of the tree.

set_volume(newvolume [, interval=0.005])

Change the volume of the channel to a new level (0 means silence, 1 means full volume). This affects all notes in the channel and any subchannels.

The volume change begins immediately, and occurs smoothly over the interval given (in seconds). If no value is given, the interval defaults to 0.005 (five milliseconds), which is short enough that it will sound instantaneous. (You should not use an interval shorter than 0.005; it can cause undesirable clicks and pops.)

Due to the way the volume code is written (a cheap and dirty hack), two volume changes scheduled too close together on the same channel (within about one second) can interfere with each other. The earlier one may be ignored entirely in favor of the later. Therefore, you should not rely on rapid sequences of set_volume() calls for your sound effects. Set volumes on individual notes instead, or else create several channels.


stereo: a module of stereo pan objects

This is a separate module, not a class of methods. Each function is a top-level function in the module.

These functions are for creating stereo panning description objects. A stereo object is a stereo shift, a contraction, or a combination of these. (See Soundscape Basics.) Stereo objects can be passed to new_channel_pan() or sched_note_pan().

Note that in the current implementation, stereo objects are represented by simple tuples, or by None (for the default stereo position). You should not rely on this remaining true. I may get cleverer in a future release, and re-implement them as a Python class. Use the utility functions.


default() -> stereo

Return a stereo object which describes the default stereo position -- no shift, no contraction.

shift(pos) -> stereo

Return a simple stereo shift. If pos is zero, there is no shift in origin; this returns the default stereo position. -1 means all the way left; 1 means all the way right.

scale(size) -> stereo

Return a stereo effect which is not shifted left or right, but is compressed or stretched from the center. If size is less than 1, the channels are compressed; zero causes every sound to be perfectly centered. If size is greater than 1, the channels are spread apart. Negative values cause the left and right channels to swap.

fixed(pos) -> stereo

Return a stereo effect which is compressed to a point. All sounds contained in this effect, no matter how shifted, will come from a single point. If pos is zero, this will be the center; if -1, the left side; if 1, the right.

fixed(pos) is equivalent to compose(shift(pos), scale(0)). You figure it out.

compose(stereo1, stereo2) -> stereo

Return a stereo effect which is the result of applying of stereo1 on top of stereo2. This is the equivalent of a channel set to stereo1, containing a channel stereo2.

cast(obj) -> stereo

Convert obj into a stereo object. If obj is None, this returns the default stereo position. If obj is a number, this returns a simple stereo shift -- no scaling. If obj is a stereo object, this returns it (or an equivalent object).


Designing Soundscapes

Return to Boodler docs index