Event types


A common question is, "Which parameters have special meanings in Pbind?" Perhaps surprisingly, none of them do! That's because Pbind simply puts data into the result event; it doesn't care what the data are.


The event prototype used when playing the pattern defines the actions to take, and it is here that parameters are defined. Most patterns will play using the default event prototype (Event.default), so this is the source of the parameters that will most typically be used.


The default event prototype defines a number of "event types," each of which performs a different task. The \type key determines which action is taken, and the significant parameters depend on the event type.


There are a lot of event types! However, only a few are commonly used. The \note event type is by far the most typical. The others are auxiliary, and most useful when writing patterns to generate a Score suitable for non-real-time rendering.


Before looking at the event types themselves, let's go over some standard parameters used across many event types. (Not every common parameter is used in every event type, but these turn up in lots of places.)


Common parameters


Timing control


\delta: Number of beats until the next event. Calculated from ~dur * ~stretch, if \delta is not given explicitly.

\lag: Number of seconds to delay the event's server message(s).

\timingOffset: Number of beats to delay the event's server message(s). In conjunction with Quant, this allows control over the order of event preparation between different patterns in the client, without desynchronizing sonic events that should play together. PG_06g_Data_Sharing has an example of its use to pass data from a bass pattern to a chord pattern.


\sustain: Number of beats to wait before releasing a Synth node on the server. The SynthDef must have a 'gate' argument for the explicit release to be sent; otherwise, the pattern assumes the note will release itself using a timed envelope. \sustain is calculated from ~dur * ~legato * ~stretch if not given directly.


Node control


\addAction: How to add a synth or group node relative to the given \group in the event. See Synth.

\amp: Not formally defined as a special parameter, but this is typically used for Synth amplitude. The SynthDef should have an 'amp' argument and use it to control volume. \amp is optionally calculated from \db.

\id: The desired id(s) for newly created Nodes in this event. Normally this is nil, in which case the IDs will be obtained from server.nextNodeID.

\instrument: The SynthDef name for which nodes will be created. Only one name should be given (unlike other arguments, which "multichannel expand" to create multiple nodes).

\group: The target node relative to which new node(s) will be created. Similar to 'target' in Synth(defName, args, target, addAction).

\out: Generally used for the output bus of a Synth. When using Pbus or Pfxb, an audio bus is allocated to isolate the pattern's signal. All events from the pattern receive the new bus number in the \out slot, and SynthDefs being played should use an 'out' argument for the target of output UGens, e.g., Out.ar(out, ...).



Event Types


Node control


rest: As one would expect, a \rest does nothing except wait the required amount of time until the next event.


note: This is the default event type, used when \type is not specified. It plays one or more Synth nodes on the server, with an automatic release after \sustain beats if the SynthDef has a 'gate' argument.


p = Pbind(

// array is "multichannel expanded" into one Synth each

\degree, #[2, 5, 8, 11, 13, 16],

\octave, 3,

\dur, 2,

\sustain, 3,

// non-zero strum staggers the entrances

\strum, 0.12

).play(quant: 2);


p.stop;


on: Start a Synth node (or nodes) without releasing. The node ID(s) are in the event's ~id variable. Those IDs can be used with the off, set and kill event types.


off: Release server nodes nicely if possible. If the SynthDef has a 'gate' argument, the gate will be set to 0 or a user-specified value. Otherwise, the nodes are brutally killed with n_free.


kill: Immediately remove nodes using n_free.


set: Send new values to the control inputs of existing nodes.


There are two ways to specify argument names: by instrument and by argument array.


By instrument:



(

SynthDef(\event_set, { |freq = 440, gate = 1, amp = 0.1, lagTime = 0.1,

ffreq = 2000, detune = 1.005, out = 0|

var sig = Saw.ar(Lag.kr(freq, lagTime) * [1, detune]).sum * amp

* EnvGen.kr(Env.adsr, gate, doneAction: 2);

Out.ar(out, sig ! 2);

}).add;

)


a = Synth(\event_set);


(

p = Pbind(

\type, \set,

\id, a,

\instrument, \event_set,

\args, #[],

\freq, Pexprand(200, 600, inf),

\dur, Pwhite(1, 5, inf) * 0.125

).play;

)


p.stop;

a.free;


By argument names:



a = Synth(\event_set);


(

p = Pbind(

\type, \set,

\id, a,

\args, #[\freq],

\freq, Pexprand(200, 600, inf),

\dur, Pwhite(1, 5, inf) * 0.125

).play;

)


p.stop;

a.free;


monoNote

monoOff

monoSet: These event types are used internally by Pmono and PmonoArtic. They should not be used directly.



Server control


group: Create a new group (or groups).


bus: Set the value of a control bus, or contiguous control buses. This assumes that you already have the bus index.



Buffer control


All of these buffer event types expect the buffer number to be provided. They will not automatically get a buffer number from the server's buffer allocator. A Buffer object is allowed -- you could create the Buffer first using Buffer.alloc or Buffer.new and then use this object in the control events. See also "Event types with cleanup" below for other, user-friendlier Buffer control options.


alloc: Allocate memory for a buffer on the server. Only one buffer may be allocated per event.


free: Deallocate the buffer's memory on the server.


gen: Generate wavetable data in the buffer, using one of the server's b_gen plug-ins. The Buffer help file has more detail on the standard plug-ins.


load: Allocate buffer memory in the server and load a sound file into it, using b_allocRead.


read: Read a sound file into a buffer already allocated on the server. This event type is good to cue a sound file for use with DiskIn.



Event types with cleanup


These event types uniquely have automatic cleanup event types associated with them. Playing one of these event types allocates a server resource. Later, the resource may be freed by changing the event type to the corresponding cleanup type and playing the event again. While the resource is active, the event can be used as a reference to the resource in other events or Synth messaging.


// create a buffer

b = (type: \allocRead, path: "sounds/a11wlk01.wav").play;


a = { PlayBuf.ar(1, b, doneAction: 2) }.play;


// remove buffer

EventTypesWithCleanup.cleanup(b);


See the Pproto example in PG_06f_Server_Control, showing how these can be used to clean up server objects at the end of a pattern.


audioBus: Allocate an audio bus index from the server.


controlBus: Allocate a control bus index from the server.


buffer: Allocate a buffer number if not specified, and reserve the memory on the server.


allocRead: Read a disk file into server memory. The file is closed when finished.


cue: Cue a sound file (generally for use with DiskIn).


table: Fill a buffer with preset data. This uses /b_setn to transfer the data, so all of the data must fit into one datagram. It may take some experimentation to find the upper limit.


cheby: Generate a Chebyshev transfer function for waveshaping.


sine1: Mirrors the sine1 method for Buffer, generating a wavetable with an integer-multiple harmonic spectrum using the given partial amplitudes.


sine2: Like sine1, but the frequency ratio of each partial is also given.


sine3: Like sine2, but the phase of each partial may also be provided.




MIDI output


midi: Sends one of several types of MIDI messages to a MIDIOut object.


Available midicmds














Miscellaneous


phrase: See recursive_phrasing (JITLib).


setProperties: Set variables belonging to a given object. One possible use is to control a GUI using a pattern.

receiver: The object to be modified.


// Visualize Brownian motion

w = Window("Brownian motion", Rect(10, 100, 500, 50));

x = Slider(w, Rect(10, 15, 480, 20));

w.front;


p = Pbind(

\type, \setProperties,

\receiver, x,

// this means, call x.value_() on every event

\args, [\value],

// and look for the value under \value

\value, Pbrown(0, 1, 0.1, inf),

\delta, 0.1

).play;


p.stop;



Previous: PG_07_Value_Conversions

Next: PG_Cookbook01_Basic_Sequencing