/*
* CountMeIn, by Dan Stowell July 2005
* Published under the Creative Commons licence
* http://creativecommons.org/licenses/by/2.0/
*
* This class lets you speak into the microphone (say "1 2 3 4" for example) and trigger a task to happen on the next beat.
* It will also set the chosen TempoClock's tempo to match your count in.
* It will NOT listen until you set the variable "primed" to true.
*
*
* Save this whole block of code as "CountMeIn.sc" somewhere in your classes folder.
*
* Example of use:
*
* var count;
* // Create the object, passing it a Task (or a Tdef) that I've created earlier
* count = CountMeIn.new(Tdef(\breakbeatTask), tempoMultiply:0.5, verbose:true;)
* // When you're ready to start, run this line
* count.primed_(true);
*
*/
CountMeIn {
var theTask, numBeats, tempoClock,
<>primed, tempoMultiply, s, verbose;
var beattimes, triggerer, triggered, i, beatintervals, launchtime, tempo, eststarttimes;
*new { arg theTask, numBeats=4, tempoClock=TempoClock.default,
primed=false, tempoMultiply=1, s=Server.default, verbose=true;
^super.newCopyArgs(theTask, numBeats, tempoClock, primed, tempoMultiply, s, verbose).init
}
init {
beattimes = Array.newClear(numBeats);
eststarttimes = Array.newClear(numBeats-1);
beatintervals = Array.newClear(numBeats -1);
i = 0;
triggerer = { var in;
in = Amplitude.kr(AudioIn.ar(2), 0.00001, 0.1);
SendTrig.kr(Trig1.kr(
(Slope.kr(in) > 0.5)
&&
(in > 0.5)
, 0.15
), 74, 0)}.play;
triggered = OSCresponder(s.addr, "/tr",
{
if(verbose, {("Received message "+i).postln});
if(primed, {
beattimes[i] = SystemClock.seconds;
// For every click (apart from the very first),
// we can calc an interval and also estimate a start time
if(i != 0, {
beatintervals[i-1] = beattimes[i] - beattimes[i-1];
eststarttimes[i-1] = beattimes[i] + (beatintervals[i-1] * (numBeats - i));
});
i = i + 1;
if(i == beattimes.size,
{
// We must now calculate the tempo and set the launch task
if(verbose, {
(" Beat times: " + beattimes).postln;
(" Beat durs: " + beatintervals).postln;
(" Est starts: " + eststarttimes).postln;
});
// The launch delta would normally be the mean of the recorded intervals
launchtime = beattimes[beattimes.size-1] + beatintervals.mean;
tempo = tempoMultiply / beatintervals.mean;
if(verbose, {
("Launching at " + launchtime).postln;
("Tempo is " + tempo).postln;
});
// Set the launch task
SystemClock.schedAbs(launchtime, {
tempoClock.tempo_(tempo);
theTask.play(tempoClock, quant:0)
});
// Once that's done, kill the triggerer and the responder
triggerer.free;
triggered.remove;
});
}, {if(verbose, {"But ignoring since I'm not primed.".postln;})});
}).add;
} // End of init
} // End of whole class