[
Cottle examples]
4. Keyword Assignment, MouseX.kr and MouseY.kr, Linear and Exponential values
Keyword Assignment
//4.1 Defaults
// Boot internal server.
s = Server.internal;
s.boot;
// Synth.scope cannot be used as is.
// The { }.scope syntax will be used throughout to focus attention on the syntax features
// under discussion. Remember, { }.play and { }.scope are SHORTCUTS!
{ SinOsc.ar }.scope;
// Linux: Replace .scope with .play throughout this chapter.
//4.2 keywords, indents
// Because the synthesis engine is not a subprocess within the language, it makes no sense
// to instantiate it for a fixed duration. The synth engine runs continuously, and new events
// are created in it at will. Hence the duration argument in Cottle's examples is not valid
// in sc3 and is omitted.
// There are ways to sound a synth for a fixed length of time. These will be covered in later
// chapters.
{ SinOsc.ar(freq: 440, phase: 0, mul: 0.4, add: 0) }.scope;
{ SinOsc.ar(phase: 0, freq: 440, add: 0, mul: 0.4) }.scope;
{ SinOsc.ar(freq: 440, mul: 0.4) }.scope;
// The ugenGraphFunc argument can be used when writing a SynthDef:
(
SynthDef.new(name: "basicSine",
ugenGraphFunc: {
SinOsc.ar(
freq: 440,
phase: 0,
mul: 0.4,
add: 0)
}).play(s);
)
// MouseX.kr and MouseY.kr
// 4.3 MouseX
{ SinOsc.ar(LFNoise0.ar(MouseX.kr(1, 50), 500, 600), mul: 0.5) }.scope;
// 4.4 MouseY
{ SinOsc.ar(440, mul: MouseY.kr(0.9, 0)) }.scope;
// 4.5 MouseX controlling frequency
{ SinOsc.ar(MouseX.kr(220, 880), mul: 0.3) }.scope;
// 4.6 exponential change
{ SinOsc.ar(MouseX.kr(220, 880, 'exponential'), mul: 0.3) }.scope;
// 4.7 Just for fun
// OverlapTexture in sc2 is a kind of Spawn UGen, which creates new UGens on the fly.
// This cannot be done within one SynthDef in sc3.
// Instead, we write the SynthDef(s) for the thing that's going to be spawned,
// and schedule their instantiation.
// Note that what goes inside the Out ugen is essentially the same as what went inside
// the OverlapTexture in sc2. The SynthDef often corresponds to what got spawned in sc2.
// .poll has to be done by latching the signal onto a one-time-only trigger.
// To control the overlap, a fixed-length envelope is used.
(
SynthDef("ch4-ex7", {
var control1, control2; // the controls have to be built in the synthdef
var onetrig;
onetrig = Impulse.kr(0);
control1 = Latch.kr(MouseX.kr(60, 1000, 'exponential'), onetrig);
control2 = Latch.kr(MouseY.kr(60, 5000, 'exponential'), onetrig);
Out.ar(0,
Pan2.ar(
in: SinOsc.ar(
freq: SinOsc.ar(
freq: SinOsc.ar(
freq: rrand(0.1, 20.0),
mul: control1, add: 1.1*control1
),
mul: control2, add: 1.1*control2
),
mul: MouseY.kr(0.12, 0.05)
),
pos: 1.0.rand
) * EnvGen.kr(Env.linen(2, 4, 2), doneAction:2);
// doneAction makes each synth stop itself when the envelope is done.
// This prevents UGens from piling up and choking the server.
// Watch the number of UGens and Synths in the server window for proof!
)
}).send(s);
)
(
r = Routine({
inf.do({ // loop forever (until cmd- or C-c C-s in emacs.)
Synth.new("ch4-ex7", target: s);
2.5.wait; // 2.5 sec between events
});
}).play(SystemClock);
)
// Execute this line when you're sick of it.
r.stop;
// That means new synths will stop being created, and the existing ones will play out
// until they terminate.