View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide

STK Physical Models

Home   How To   Code Pool   Public Library   Theory   Events
based on STK 4.1.3 source code by Perry R. Cook and Gary P. Scavone, 1995 - 2002.

SynthDef(\flute, { arg out=0, gate=1, freq=440, amp=1.0, endReflection=0.5, jetReflection=0.5, jetRatio=0.32, noiseGain=0.15, vibFreq=5.925, vibGain=0.0, outputGain=1.0;

	var adsr = (amp*0.2) + EnvGen.ar(Env.adsr(0.005, 0.01, 1.1, 0.01), gate, doneAction: 2);
	var noise = WhiteNoise.ar(noiseGain);
	var vibrato = SinOsc.ar(vibFreq, 0, vibGain);

	var delay = (freq*0.66666).reciprocal;
	var lastOut = LocalIn.ar(1);
	var breathPressure = adsr*Mix([1.0, noise, vibrato]);
	var filter = LeakDC.ar(OnePole.ar(lastOut.neg, 0.7));
	var pressureDiff = breathPressure - (jetReflection*filter);
	var jetDelay = DelayL.ar(pressureDiff, 0.025, delay*jetRatio);
	var jet = (jetDelay * (jetDelay.squared - 1.0)).clip2(1.0);
	var boreDelay = DelayL.ar(jet + (endReflection*filter), 0.05, delay);
	LocalOut.ar(boreDelay);
	Out.ar(out, 0.3*boreDelay*outputGain);
}).store;

SynthDef(\blowbotl, { arg out=0, amp=1.0, freq=440, rq=0.0, gate=1, noise=0.0, vibFreq=5.2, vibGain=0.0;
	var lastOut = LocalIn.ar(1);
	var adsr = amp*EnvGen.ar(Env.adsr(0.005, 0.01, 1.0, 0.010), gate, doneAction: 2);
	var vibrato = SinOsc.ar(vibFreq, 0, vibGain);
	var pressureDiff = (adsr+vibrato) - lastOut;
	var jet = (pressureDiff * (pressureDiff.squared - 1.0)).clip2(1.0);
	var randPressure = WhiteNoise.ar(noise)*adsr*(1.0 + pressureDiff);
	
	var resonator = Resonz.ar(adsr+randPressure - (jet*pressureDiff), freq, rq);
	LocalOut.ar(resonator);
	Out.ar(out, LeakDC.ar(resonator));
}).store

SynthDef(\bowed, { arg out=0, amp=1.0, gate=1, freq=420, bowOffset = 0.0, bowSlope = 0.5, bowPosition = 0.75, vibFreq=6.127, vibGain=0.0;
	var betaRatio = 0.027236 + (0.2*bowPosition);
	var baseDelay = freq.reciprocal;
	var lastOut = LocalIn.ar(2);
	var vibrato = SinOsc.ar(vibFreq, 0, vibGain);
	var neckDelay = baseDelay*(1.0-betaRatio) + (baseDelay*vibrato);
	var neck = DelayL.ar(lastOut[0], 0.05, neckDelay);
	var bridge = DelayL.ar(lastOut[1], 0.025, baseDelay*betaRatio);
	var stringFilter = OnePole.ar(bridge*0.95, 0.55);
	var adsr = amp*EnvGen.ar(Env.adsr(0.02, 0.005, 1.0, 0.01), gate, doneAction: 2);
	var bridgeRefl = stringFilter.neg;
	var nutRefl = neck.neg;
	var stringVel = bridgeRefl + nutRefl;
	var velDiff = adsr - stringVel;
	var slope = 5.0 - (4.0*bowSlope);
	var bowtable = (( ((velDiff+bowOffset)*slope) + 0.75 ).abs ).pow(-4).clip(0, 1);
	var newVel = velDiff*bowtable;
	LocalOut.ar([bridgeRefl, nutRefl] + newVel);
	Out.ar(out, Resonz.ar( bridge*0.5, 500, 0.85 ) );
}, [\ir, 0,0, 0, 0, 0, 0, 0, 0]).store;

SynthDef(\voicform, { arg out=0, gate=1, freq=440, amp=1.0, voiceGain=1.0, noiseGain=0.0, sweepRate=0.001;
	
	var voiced = Pulse.ar(freq, 0.1, voiceGain);
	var onezero = OneZero.ar(voiced, -0.9);
	var onepole = OnePole.ar(onezero, 0.97 - (amp*0.2));
	var noise = WhiteNoise.ar(noiseGain*0.1);
	var excitation = onepole + noise;

	var ffreqs = Control.names([\ffreq]).kr([770, 1153, 2450, 3140]);
	var fradii = Control.names([\bw]).kr([0.950, 0.970, 0.780, 0.8]);
	var famps = Control.names([\gain]).kr([1.0, 0.355, 0.0355, 0.011]);
	
	var filters = TwoPole.ar(excitation, Lag.kr(ffreqs, sweepRate), Lag.kr(fradii, sweepRate), Lag.kr(famps, sweepRate) );
	
	Out.ar(out, amp*Mix(filters) );
}).store;



Note: you can try using voicform with this class file: Phonemes
Example usage:
x = Synth(\voicform);
x.set(\sweepRate, 0.5);
i=0;

(
    i = i+1;
    a = Phonemes.parameter(i).flop;
    b = Phonemes.gain(i);
    Phonemes.string(i).postln;
    x.setn(\ffreq, a[0]);
    x.setn(\bw, 1-a[1]);
    x.setn(\gain, a[2].dbamp);
    x.set(\voiceGain, b[0]);
    x.set(\noiseGain, b[1]);
    x.set(\freq, exprand(200, 800) );
)


Link to this Page