// @title rhythmTracker.ck // @author Brent Townshend // @note amplitude/spectrum tracking using UAna ugens // track amplitude for triggering of an instrument // frequency will track centroid of the input spectrum FFT fft; 0=>int liveInput; SndBuf snd; if (liveInput) { adc.chan(0) => fft; adc.chan(0) => WvOut w2 => blackhole; "rhythm1-in.wav"=>w2.wavFilename; } else { "moneyL.wav"=>snd.read; snd => fft; //snd => Binaural4.input[0]; } fft =^ RMS rms => blackhole; fft =^ Centroid cent => blackhole; // setup FFT: choose high-quality transform parameters 2048 => fft.size; 0.5 => float hop; second / samp => float srate; // actual audio graph and parameter setting // NOTE: gain 'g' prevents direct connection bug if (me.args() && me.arg(0)=="1") { snd => Gain g => Binaural4.input[0]; 0.1=>g.gain; } 0=>int done; // Create a set of instruments with slightly different thresholds, and pitches each a fifth higher 12=>int ninstr; for (0=>int j;j int c1; Shakers instr => Gain g1 => Binaural4.input[c1]; instr => Gain g2 => Binaural4.input[(c1+1)%4]; // Instrument [ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] @=>int ilist[]; instr.preset(ilist[id]); Math.cos(azimuth-c1*Math.PI/2)=>g1.gain; Math.sin(azimuth-c1*Math.PI/2)=>g2.gain; <<<"Id ",id,", azim=",azimuth,", c1=",c1," g1=",g1.gain(),", g2=",g2.gain()>>>; // initial gain 5.0 => instr.gain; 1.0 => instr.energy; 1.0=>instr.objects; // Parameters for mapping amplitude in dB to note-on trigger 65=>float maxdb; mindb=>float thresh; // instantiate a smoother to smooth tracker results (see below) Smooth sma, smf; // set time constant: shorter time constant gives faster // response but more jittery values sma.setTimeConstant((fft.size() * 2)::samp); smf.setTimeConstant((fft.size() * 1)::samp); smf.setNext(60); // main inf-loop while(~done) { // hop in time by overlap amount (fft.size() * hop)::samp => now; // then we've gotten our first bufferful // compute the FFT and RMS analyses rms.upchuck(); rms.fval(0) => float a; Math.rmstodb(a) => float db; Math.min(maxdb, db) => db; if (db>thresh) { // Fire a note (smf.getLast()*fscale => Std.ftom) $int => int note; <<