SuperCollider 1
This entry looks at some code for audio-visual creation in SuperCollider. The code provided below maps some environmental variables to a Korg nanoKontrol2 (or any controller you may want to use). It is a test of the kind of thing you can do with a midi controller, a synthDef and visuals in SuperCollider. You will need to run the midi stuff at the bottom first and then you can run the stuff between the brackets. The synthDef and the Pbind will all be evaluated in that main code block. The code involves mutating some of Supercollider tutorial on the "pen" class.
(
~scale=1;
~motion=0.1;
~penWidth = 1;
~penWidth2 = 0.1;
~change = 0.6;
~dur=0.6;
Server.default.waitForBoot({fork{
var sound,tempo,data,window, userView;
var h = 800, v = 600, seed = Date.seed, phase = 0, zoom = 0.7, zoomf = 1, run = true;
SynthDef(\tr5z,{arg freq=300,filterFreq=400,xcc=440, multer=1.66; var n=5,env;
Mix.fill(n, {arg index; var amp,z,e,za,xcc2;
//index.postln;
xcc=freq*(index+1);
xcc2=freq*(index*multer);
amp=1/(index+1);
z=SinOsc.ar(xcc,0,amp*0.2);
za=SinOsc.ar(xcc2,0,amp*0.2);
e=Resonz.ar((z+za),filterFreq,Line.kr(1,0.5,
5),mul:SinOsc.kr(Line.kr(0.5,4,2)* Line.kr(0.8,0,10)));
env=EnvGen.ar(Env.perc(0.1,0.2,0.4),doneAction:2);
Out.ar(0,Pan2.ar(e*env))})}).add;
//tempo = TempoClock.new(10);
p = Pbind(
\instrument, \tr5z,
\freq, Pwhite(200, 1000,inf),
\xcc, Pwhite(200, 1000,inf),
\filterFreq, Pfunc{~scale*1000},
\multer, Pfunc{~change+0.6},
\dur, Pfunc{~dur}
).collect({ arg event;
data = event;
}).play;
0.5.wait;
{
window = Window("Kwindow",1280@720,false).front;
window.onClose_({
sound.stop;
sound.free;
run = false;
p.stop;
});
userView = UserView(window,1280@720).background_(Color.black).frameRate_(30).clearOnRefresh_(true).animate_(true).drawFunc_({
Pen.use {
var p1 = Point(20.rand2 + (h/2), 20.rand2 + (v/2));
var p2 = Point(20.rand2 + (h/2), 20.rand2 + (v/2));
var xscales = { exprand(2** -0.1, 2**0.1) } ! 2;
var yscales = { exprand(2** -0.1, 2**0.1) } ! 2;
var xlates = { 8.rand2 } ! 2;
var ylates = { 8.rand2 } ! 2;
var rots = { 2pi.rand + phase } ! 2;
var z={~dur*5}!2;
var xform;
xscales = (xscales ++ (z)) * 1;
//xscales.postln;
yscales = (yscales ++ (1/yscales)) * 1;
xlates = xlates ++ xlates.neg;
ylates = ylates ++ xlates.neg;
rots = rots ++ rots.neg;
xform = {|i| [xlates[i], ylates[i], rots[i], xscales[i], yscales[i]] } !~change;
Pen.strokeColor = Color.grey(1, ~penWidth2);
Pen.width = 8.linrand + 1;
Pen.translate(1280/2, 720/2);
Pen.scale(0.1,~dur );
Pen.translate(-1280/2, -720/2);
100.do {
var p, rot, xlate, ylate, xscale, yscale;
Pen.width = ~penWidth;
Pen.beginPath;
#rot, xlate, ylate, xscale, yscale = xform.choose;
Pen.translate(xlate, ylate);
Pen.rotate(rot,h/2, v/2);
Pen.scale(xscale, yscale);
Pen.moveTo(p1);
Pen.lineTo(p2);
Pen.stroke;
};
};
});
//{ while { run } { window.refresh; 0.05.wait; } }.fork(AppClock)
}.defer;
}});
)
MIDIClient.init;
(
MIDIIn.connect(device:1);
MIDIIn.control = { arg src, chan, num, val;
switch(num,
13, {~motion= val.linlin(0, 127, -1, 1)},
14, {~penWidth= val.linlin(0, 127, 1,20)},
15, {~dur = val.linlin(0, 127, 0.1, 1)},
16, {~scale = val.linlin(0, 127, 0.1, 1)},
17, {~penWidth2 = val.linlin(0, 127, 0.1,0.5)},
18, {~change = val.linlin(0, 127, 0.6,1.0)}
);}
)
Below is a screen capture of the piece running. Not pictured are the twiddling of the knobs on the nanoKontrol - you can imagine that as it plays.