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

Slave Pianos, A Schema and Historo-Materialist Pro-gnostic, Score (Codes)

// -- Monophony -------------------------------------------------------------

s.boot;
MIDIClient.init;
m = MIDIOut(0, MIDIClient.destinations.at(0).uid);
"aconnect 128:1 20:0".systemCmd;

// -- Setup

(
~fftB = Buffer.alloc(s, 2048, 1);
~sfB  = Buffer.new(s);
~sfB.allocRead("tyndall/slave-guitars.snd");
~hainsL = 1.1;
~waitT = 0.05;
~quietL = 21;
~durL = 1.5;
~durR = 3.0;
~loudL = 110;
~rpr = {|n, t|
	var i = In.kr(n,2);
	TRand.ar(i[0], i[1], t);
};
~randC = {
	var c = (1..4);
	switch (c.choose)
		{1} {
			s.sendMsg("c_setn", 0, 12, 
				rrand(0.005, 0.025), rrand(0.05, 0.15),
				rrand(0.75, 0.95),   rrand(1.05, 1.25),
				rrand(0.01, 0.05),   rrand(0.05, 0.175),
				rrand(0.1, 0.2),     rrand(0.2, 0.4),
				rrand(0.2, 0.45),    rrand(0.55, 0.8),
				rrand(-1.0, 0.0),    rrand(0.0, 1.0));
		}
		{2} {
			s.sendMsg("c_setn", 0, 12, 
				rrand(0.01, 0.025),  rrand(0.05, 0.25),
				rrand(0.75, 0.95),   rrand(1.05, 1.25),
				rrand(0.001, 0.01),  rrand(0.02, 0.04),
				rrand(0.1, 0.2),     rrand(0.2, 0.4),
				rrand(0.0, 0.45),    rrand(0.55, 1.0),
				rrand(-0.1, 0.0),    rrand(0.0, 1.0));
		}
		{3} {
			s.sendMsg("c_setn", 0, 12, 
				rrand(0.001, 0.015), rrand(0.015, 0.025),
				rrand(0.85, 0.95),   rrand(1.05, 1.15),
				rrand(0.001, 0.01),  rrand(0.01, 0.035),
				rrand(0.1, 0.2),     rrand(0.2, 0.4),
				rrand(0.35, 0.45),   rrand(0.55, 0.85),
				rrand(-1.0, 0.0),    rrand(0.0, 0.1));
		}
		{4} {
			s.sendMsg("c_setn", 0, 12, 
				rrand(0.05, 0.15),   rrand(0.15, 0.25),
				rrand(0.75, 0.95),   rrand(1.05, 1.25),
				rrand(0.001, 0.01),  rrand(0.02, 0.04),
				rrand(0.2, 0.4),     rrand(0.4, 0.8),
				rrand(0.0, 0.45),    rrand(0.55, 0.65),
				rrand(-0.5, 0.0),    rrand(0.0, 0.5));
		}
};
~trRecv = OSCresponderNode(s.addr, '/tr', 
	{ |time, responder, msg|
		var id = msg[2], nt, lvl;
		if(id==0,
			{
				~randC.value;
				nt = msg[3].cpsmidi;
				lvl = ~loudL;
			}, {
				nt = msg[3] * 92;
				lvl = ~quietL;
			});
		m.noteOn(0, nt, lvl);
		{m.noteOff(0, nt, 0);}.defer(rrand(~durL, ~durR));
	}).add;
)

// -- Run

(
~randC.value;
{
	var src, dtc, dtcD, ptc, ptcE, d, clk, rat, dur, pos, pan, amp, syn, b;
	src = AudioIn.ar(1);
	#ptc, ptcE = Pitch.kr(src, ampThreshold: 0.02, median: 7);
	b = ~sfB.bufnum;
	dtc = PV_HainsworthFoote.ar(FFT(~fftB.bufnum, src), ~hainsL, 0.0, 0.75, ~waitT);
	dtcD = TDelay.ar(dtc,4096*SampleDur.ir);
	d = Dseq(Dwhite(In.kr(0),In.kr(1),1),9999);
	clk = dtc + TDuty.ar(d, 0, WhiteNoise.ar.abs, 0);
	rat = ~rpr.value(2, clk);
	dur = ~rpr.value(4, clk);
	pos = ~rpr.value(8, clk) * BufDur.kr(b);
	pan = ~rpr.value(10, clk);
	amp = ~rpr.value(6, clk);
	SendTrig.ar(dtcD, 0, ptc);
	SendTrig.ar(clk, 1, rat);
	Out.ar(0, (src * 0.35) + TGrains.ar(2, clk, b, rat, pos, dur, pan, amp, 2));
}.play;
)

// -- Modify

(
~hainsL = 1.1;
~waitT = 0.05;
~durL = 0.05;
~durR = 0.1;
~quietL = 1;
~loudL = 125;
m.allNotesOff(0);
)

// -- Cleanup

(
~trRecv.remove;
)