/* * 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