// Code examples for MixerChannel signal routing tutorial
// H. James Harkins -- dewdrop_world -- [Link]
// code is released under the LGPL, [Link]
[Link];
// gather the players
// The first code block will be required for all examples in this tutorial.
(
SynthDef(\blipDelay, { |outbus, bufnum, t_repan|
var dly, dtime, sig, newdly, bufRate;
sig = [Link](outbus, 2);
// this technique is borrowed from MultiTap
[Link]([Link](sig) * 0.7, bufnum, 0, run:-1);
bufRate = [Link](bufnum);
dtime = 0;
dly = [Link](3, { |i|
dtime = dtime + rrand(0.5, 2);
dly = [Link](1, bufnum, -1, startPos:dtime * bufRate, loop:1);
[Link]([Link](dly, 5000 - (i*2000)),
[Link](-1.0, 1.0, t_repan), (i+3).reciprocal);
});
[Link](outbus, dly)
}).send(s);
SynthDef(\blipdrop, { |out, freq, freqdrop, dur, trigStart, trigEnd, bufnum|
var trig, tfreq, amp, timeScale, osc, pan;
trig = [Link]((tfreq = [Link](trigStart, trigEnd, dur))
+ [Link](12, tfreq * 0.8, tfreq));
amp = [Link](Env(#[0, 1, 0.8, 0], #[0.01, 4, 4].normalizeSum), 1,
timeScale:dur,
doneAction:2);
pan = [Link](0.8, 0.8);
freq = freq * [Link](1.2, 0.2, add: [Link](1, freqdrop, dur));
osc = [Link](bufnum, [Link](freq, trig), 0, amp);
[Link](out, [Link]([Link](trig, 0.01, 0.08) * osc, pan));
}).send(s);
// other resources needed by the synthdefs
~dlybuf = [Link](s, 6.05 * [Link], 1);
~oscbuf = [Link](s, 4096, 1)
.sine2(({ |i| rrand(3-i, 6-i) + (i+2).reciprocal.rand2 } ! 4), (1..4).reciprocal);
)
// Now we can start with the MixerChannel.
// the channel: postSendReady is in anticipation of a later section
~chan = MixerChannel(\blippy, s, 2, 2, postSendReady:true);
// play some synths every so often
(
r = Task({
{ ~[Link](\blipdrop, [\freq, rrand(1000, 2000), \freqdrop, rrand(0.4, 0.7),
\dur, rrand(6, 10), \bufnum, ~[Link],
\trigStart, rrand(1.1, 1.4), \trigEnd, rrand(7.0, 10)]);
rrand(5, 12).wait;
}.loop;
}).play;
)
// At this point the sound is pretty dry. Let's add the delay:
~dlysynth = ~[Link](\blipDelay, [\bufnum, ~[Link], \t_repan, 1]);
// Before continuing, let's pause the routine.
[Link];
//////////////////////////////////////////////////
// Master fader
~master = MixerChannel(\master, s, 2, 2, level:1);
// how to create a mixer channel whose output goes to the master fader
~chan2 = MixerChannel(\blippy, s, 2, 2, postSendReady:true, outbus:~master);
// how to re-route a channel's output to the master
~[Link] = ~master;
//////////////////////////////////////////////////
// how to do feedback loops
~dly = MixerChannel(\dly, s, 2, 2, level:1, postSendReady:true);
~src = MixerChannel(\src, s, 2, 2);
~[Link](~dly, 1); // this is explained in the next section
~[Link]({ |out|
// read later synths playing on the delay bus
[Link](~[Link], 2)
});
// one second delay with slight amplitude reduction
~[Link]({ |out| [Link]([Link](out, 2), 1, 1, 0.98) });
(
// source synths follow InFeedback in the execution chain
~[Link](\blipdrop, [\freq, rrand(1000, 2000), \freqdrop, rrand(0.4, 0.7),
\dur, rrand(6, 10), \bufnum, ~[Link],
\trigStart, rrand(1.1, 1.4), \trigEnd, rrand(7.0, 10)]);
)
// cleanup from this example
[~dly, ~src].do(_.free);
//////////////////////////////////////////////////
// auxiliary sends
// execute this only if you didn't create the master earlier
~master = MixerChannel(\master, s, 2, 2, level:1);
// restart the routine
[Link];
// reverb channel, feeding into the master
~rvbmc = [Link]("chn rvb", s, 2, 2, outbus:~master);
// play the reverb as an effect
~rvb = ~[Link]({ |out|
var numChan, maxDelay, preDelay, decay, numRefl, random;
var sig, new, dlys;
#numChan, maxDelay, preDelay, decay, numRefl, random = #[2, 0.181, 0.08,
4, 8, 0.1];
sig = [Link](out, numChan);
new = sig;
dlys = [Link](numRefl, {
new = [Link](new, maxDelay,
[Link](numChan, { [Link] }) + preDelay, decay);
});
[Link](dlys * [Link](numRefl, 1, (numRefl+1).[Link]))
});
// create the send, enabling the reverb
~send = ~[Link](~rvbmc, 0.41);
// more fun with the send
~[Link] = 0;
~[Link](0.8, 40); // fade it in slowly over 40 seconds
[Link];
//////////////////////////////////////////////////
// Signal routing with the mixing board GUI
// If you haven't run the first block of code in this tutorial, do it now.
// first clear the old channels, to remove previous relationships
[~chan, ~rvbmc, ~master].do(_.free);
// recreate resources and restart routine
(
~master = MixerChannel(\master, s, 2, 2, level:1);
~chan = MixerChannel(\blippy, s, 2, 2, postSendReady:true);
~rvbmc = [Link]("chn rvb", s, 2, 2);
~dlysynth = ~[Link](\blipDelay, [\bufnum, ~[Link], \t_repan, 1]);
~rvb = ~[Link]({ |out|
var numChan, maxDelay, preDelay, decay, numRefl, random;
var sig, new, dlys;
#numChan, maxDelay, preDelay, decay, numRefl, random = #[2, 0.181, 0.08,
4, 8, 0.1];
sig = [Link](out, numChan);
new = sig;
dlys = [Link](numRefl, {
new = [Link](new, maxDelay,
[Link](numChan, { [Link] }) + preDelay, decay);
});
[Link](dlys * [Link](numRefl, 1, (numRefl+1).[Link]))
});
[Link];
)
// make the GUI
~board = MixingBoard("demo", nil, ~chan, ~rvbmc, ~master);
// the rest of the steps here are in the HTML document
// to view the current state of the board:
~[Link];
// stop the routine before closing the mixer window
[Link];