// ************ tether setup **************** // float tether1[3]; float tether2[3]; 0 => int footbutton; // ************ Voice Model Basics ********** // // sub patch SndBuf glot => TwoZero t => TwoZero t2 => OnePole p; "special:glot_pop" => glot.read; // built-in glottal pop! 1.0 => t.b0; 0.0 => t.b1; -1.0 => t.b2; // set two zero filters 1.0 => t2.b0; 0.0 => t2.b1; 1.0 => t2.b2; 0.95 => p.pole; .5 => p.gain; // set one pole parameters // formant filters p => TwoPole f1 => Gain g; p => TwoPole f2 => g; p => TwoPole f3 => g; // the rest Noise n => t; 0.0 => n.gain; // Noise source for whispers g => JCRev r => dac; 0.03 => r.mix; r => Gain g2 => WvOut w => blackhole; 0.3 => g2.gain; "TetherSing.wav" => w.wavFilename; // see formant filter parameters 0.997 => f1.radius => f2.radius => f3.radius; 1.0 => f1.gain; 0.8 => f2.gain; 0.6 => f3.gain; 1 => int notDone; spork ~ getTether(); // some globals 400.0 => float f1freq; 1000.0 => float f2freq; 2800.0 => float f3freq; 400.0 => float target_f1freq; 1000.0 => float target_f2freq; 2800.0 => float target_f3freq; 100.0 => float freq => float target_freq; (44100.0 / freq) :: second => dur pitchPer; spork ~ doImpulse(); spork ~ rampStuff(); while (notDone) { if (tether1[0] < -0.1) 0.05 * (-0.1 - tether1[0]) => n.gain; else 0.0 => n.gain; if (tether1[1] < -0.1) 0.5 * (-0.1 - tether1[1]) => glot.gain; else 0.0 => glot.gain; (1.0-tether1[2])*300.0 + 5.0 => target_freq; (44100.0 / target_freq) :: samp => pitchPer; // [-.5 to .5,-.5 to .5,.6 to -.4] range we want to use of formant tether if (tether2[0] < -0.5) -0.5 => tether2[0]; if (tether2[0] > 0.5) 0.5 => tether2[0]; if (tether2[1] < -0.5) -0.5 => tether2[1]; if (tether2[1] > 0.5) 0.5 => tether2[1]; if (tether2[2] < -0.4) -0.4 => tether2[2]; if (tether2[2] > 0.6) 0.6 => tether2[2]; 0.5 + tether2[0] => tether2[0]; 0.5 + tether2[1] => tether2[1]; 0.6 - tether2[2] => tether2[2]; 250.0 + 600.0*tether2[0] => target_f1freq; 800.0 + 2000.0*tether2[1] => target_f2freq; 2200.0 + 1100.0*tether2[2] => target_f3freq; // <<< target_freq, freq, pitchPer >>>; 30 :: ms => now; } // source generation fun void doImpulse() { while( notDone ) { 0 => glot.pos; pitchPer => now; } } fun void rampStuff() { // interpolation 0.010 => float slew; // rate of target acquisition 0.005 => float slew2; // rate of target acquisition while( notDone ) { (target_f1freq - f1freq) * slew + f1freq => f1freq => f1.freq; (target_f2freq - f2freq) * slew + f2freq => f2freq => f2.freq; (target_f3freq - f3freq) * slew + f3freq => f3freq => f3.freq; (target_freq - freq) * slew2 + freq => freq; 0.0025::second => now; } } //tether input fun void getTether() { Hid hi; HidMsg msg; 0 => int device; if( me.args() ) me.arg(0) => Std.atoi => device; if( !hi.openJoystick( device ) ) me.exit(); <<< "joystick '" + hi.name() + "' ready", "" >>>; while( notDone ) { 30::ms => now; // hi => now; while( hi.recv( msg ) ) { if( msg.isAxisMotion() ) // joystick axis motion { //<<< "joystick axis", msg.which, ":", msg.axisPosition >>>; if ( msg.which == 0 ) msg.axisPosition => tether1[0]; else if( msg.which == 1 ) msg.axisPosition => tether1[1]; else if( msg.which == 2 ) msg.axisPosition => tether1[2]; else if( msg.which == 3 ) msg.axisPosition => tether2[0]; else if( msg.which == 4 ) msg.axisPosition => tether2[1]; else if( msg.which == 5 ) msg.axisPosition => tether2[2]; // <<< tether1[0], tether1[1], tether1[2], tether2[0], tether2[1], tether2[2] >>>; } else if( msg.isButtonDown() ) // joystick button down { 1 => footbutton; <<< "joystick button", msg.which, "down" >>>; //footbutton_call(footbutton_state); // pedalhit.signal(); } else if( msg.isButtonUp() ) // joystick button up { 0 => footbutton; <<< "joystick button", msg.which, "up" >>>; //footbutton_call(footbutton_state); } } } }