SuperCollider Basics
We went through the history of SC a bit and then discussed the structure
of SC3 overall (the client-server model) and the smalltalk-like
language used to do SC-stuff. Most of this is covered by the
SC3 tutorials available (links below), so I won't repeat it here.
Links
Class Downloads
I didn't really keep a running set of SC source-code docs for what I did
in class, but here are the notes I used while presenting things (most of
them I modified slightly during the presentation; they are by-and-large
taken from the SC tutorials linked above):
"Hello World!".postln;
f = { "Function evaluated".postln; };
f; vs. f.value; <- but only to lang
f = { 3.0.rand; }
f = { arg a, b; a + b; }; vs. f = { |a, b| a + b; };
// variable declarations
f vs fff
~variable = something. Yet Another...
( ) enclosure (with var fff; declare it)
// comments
/* comments */
-------
{ SinOsc.ar(440, 0, 0.2); }.play;
kr:
(
{ var ampOsc;
ampOsc = SinOsc.kr(0.5, 1.5pi, 0.5, 0.5);
SinOsc.ar(440, 0, ampOsc);
}.play;
)
also vars and args
show nested
two SinOscs separated by commas -- 2 chans
arrays
{ PinkNoise.ar(0.2) + SinOsc.ar(440, 0, 0.2) + Saw.ar(660, 0.2) }.scope;
.plot
{ [SinOsc.ar(440, 0, 0.2), SinOsc.ar(442, 0, 0.2)] }.play;
s.scope;
SynthDefs
//first the Function
{ SinOsc.ar(440, 0, 0.2) }.play;
// now here's an equivalent SynthDef
SynthDef.new("tutorial-SinOsc", { Out.ar(0, SinOsc.ar(440, 0, 0.2)) }).play;
do not need the "new"; very rarely used in real SC code
x = { SinOsc... }
y = SynthDef("...", { ... }).add;
x.free;
y.free;
// first with a Function. Note the random frequency each time 'play' is called.
f = { SinOsc.ar(440 + 200.rand, 0, 0.2) };
x = f.play;
y = f.play;
z = f.play;
x.free; y.free; z.free;
// Now with a SynthDef. No randomness!
SynthDef("tutorial-NoRand", { Out.ar(0, SinOsc.ar(440 + 200.rand, 0, 0.2)) }).add;
x = Synth("tutorial-NoRand");
y = Synth("tutorial-NoRand");
z = Synth("tutorial-NoRand");
x.free; y.free; z.free;
.add .load .play .send
(
// a synthdef browswer
SynthDescLib.global.read;
SynthDescLib.global.browse;
)
(
// 3 arguments (controls) with default values
SynthDef(
"withControls",
{ arg freq = 440, beatFreq = 1, mul = 0.22;
Out.ar(
0,
SinOsc.ar([freq, freq+beatFreq], 0, mul)
)
}).add;
)
// items in the array are passed to the controls in Synth when it's created
z = Synth("withControls", [\freq, 440, \beatFreq, 1, \mul, 0.1]);
// evaluate this line after the synth is running to reset its controls
z.set(\freq, 700, \beatFreq, 2, \mul, 0.2);
Synth("withControls", [\freq, 440, \beatFreq, 0.5, \mul, 0.1]);
Synth("withControls", ["freq", 440, "beatFreq", 0.5, "mul", 0.1]);
[ controlName, value, controlName, value, controlName, value].
Synth("withControls", [0, 440, 1, 1, 2, 0.1]);
In this case, the pattern is
[ controlIndex, value, controlIndex, value, controlIndex]. (from orig def)
(
SynthDef("resetMyControls", { arg freq = 440, mul = 0.22;
Out.ar(
0,
SinOsc.ar([freq, freq+1], 0, mul)
)
}).add;
)
~aSynth = Synth("resetMyControls", [\freq, 440, \mul, 0.06]);
~aSynth.set(\freq, 600, \mul, 0.25);
(or var aSynth; // variables without the '~' MUST first be declared!!)
s.queryAllNodes
Synth.head()
Synth.tail()