-
Karst final SuperCollider code
//Karst
/*
a site-specific performance work for amplified gesture and prosthetic voice featuring Sonnets to Orpheus (Part 2, Number 11) by Rainer Maria Rilke.
*///audio sample available here: http://soundcloud.com/meghatron
//SERVER
(
Server.default = s = Server.internal.boot;
s.waitForBoot({
});
//took out paren to save a step since I have to reboot entirely after every kill
//ARDUINO
//ibid
SerialPort.listDevices;
d = SerialPort.devices[2];
f = SCPyduino.new(d); //declares f an SCPyduino object
)
//NON SEQUENTIAL CLOSE (rather than scrolling to the end, kill SCPyduion here when code block stopped before reboot)
//close the serial port
(
f.close;
)
//KARST MAIN CODE BLOCK
(
//VARIABLES
//synths
var synth, scrape;
//functions
//ACTION - remane these functions and create a 4th, one for each sample
var func, pfunc, ffunc;
//sample variables
var transform, death, machine, noisefloor;
//more joshparametrical magic right here
var flex1, flex2, controlflex1, controlflex2;
//CONTROL
controlflex1 = CtkControl.play;
controlflex2 = CtkControl.play;
//SAMPLES
//Source = Rilke: Orpheus Sonnet pt2 10 “The machine threatens all we have gained, so long as it dare become the tyrant of spirit, rather than its servant.”
machine = CtkBuffer.playbuf(“sounds/Karst_Machine.aif”).load;
//Source = Rilke: Orpheus Sonnet pt2 11 “Many quietly acceptable methods of death have come to pass since onward conquering man first laid claim to the hunter’s arts;….”
death = CtkBuffer.playbuf(“sounds/Karst_Death.aif”).load;
//Source = Rilke: Orpheus Sonnet pt2 12 “Aspire to transform, O enraptured be by the fire wherein something elusive flames with brazen tidings of change;….”
transform = CtkBuffer.playbuf(“sounds/Karst_Transform.aif”).load;
//Source = Site Noisefloor, May 29, 2010
noisefloor = CtkBuffer.playbuf(“sounds/Karst_Noisefloor.aif”).load;
//KILL SWITCH
//actions on CmdPeriod which is triggered by a sensor on pin 5
CmdPeriod.doOnce({
machine.free;
death.free;
transform.free;
noisefloor.free;
a.stop;
b.stop;
c.stop;
g.stop;
h.stop;
k.stop;
Server.killAll;
”I’m freeing the buffers!”.postln;
});
//SYNTHDEFS
// trigger synth
synth = CtkSynthDef(\synth, {arg imp, begin, out = 0, bufnum = 0, pan = 0, amp =0.5, deviation = 0, pch = 1;
var trig, sig, sampstosecs, devAmt, outsig, env;
env = EnvGen.kr(Env.new([0, 1,0], [0.1,0.1], \linear, 1));
trig = Impulse.ar(imp);
sampstosecs = (SampleRate.ir * BufRateScale.kr(bufnum));
devAmt = (deviation * LFNoise1.kr( imp) * sampstosecs);
sig = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum) * pch, trig, (begin * sampstosecs) + devAmt, 0);
outsig = Pan2.ar(sig*amp, pan);
Out.ar(out, [outsig[0], DelayN.ar(outsig[1], 0.002, 0.002)]);
});
//contact mic synth for scraping the walls
scrape = CtkSynthDef(\scrape, { arg bus;
var signal;
signal = SoundIn.ar(bus);
Out.ar(bus,signal*1);
});
scrape.new(0,nil).bus_(0).play;
scrape.new(0,nil).bus_(1).play;
//FUNCTIONS
//FUNC :: for use with impulse triggers
func = {arg duration, amp, rhythms, imps, begs, pans, dev;
var start, now, index, dur, imp, beg, rhy, pan1;
Task({
start = Main.elapsedTime;
now = 0;
index = 0;
imp = imps;
while({
now < duration;
}, {
now = Main.elapsedTime - start;
rhy = rhythms[index%rhythms.size];
imp = imps[index%imps.size];
beg = begs[index%begs.size];
pan1 =pans[index%pans.size];
synth.new(0, nil).bufnum_(noisefloor.bufnum).imp_(4).begin_(beg).pan_(pan1).amp_(amp).deviation_(dev)
.pch_(controlflex1).play;
rhy.wait;
index = index + 1;
})
}).play
};
//PFUNC :: make my func the pfunc
pfunc = {arg duration, amp, rhythms, durs, imps, begs, pans, dev;
var start, now, index, dur, imp, beg, rhy, pan1;
Task({
start = Main.elapsedTime;
now = 0;
index = 0;
imp = imps;
while({
now < duration;
}, {
now = Main.elapsedTime - start;
rhy = rhythms[index%rhythms.size];
dur = durs[index%durs.size];
imp = imps[index%imps.size];
beg = begs[index%begs.size];
pan1 =pans[index%pans.size];
synth.new(0,10).bufnum_(death.bufnum).imp_(4).begin_(beg).pan_(pan1).amp_(amp).deviation_(dev).play;
(rhy + dur).wait;
index = index + 1;
})
}).play
};
//FFUNC :: machine function
ffunc = {arg duration, amp, rhythms, durs, imps, begs, pans, dev;
var start, now, index, dur, imp, beg, rhy, pan1;
Task({
start = Main.elapsedTime;
now = 0;
index = 0;
imp = imps;
while({
now < duration;
}, {
now = Main.elapsedTime - start;
rhy = rhythms[index%rhythms.size];
dur = durs[index%durs.size];
imp = imps[index%imps.size];
beg = begs[index%begs.size];
pan1 =pans[index%pans.size];
synth.new(0, 10).bufnum_(machine.bufnum).imp_(4).begin_(beg).pan_(pan1).amp_(amp).deviation_(dev).play;
(rhy + dur).wait;
index = index + 1;
})
}).play
};
//ARDUINO
//Arduino: Sensors
//Left Piezo ”a” “u” lop
//f.analog[0].active_(1);
//Left Flex ”b” “v” lox
f.analog[1].active_(1);
//Left Force ”c” “w” lor
f.analog[2].active_(1);
//Right Piezo “g” “x” rop
//f.analog[3].active_(1);
//Right Flex ”h” “y” rox
f.analog[4].active_(1);
//Right Force “k” “z” ror
//f.analog[5].active_(1);
/*
//Left Piezo
a = fork{
loop{
var lop;
f.iterate;
u= f.analog[0].value;
”u:”.post;
u.postln;
lop = (1000-u)/100;
”lop: imp: “.post;
lop.postln;
syn1.imp_(lop);
0.001.wait;
}
};
*/
m = 0;
//Left Flex
//3030: this is working, starts inactive, is trigger at first bend and cycles through noisefloor functions, the first of which is pitch affected by sensor value
b = fork{
t = Main.elapsedTime;
loop{
var lox;
f.iterate;
v= f.analog[1].value;
flex1 = v;
//controlflex1.set((flex1 / 500) - 0.5);
controlflex1.set((flex1 / 500) - 0.5);
”v:”.post;
v.postln;
(v > 250).if({
(Main.elapsedTime > (t + 1)).if({
t = Main.elapsedTime;
m = m + 1;
m.postln;
[
//FUNC:::: duration, amp, rhythms, durs, imps, begs, pans, dev;
//duration = duration of the gesture, but may default to 10 seconds
//amp = amp
//rhythms = space between attacks in the gesture
//imps = how ofter the playbuff retriggers; low values = larger chunks o’ audio, inverse relationship means 0.1 = 10 seconds, 10 = .1 seconds
//begs = pickup spot
//pans = pan
//dev = deviation or randomness on the location of the pickup spot
//duration should be longer than rhytms for more than one note
{func.value(30, 0.5, [1],[0.02],[0.1],[0, 1, -1],[2]).play},
{func.value(30, 0.5, [10],[0.4],[0.1],[0, 1, -1],[2]).play},
].wrapAt(m).value;
})
});
0.001.wait;
}
};
/*
//Left Force
c = fork{
loop{
var lor;
f.iterate;
w= f.analog[2].value;
”w:”.post;
w.postln;
lor = 100-w;
”lor: imp: “.post;
lor.postln;
syn3.imp_(lor);
syn3.pan_(lor-80);
syn3.imp_(lor+0.1);
syn3.pan_(lor-90);
0.001.wait;
}
};
//Right Piezo
g = fork{
loop{
var rop;
f.iterate;
x= f.analog[3].value;
”x:”.post;
x.postln;
rop = x-350/100;
”imp “.post;
rop.postln;
0.001.wait;
}
};
*/
n = 0;
//Right Flex
h = fork{
t = Main.elapsedTime;
loop{
var lox;
f.iterate;
y= f.analog[4].value;
flex1 = y;
controlflex2.set((flex1 / 1000) - 0.5);
”y:”.post;
y.postln;
(y > 350).if({
(Main.elapsedTime > (t + 1)).if({
t = Main.elapsedTime;
n = n + 1;
n.postln;
[
{pfunc.value(2, 0.5, [0.25],[0.03],[3],[1],[0, 1, -1],[2]).play},
{ffunc.value(2, 0.5, [0.25],[0.03],[3],[4,5,6,7,8,9],[0, 1, -1],[2]).play},
{ffunc.value(2, 0.5, [0.25],[1],[5],[4,5,6,7,8,9],[0, 1, -1],[2]).play},
{ffunc.value(2, 0.5, [0.25],[3],[3],[4,5,6,7,8,9],[0, 1, -1],[2]).play}
].wrapAt(m).value;
})
});
lox = 250-y;
0.001.wait;
}
};
//Right Force
//Right Force has a yellow wire conencting to the breadboard in prototype layout
k= fork{
loop{
var ror;
f.iterate;
z =0;
z = f.analog[2].value;
”z:”.post;
z.postln;
((z>350) and: {z<1000}).if({
CmdPeriod.run;
});
0.001.wait;
}
};
)
//SEQUENTIAL CLOSE (this is repeated at the top)
//close the serial port
(
f.close;
)