View this PageEdit this Page (locked)Uploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide

CountMeIn

Home   How To   Code Pool   Public Library   Theory   Events
/*
* 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


Link to this Page