1declare name "Nonlinear Banded Waveguide Models"; 2declare author "Romain Michon"; 3declare copyright "Romain Michon (rmichon@ccrma.stanford.edu)"; 4declare version "1.0"; 5declare licence "STK-4.3"; // Synthesis Tool Kit 4.3 (MIT style license); 6declare description "This instrument uses banded pm.waveguide. For more information, see Essl, G. and Cook, P. Banded Waveguides: Towards Physical Modelling of Bar Percussion Instruments, Proceedings of the 1999 International Computer Music Conference."; 7 8import("stdfaust.lib"); 9 10bow(offset,slope) = pow(abs(sample) + 0.75, -4) : saturationPos 11 with{ 12 sample(y) = (y + offset)*slope; 13 }; 14 15bandPass(resonance,radius) = fi.TF2(b0,b1,b2,a1,a2) 16 with{ 17 a2 = radius*radius; 18 a1 = -2*radius*cos(ma.PI*2*resonance/ma.SR); 19 b0 = 0.5-0.5*a2; 20 b1 = 0; 21 b2 = -b0; 22 }; 23 24saturationPos(x) = x <: (_>1),(_<=1 : *(x)) :> +; 25saturationNeg(x) = x <: (_<-1),(_>=-1 : *(x)) :> *(-1) + _; 26 27//==================== GUI SPECIFICATION ================ 28 29freq = hslider("h:Basic Parameters/synthfreq [1][unit:Hz] [tooltip:Tone frequency]",440,20,20000,1); 30gain = hslider("h:Basic Parameters/gain [1][tooltip:Gain (value between 0 and 1)]",0.8,0,10,0.01)*10; 31gate = checkbox("h:Basic Parameters/gate [1][tooltip:noteOn = 1, noteOff = 0]"); 32 33//==================== MODAL PARAMETERS ================ 34 35preset = 1; 36 37nMode(1) = 4; 38 39modes(1,0) = 1; 40basegains(1,0) = pow(0.9,1); 41excitation(1,0) = 1*gain/nMode(1); 42 43modes(1,1) = 2.756; 44basegains(1,1) = pow(0.9,2); 45excitation(1,1) = 1*gain/nMode(1); 46 47modes(1,2) = 5.404; 48basegains(1,2) = pow(0.9,3); 49excitation(1,2) = 1*gain/nMode(1); 50 51modes(1,3) = 8.933; 52basegains(1,3) = pow(0.9,4); 53excitation(1,3) = 1*gain/nMode(1); 54 55//==================== SIGNAL PROCESSING ================ 56 57//----------------------- Synthesis parameters computing and functions declaration ---------------------------- 58 59//the number of modes depends on the preset being used 60nModes = nMode(preset); 61 62//bow table parameters 63tableOffset = 0; 64tableSlope = 10 - (9); 65 66delayLengthBase = ma.SR/freq; 67 68//de.delay lengths in number of samples 69delayLength(x) = delayLengthBase/modes(preset,x); 70 71//de.delay lines 72delayLine(x) = de.delay(4096,delayLength(x)); 73 74//Filter bank: fi.bandpass filters (declared in instrument.lib) 75radius = 1 - ma.PI*32/ma.SR; 76bandPassFilter(x) = bandPass(freq*modes(preset,x),radius); 77 78//Delay lines feedback for bow table lookup control 79baseGainApp = 0.8999999999999999 + (0.1); 80velocityInputApp = 0.8; 81velocityInput = velocityInputApp + _*baseGainApp,par(i,(nModes-1),(_*baseGainApp)) :> +; 82 83//Bow velocity is controlled by an ADSR envelope 84maxVelocity = 0.03 + 0.1*gain; 85bowVelocity = maxVelocity*en.adsr(0.02,0.005,90,0.01,gate); 86 87//----------------------- Algorithm implementation ---------------------------- 88 89//Bow table lookup (bow is decalred in instrument.lib) 90bowing = bowVelocity - velocityInput <: *(bow(tableOffset,tableSlope)) : /(nModes); 91 92//One resonance 93resonance(x) = + : + (excitation(1,x)*gate) : delayLine(x) : _*basegains(1,x) : bandPassFilter(x); 94 95/*process = 96 //Bowed Excitation 97 _<:((bowing <: 98 //nModes resonances with nModes feedbacks for bow table look-up 99 (resonance(1)~_))~_);*/ 100 101process(x) = 102 //Bowed Excitation 103 (bowing <: 104 //nModes resonances with nModes feedbacks for bow table look-up 105 par(i,nModes,(resonance(i)~_)))~par(i,nModes,_) :> _ : +(x) :_; 106