// real-time processing adc => Pan2 pan => dac; // feedback pan.left => Delay delayL => Gain gL => delayL => dac.left; pan.right => Delay delayR => Gain gR => delayR => NRev r => dac.right; // analysis adc => FFT fft =^ Flux flux => blackhole; // more analysis fft =^ RMS rms => blackhole; // set delay .5::second => delayL.max => delayL.delay; .25 => gL.gain; .2::second => delayR.max => delayR.delay; .5 => gR.gain; .05 => r.mix; // set FFT parameters Windowing.hann( 512 ) => fft.window; 512 => fft.size; 256 => int hopSize; // gain 0 => float gainTarget; // pan target 0 => float panTarget; // rms threshold .000100 => float rmsThreshold; // flux threshold .38 => float fluxThresholdHi; fluxThresholdHi - 0 => float fluxThresholdLo; // spork it spork ~ smooth(); // go while( true ) { // upchuck the flux flux.upchuck() @=> UAnaBlob @ fluxBlob; // upchuck the RMS rms.upchuck() @=> UAnaBlob @ rmsBlob; // examine flux // <<< fluxBlob.fval(0), rmsBlob.fval(0) >>>; // ensure we have high enough RMS if( rmsBlob.fval(0) > rmsThreshold ) { // gain 2 => gainTarget; // check flux if( fluxBlob.fval(0) > fluxThresholdHi ) 1 => panTarget; else if( fluxBlob.fval(0) < fluxThresholdLo ) -1 => panTarget; else 0 => panTarget => gainTarget; } else // center things { 0 => gainTarget; } // hop (hopSize+Std.rand2(-10,10))::samp => now; } // smoothly fun void smooth() { .001 => float slew; while( true ) { // slew it (panTarget - pan.pan())*slew + pan.pan() => pan.pan; (gainTarget - pan.gain())*slew + pan.gain() => pan.gain; // advance time 1::samp => now; } }