boodle.generator
index
boodle/generator.py

generator: A module containing various workhorse classes, used deep
in the heart of Boodler.
 
Generator -- stores the internal state of Boodler sound generation
Channel -- for creating hierarchical trees of sounds and agents
FrameCount -- represents a time (or duration) measured in sound frames
 
run_agents() -- the big function that does everything

 
Modules
       
StringIO
bisect
boodle
boodle.listen
logging
boodle.sample
boodle.stereo
sys
traceback

 
Classes
       
boodle.BoodlerError(exceptions.Exception)
BoodleInternalError
ChannelError
ScheduleError
Channel
FrameCount
Generator

 
class BoodleInternalError(boodle.BoodlerError)
    BoodleInternalError: Represents an internal sanity check going
wrong.
 
 
Method resolution order:
BoodleInternalError
boodle.BoodlerError
exceptions.Exception
exceptions.BaseException
__builtin__.object

Data descriptors inherited from boodle.BoodlerError:
__weakref__
list of weak references to the object (if defined)

Methods inherited from exceptions.Exception:
__init__(...)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature

Data and other attributes inherited from exceptions.Exception:
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T

Methods inherited from exceptions.BaseException:
__delattr__(...)
x.__delattr__('name') <==> del x.name
__getattribute__(...)
x.__getattribute__('name') <==> x.name
__getitem__(...)
x.__getitem__(y) <==> x[y]
__getslice__(...)
x.__getslice__(i, j) <==> x[i:j]
 
Use of negative indices is not supported.
__reduce__(...)
__repr__(...)
x.__repr__() <==> repr(x)
__setattr__(...)
x.__setattr__('name', value) <==> x.name = value
__setstate__(...)
__str__(...)
x.__str__() <==> str(x)

Data descriptors inherited from exceptions.BaseException:
__dict__
args
message
exception message

 
class Channel
    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.
 
Public methods and fields:
 
parent -- the parent of the channel (None if root)
get_root_channel() -- return the root channel of the tree
set_volume() -- change the volume of the channel
set_pan() -- change the channel to a new pan position
stop() -- stop the channel immediately
get_prop() -- get a property from this channel
has_prop() -- see whether this channel has a given property
set_prop() -- set a property on this channel
del_prop() -- delete a property from this channel
 
Internal methods:
 
realstop() -- do the work of stopping the channel
close() -- shut down the channel
addnote() -- note that a note has been added to the channel
remnote() -- note that a note has been removed from the channel
 
Class method:
 
compare() -- compare two channels in deepest-to-root order
 
  Methods defined here:
__init__(self, parent, gen, createagent, startvol, pan)
__str__(self)
addnote(self)
addnote() -> None
 
Note that a note has been added to the channel.
 
Internal method. (Called from sample.queue_note.)
close(self)
close() -> None
 
Shut down the channel. This presumes that all notes, agents, and
subchannels have already been deleted.
 
Internal method. (This is called both from the explicit stop list,
and from the regular check for channels with no more stuff
scheduled.)
del_prop(self, key)
del_prop(key) -> None
 
Delete a property from this channel. If none is set, this has no
effect.
 
Note that this does not affect parent channels. So get_prop(key)
may still return a value after del_prop(key).
get_prop(self, key, default=None)
get_prop(key, default=None) -> any
 
Get a property from this channel. If none is set, see if one is
inherited from the parent. If there is no inherited value either,
return None, or the given default.
 
Note that None is a legal property value. To distinguish between
no property and a property set to None, use has_prop().
get_root_channel(self)
get_root_channel() -> channel
 
Return the root channel of the tree.
has_prop(self, key)
has_prop(key) -> bool
 
See whether this channel has a given property. If none is set, see
if one is inherited from the parent.
realstop(self)
realstop() -> None
 
Do the work of stopping the channel. This deletes all notes
in the channel (and its subchannels), and all agents, and then
closes all the subchannels. Finally it closes the channel itself.
 
Internal method. (The stop() method queues this up in stoplist.)
remnote(self)
remnote() -> None
 
Note that a note has been removed from the channel.
 
Internal method. (Called from the callback to cboodle.create_note.)
set_pan(self, newpan, interval=0.5)
set_pan(newpan, interval=0.5) -> None
 
Change the channel to a new pan position. This affects all notes
in the channel and any subchannels.
 
The position is specified relative to the parent. A value of 0
(or None, or stereo.default()) places the channel in the same
position as its parent. A positive number shifts it to the right
of the parent; a negative number shifts it left. The value may
also be any object created by the stereo module.
 
The change begins immediately, and occurs smoothly over the
interval given (in seconds). If no value is given, the interval
defaults to 0.5 (half a second). You should not use a shorter
interval; it may not be rendered correctly, particularly for
large changes.
 
Due to the way the stereo code is written (a cheap and dirty hack),
two stereo 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_pan() calls for your
sound effects. Set pan positions on individual notes instead, or
else create several channels.
set_prop(self, key, val)
set_prop(key, val) -> None
 
Set a property on this channel.
set_volume(self, newvol, interval=0.0050000000000000001)
set_volume(newvolume, interval=0.005) -> None
 
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.
stop(self)
stop() -> None
 
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.

Static methods defined here:
compare(ch1, ch2)
compare(ch1, ch2) -> int
 
Compare two channels in depth order. Sorting a list of channels
with this comparison function will put the deepest ones first,
the root last.

Data and other attributes defined here:
logger = None
ordinal = 0

 
class ChannelError(boodle.BoodlerError)
    ChannelError: Represents an invalid use of a channel.
 
 
Method resolution order:
ChannelError
boodle.BoodlerError
exceptions.Exception
exceptions.BaseException
__builtin__.object

Data descriptors inherited from boodle.BoodlerError:
__weakref__
list of weak references to the object (if defined)

Methods inherited from exceptions.Exception:
__init__(...)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature

Data and other attributes inherited from exceptions.Exception:
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T

Methods inherited from exceptions.BaseException:
__delattr__(...)
x.__delattr__('name') <==> del x.name
__getattribute__(...)
x.__getattribute__('name') <==> x.name
__getitem__(...)
x.__getitem__(y) <==> x[y]
__getslice__(...)
x.__getslice__(i, j) <==> x[i:j]
 
Use of negative indices is not supported.
__reduce__(...)
__repr__(...)
x.__repr__() <==> repr(x)
__setattr__(...)
x.__setattr__('name', value) <==> x.name = value
__setstate__(...)
__str__(...)
x.__str__() <==> str(x)

Data descriptors inherited from exceptions.BaseException:
__dict__
args
message
exception message

 
class FrameCount
    FrameCount: Represents a time (or duration) measured in a fixed
number of sound frames. A frame is a group of values, one for each
channel. (For a mono sound file, therefore, a frame is the same as
a sample value.) When you see a sound rate like 44100 Hz, that's
measuring frames per second.
 
FrameCount objects can be passed as the delay (or duration) value
for sched_note(), etc. However, you should only do this when you
need exact-frame scheduling. A soundscape which uses FrameCount
values will come out different on different computers, because
not all audio devices play at the same frame rate. Boodler normally
compensates for this, but if you use FrameCounts, you are bypassing
that compensation.
 
FrameCount(frames) -- constructor.
 
The argument should be an integer (or long) number of frames. No
range-checking is done at constructor-time.
 
  Methods defined here:
__init__(self, frames)

 
class Generator
    Generator: A class that stores the internal state of Boodler
sound generation.
 
Everything in this class is private to Boodler.
 
Interesting fields:
 
(Note that sets are implemented as dicts, where only the keys are
significant. It may be worth changing to Python sets, or it may
not.)
 
queue -- list of [runtime, agent, handler] lists. Sorted by
    runtime (and, insignificantly, by the other list values).
    These are not tuples because we have to update the runtime in
    place occasionally.
rootchannel -- the root channel object
channels -- set of channels in existence
 
allhandlers -- set of all active handler objects
listeners -- list of sources of external events
postqueue -- list of events received from external sources. These
    are handled at the beginning of the next run cycle
 
loader -- the package loader
 
Internal methods:
 
close() -- shut down the generator object
select_time() -- determine the schedule time represented by a value
select_duration() -- determine the duration represented by a value
set_stats_interval() -- set the interval at which stats are dumped
addagent() -- put an agent on the schedule queue
remagent() -- remove an agent from the schedule queue
addhandler() -- add a Handler object to the system
remhandlers() -- remove a list of Handler objects from the system
sendevent() -- process an event on the given channel
dump_stats() -- write statistical information to the given file
 
  Methods defined here:
__init__(self, basevolume=0.5, stdinlisten=False, netlisten=False, listenport=None, loader=None)
addagent(self, ag, chan, runtime, handle)
addagent(ag, chan, runtime, handle) -> None
 
Put an agent on the schedule queue. The arguments are the channel,
the scheduled time to run, and the function to call at that
time. (handle is commonly ag.run.)
 
A given agent can only be on the queue once.
addhandler(self, han)
addhandler(han) -> None
 
Add a Handler object to the system. This sets up listening (and
channel holds) as described by the Handler.
close(self)
close() -> None
 
Shut down the generator object and any resources it has open.
(This does not, however, shut down the cboodle module. The
caller must do that.)
dump_stats(self, fl=None)
dump_stats(fl=sys.stdout) -> None
 
Write statistical information to the given file or stream.
remagent(self, ag)
remagent(ag) -> None
 
Remove an agent from the schedule queue. This does not check whether
it's on the queue first.
 
(When agents reach the front of the queue and are played, they
aren't removed through this method. That's separate code in
run_agents().)
remhandlers(self, hans)
remhandlers(hans) -> None
 
Remove a list of Handler objects from the system. This shuts
down listening and releases held channels.
 
It is safe for a Handler to appear more than once in the list.
select_duration(self, duration)
select_duration(duration) -> long
 
Determine the duration represented by a value. Typically this is
a number (in seconds). It may also be a FrameCount object.
 
This should only be called from Agent methods used by agent run()
code.
 
Raises ScheduleError for illegal values.
select_time(self, delay)
select_time(delay) -> long
 
Determine the schedule time represented by a value. Typically this 
is a number (in seconds), measured from the current agentruntime.
It may also be a FrameCount object.
 
This should only be called from Agent methods used by agent run()
code. (Outside of run() time, the agentruntime is not set.)
 
Raises ScheduleError for illegal values.
sendevent(self, ev, chan)
sendevent(ev, chan) -> None
 
Process an event on the given channel. This invokes all the
listeners which are paying attention to the event.
set_stats_interval(self, val)
set_stats_interval(val) -> None
 
Set the interval (in seconds) at which stats are dumped to the
logger. Pass None to turn stats off.

 
class ScheduleError(boodle.BoodlerError)
    ScheduleError: Represents an invalid use of the scheduler.
 
 
Method resolution order:
ScheduleError
boodle.BoodlerError
exceptions.Exception
exceptions.BaseException
__builtin__.object

Data descriptors inherited from boodle.BoodlerError:
__weakref__
list of weak references to the object (if defined)

Methods inherited from exceptions.Exception:
__init__(...)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature

Data and other attributes inherited from exceptions.Exception:
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T

Methods inherited from exceptions.BaseException:
__delattr__(...)
x.__delattr__('name') <==> del x.name
__getattribute__(...)
x.__getattribute__('name') <==> x.name
__getitem__(...)
x.__getitem__(y) <==> x[y]
__getslice__(...)
x.__getslice__(i, j) <==> x[i:j]
 
Use of negative indices is not supported.
__reduce__(...)
__repr__(...)
x.__repr__() <==> repr(x)
__setattr__(...)
x.__setattr__('name', value) <==> x.name = value
__setstate__(...)
__str__(...)
x.__str__() <==> str(x)

Data descriptors inherited from exceptions.BaseException:
__dict__
args
message
exception message

 
Functions
       
run_agents(starttime, gen)
run_agents(starttime, gen) -> None
 
The big function that does everything. This is called regularly from
inside the cboodle module. Its task is to push notes into the note
queue, and also manage everything required to do that -- agents,
channels, listeners, etc.
 
Raises StopGeneration when the soundscape is over (i.e., when all
channels have expired).

 
Data
        TRIMOFFSET = 13230000
TRIMTIME = 26460000
UNLOADAGE = 10000000
UNLOADTIME = 1323000
cboodle = <boodle.DummyDriver>