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