How do Events get their defaults?

You can do this:

Event.parentEvents.default[\play].def.sourceCode

It’s intimidating to dig into the source code if you’re not used to it - but for Event, I would suggest trying to make the leap. Event is extremely powerful, but there’s really no straightforward way of harnessing all of the details without looking at the code once in a while - I promise learning how to look things up in the Event source will pay off :slight_smile:

A good place to start is the makeParentEvents method. This is where all of the defaults for the various kinds of Events are defined. There are a few important pieces here…


Partial events are defined starting with the line partialEvents = ( . These provide default values for different use cases - these aren’t used directly - rather they are just ways of breaking up functionality into smaller related pieces, and are combined together for parentEvents later on. For example, you have:

ampEvent: (
	amp: #{ ~db.dbamp },
	db: -20.0,

…which tells you that anything using ampEvent has a default \db of -20, and by default gets it’s \amp value based on that db.

Later on, in Event.sc you’ll see things like ().putAll(partialEvents.pitchEvent ..., which is where these partial events are mixed together into a parentEvent.

The most important partial event is playerEvent - it’s worth looking at the function it defines for it’s play key. This is the function that will be called in 95% of cases when you do Event:play. Importantly, this function looks up an event type in the \type key and calls the associated function - so the \type defines the real behavior for Event:play, the stuff in playerEvent[\play] just defines some high level logic. It also does some under-documented things, like called ~finish before ~play (this lets you define a \finish function in your event to set any final values, or e.g. do a postln before playing).


Event types are defined starting with the line eventTypes: ( .
These ONLY specify what happens when Event:play is called, and are looked up using the \type key of the event (see playerEvent above). So, an event like (type: \breakfast).play will look up and call playerEvent[\play], which will in turn call eventTypes[\breakfast][\play]. Note that you can get roughly the same behavior by just specifying a \play key in your event as well.

You can add your own event types using the addEventType method - this is useful if you want some special play behavior that you’ll re-use in many places. Once you do Event.addEventType(\breakfast, { "eggs and bacon".postln }), you can then trigger your custom \play function any time you have (type: \breakfast).

The critical event type is the default one, \note - this is the code that’s executed for common note-playing event scenarios. This gives you a detailed picture of exactly how an Event is actually turned into a synth playing on the server, where arguments come from, etc etc.


Parent events are events intended to be used as parents for a whole stream. They are defined starting with the line parentEvents = ( . In almost every conceivable case, the default event will be used, but there are two main places where different parentEvent’s might become useful.

There is one place where you would generally use these: when specifying a custom event type via addEventType, the third argument is a parentEvent. This will used as a parent when playing any Event of this \type. For example:

Event.addEventType(
	\breakfast,
	func: { ~items.postln }, 
	parentEvent: (
		items: ["eggs", "bacon"]
	)
);
Pbind(
	\type, \breakfast
).play;

Now, type: \breakfast stands in for both a play function AND a whole set of default keys.


I would highly encourage keeping Event.sc open while working with patterns, and using it at least for reference when you’re not sure of something. It’s hairy, but once you have an idea of what to look for, it’s not so bad.
And, the Event:addEventType workflow is a fantastic way to nail down common Event behaviors that you use often, in a way that’s simple and keeps your code clean. These days I usually define a new event type for any (non-trivial) instrument - I can specify default values, custom calculations, and whatever else I might need to use for it (even things like voicing behavior!).

(wrote this while making lunch, sorry for the food references, I’m hungry!)

4 Likes