Slave Pianos, A Schema and Historo-Materialist Pro-gnostic, Score (Codes)
// -- Polyphony -------------------------------------------------------------
s.boot;
MIDIClient.init;
m = MIDIOut(0, MIDIClient.destinations.at(0).uid);
"aconnect 128:1 20:0".systemCmd;
// -- Initialize
(
~peaks = {|a|
var r;
r = Array();
(a.size-2).do({|i|
if((a[i+1] > a[i]) && (a[i+1] > a[i+2]), {
r = r.add(i+1);
})
});
r;
};
~binFreqs = {|n, bins|
var w = s.sampleRate / n;
var hw = w / 2;
bins.collect({|i| (i * w) + hw});
};
~fftN = 1024;
~fftB = Buffer.alloc(s,1024);
~oscN = 64;
~freqB = Buffer.alloc(s,~oscN);
~amplB = Buffer.alloc(s,~oscN);
~midiN = 12;
~midiU = 64;
~midiC = 0.9;
~durL = 1.5;
~durR = 2.0;
~waitL = 0.01;
~waitR = 0.05;
~ctlL = 0.01;
)
// -- Run
(
~queryR = Routine({
loop {
~fftB.getn(0, ~fftN, { |b|
var c, d, e, f, g, h, i;
c = b.clump(2).flop;
d = [Signal.newFrom(c[0]), Signal.newFrom(c[1])];
e = Complex(d[0], d[1]);
f = e.magnitude;
g = ~peaks.value(f);
h = ~binFreqs.value(~fftN,g).copyRange(0,~oscN);
i = g.collect({|i| f[i]}).copyRange(0,~oscN) * 0.01;
if(~midiC.coin, {
~midiN.do({
var j = ~midiU.rand, p = h[j].cpsmidi;
m.noteOn(0, p, i[j]*128);
})});
~freqB.setn(0,h);
~amplB.setn(0,i);
});
rrand(~waitL,~waitR).yield;
}
}).play;
~analysisS = {
FFT(~fftB.bufnum, AudioIn.ar(1));
0.0;
}.play;
~synthesisS = {
var m = Mix.fill(~oscN,{|i|
var f, a;
f = Lag.kr(BufRd.kr(1, ~freqB.bufnum, i, 0, 1), ~ctlL);
a = Lag.kr(BufRd.kr(1, ~amplB.bufnum, i, 0, 1), ~ctlL);
SinOsc.ar(f,(pi*2).rand)*a;
});
Pan2.ar(
m + (AudioIn.ar(1) * 0.25),
LFNoise0.kr(~waitR.reciprocal),
0.5).clip2(1.0);
}.play;
)
// -- Modify
(
~midiN = 12;
~midiU = 64;
~midiC = 0.9;
~durL = 1.5;
~durR = 2.0;
~waitL = 0.5;
~waitR = 0.5;
~ctlL = 0.01;
m.allNotesOff(0);
)
// -- Shutdown
(
~queryR.stop;
~analysisS.free;
~synthesisS.free;
~fftB.free;
~freqB.free;
~amplB.free;
)
// -- All notes off
m.allNotesOff(0);
// -- Copy audio
{Out.ar(0,AudioIn.ar(2))}.play