PR(\defTrig)


Like defPerc, this process generates rhythms based on user defined synthdefs. In defPerc, however, the synthdef is expected to produce one percussive note and release itself when it's finished. PR(\defTrig) is for synthdefs that should run continuously, and respond to rhythmically occurring triggers. This is useful for sounds that should fluctuate briefly when triggered, or for effects that should be connected to a pulse.


As in defPerc, the ~objects array provides the synthdefs. Each synthdef should have a t_trig argument, which will receive the value from the ~amps array on every note. Because of the prefix t_, the argument is "trigger rate," meaning that when its value is changed, it will hold the new value for one control cycle (the same duration as Impulse.kr) and then fall immediately back to zero so that it can be retriggered on the next /n_set message. (So, if you want to use the trigger value as an amplitude scaler, you should latch it: Latch.kr(t_trig, t_trig).)


For every item in the objects array, one synth node is created when you play the process. Where PR(\defPerc) used the ~defs array to choose which synthdef to play, here, the same array chooses which node to trigger. Only one node can trigger at one time.


The synthdef may also include a gate argument for the final release when the process stops. If the gate argument is absent, the synth will be killed brutally with /n_free, which could result in audio clicks. Better practice generally is to include a master envelope in the synth with a gate argument for a smooth release.


Example


// Using defTrig as an effect.

// Since is an effect, it should play on the source MixerChannel.

// So, we create the MixerChannel externally and pass it in via the ~chan parameter.

// (The process knows that it didn't create the mixer, so it leaves it alone on .free!)


s.boot;

TempoClock.default.tempo = 2;


m = MixerChannel(\source, s, 1, 2);


a = m.play({

Klank.ar(`[

{ rrand(500.0, 1200.0) } ! 5,

{ rrand(0.5, 1.0) } ! 5,

{ rrand(0.4, 0.8) } ! 5

], PinkNoise.ar(0.05))

});

a.free;


(

PR(\defTrig).chuck(BP(\ex1), parms: (

chan: m,

isFx: true, // otherwise the synths will be regular sound sources

objects: [

// because isFx == true, this will use ReplaceOut instead of Out

{ |outbus, t_trig, gate = 1|

// trigger controls wet/dry so you will hear the effect spike in and out

// master envelope is also here

var wet = Decay2.kr(t_trig, 0.01, 0.15)

* EnvGen.kr(Env.asr(0.1, 1, 0.1), gate, doneAction: 2),

sig = In.ar(outbus, 1),

ringfreq = TExpRand.kr(100, 1000, t_trig),

sig2 = sig * SinOsc.ar(ringfreq);

XFade2.ar(sig, sig2, wet * 2 - 1)

}

],

// just a fixed rhythm here

amps: #[1, 0, 0, 0, 1, 0, 0, 0.6, 0, 0.8, 0, 0, 0.9, 0, 0, 0]

));

)


BP(\ex1).play;

BP(\ex1).stop;

BP(\ex1).free;


a.free;

m.free;