// name: gliss.ck // desc: tuned plucked string filter // author: Ge Wang (gewang@cs.princeton.edu) // feedforward Noise imp => OneZero lowpass => PoleZero allpass; // feedback allpass => Delay delay => lowpass; // hook up to dac allpass => PoleZero dcr => dac; // our radius .999995 => float R; // our order float L; // our starting pitch 80 => float pitch; // our order Std.mtof(pitch) => setFreq; // place zero -1 => lowpass.zero; // block zero .99 => dcr.blockZero; // fire excitation .75 => imp.gain; // for one delay round trip L::samp => now; // done 0 => imp.gain; // advance time (Math.log(.0001) / Math.log(R))::samp + now => time later; // go! while( now < later && pitch < 128 ) { setFreq( Std.mtof( pitch ) ); .001 +=> pitch; 1::ms => now; } // set freq fun float setFreq( float freq ) { // sample rate second / samp => float SR; // omega 2 * pi * freq / SR => float omega; // figure total delay needed SR / freq - .5 => float D; // the integer part D $ int => int Di; // the fraction D - Di => float Df; // set allpass polePos( Df, omega ) => float a; // go a => allpass.allpass; // our delay order Di => L; // set delay L::samp => delay.delay; // set dissipation factor Math.pow( R, L ) => delay.gain; return Di $ float; } // find pole location from delay fun float polePos( float D, float omega ) { // here it is return Math.sin( (1-D) * omega / 2 ) / Math.sin( (1+D) * omega / 2 ); }