Rename interpretor to interpreter.
[Faustine.git] / interpreter / preprocessor / faust-0.9.47mr3 / examples / faust-stk / blowHole.dsp
diff --git a/interpreter/preprocessor/faust-0.9.47mr3/examples/faust-stk/blowHole.dsp b/interpreter/preprocessor/faust-0.9.47mr3/examples/faust-stk/blowHole.dsp
new file mode 100644 (file)
index 0000000..af8a4f4
--- /dev/null
@@ -0,0 +1,153 @@
+declare name "BlowHole";
+declare description "Nonlinear WaveGuide Clarinet with one register hole and one tonehole";
+declare author "Romain Michon";
+declare copyright "Romain Michon (rmichon@ccrma.stanford.edu)";
+declare version "1.0";
+declare licence "STK-4.3"; // Synthesis Tool Kit 4.3 (MIT style license);
+declare description "A clarinet model, with the addition of a two-port register hole and a three-port dynamic tonehole implementation, as discussed by Scavone and Cook (1998). In this implementation, the distances between the reed/register hole and tonehole/bell are fixed.  As a result, both the tonehole and register hole will have variable influence on the playing frequency, which is dependent on the length of the air column.  In addition, the highest playing freqeuency is limited by these fixed lengths.";
+declare reference "https://ccrma.stanford.edu/~jos/pasp/Woodwinds.html";
+
+import("music.lib");
+import("instrument.lib");
+
+//==================== GUI SPECIFICATION ================
+
+freq = nentry("h:Basic_Parameters/freq [1][unit:Hz] [tooltip:Tone frequency]",440,20,20000,1);
+gain = nentry("h:Basic_Parameters/gain [1][tooltip:Gain (value between 0 and 1)]",1,0,1,0.01); 
+gate = button("h:Basic_Parameters/gate [1][tooltip:noteOn = 1, noteOff = 0]");
+
+reedStiffness = hslider("h:Physical_and_Nonlinearity/v:Physical_Parameters/Reed_Stiffness 
+[2][tooltip:Reed stiffness (value between 0 and 1)]",0.35,0,1,0.01);
+toneHoleOpenness = hslider("h:Physical_and_Nonlinearity/v:Physical_Parameters/Tone_Hole_Openness
+[2][tooltip:A value between 0 and 1]",0.12,0,1,0.01);
+ventOpenness = hslider("h:Physical_and_Nonlinearity/v:Physical_Parameters/Vent_Openness
+[2][tooltip:A value between 0 and 1]",0,0,1,0.01);
+noiseGain = hslider("h:Physical_and_Nonlinearity/v:Physical_Parameters/Noise_Gain 
+[2][tooltip:Breath noise gain (value between 0 and 1)]",0,0,1,0.01);
+pressure = hslider("h:Physical_and_Nonlinearity/v:Physical_Parameters/Pressure 
+[2][tooltip:Breath pressure (value bewteen 0 and 1)]",0.35,0,1,0.01);
+
+typeModulation = nentry("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Modulation_Type 
+[3][tooltip: 0=theta is modulated by the incoming signal; 1=theta is modulated by the averaged incoming signal;
+2=theta is modulated by the squared incoming signal; 3=theta is modulated by a sine wave of frequency freqMod;
+4=theta is modulated by a sine wave of frequency freq;]",0,0,4,1);
+nonLinearity = hslider("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Nonlinearity 
+[3][tooltip:Nonlinearity factor (value between 0 and 1)]",0,0,1,0.01);
+frequencyMod = hslider("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Modulation_Frequency 
+[3][unit:Hz][tooltip:Frequency of the sine wave for the modulation of theta (works if Modulation Type=3)]",220,20,1000,0.1);
+nonLinAttack = hslider("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Nonlinearity_Attack
+[3][unit:s][Attack duration of the nonlinearity]",0.1,0,2,0.01);
+
+vibratoFreq = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Freq 
+[4][unit:Hz]",5,1,15,0.1);
+vibratoGain = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Gain
+[4][tooltip:A value between 0 and 1]",0.1,0,1,0.01);
+vibratoAttack = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Attack 
+[4][unit:s][tooltip:Vibrato attack duration]",0.5,0,2,0.01);
+vibratoRelease = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Release 
+[4][unit:s][tooltip:Vibrato release duration]",0.01,0,2,0.01);
+
+envelopeAttack = hslider("h:Envelopes_and_Vibrato/v:Envelope_Parameters/Envelope_Attack 
+[5][unit:s][tooltip:Envelope attack duration]",0.01,0,2,0.01);
+envelopeDecay = hslider("h:Envelopes_and_Vibrato/v:Envelope_Parameters/Envelope_Decay 
+[5][unit:s][tooltip:Envelope decay duration]",0.05,0,2,0.01);
+envelopeRelease = hslider("h:Envelopes_and_Vibrato/v:Envelope_Parameters/Envelope_Release 
+[5][unit:s][tooltip:Envelope release duration]",0.1,0,2,0.01);
+
+//==================== SIGNAL PROCESSING ================
+
+//----------------------- Nonlinear filter ----------------------------
+//nonlinearities are created by the nonlinear passive allpass ladder filter declared in filter.lib
+
+//nonlinear filter order (problem with compilation time if order is bigger than 2)
+nlfOrder = 2; 
+
+//attack - sustain - release envelope for nonlinearity (declared in instrument.lib)
+envelopeMod = asr(nonLinAttack,100,envelopeRelease,gate);
+
+//nonLinearModultor is declared in instrument.lib, it adapts allpassnn from filter.lib 
+//for using it with waveguide instruments
+NLFM =  nonLinearModulator((nonLinearity : smooth(0.999)),envelopeMod,freq,
+     typeModulation,(frequencyMod : smooth(0.999)),nlfOrder);
+
+//----------------------- Synthesis parameters computing and functions declaration ----------------------------
+
+//reed table parameters
+reedTableOffset = 0.7;
+reedTableSlope = -0.44 + (0.26*reedStiffness);
+
+//the reed function is declared in instrument.lib
+reedTable = reed(reedTableOffset,reedTableSlope);
+
+// Calculate the initial tonehole three-port scattering coefficient
+rb = 0.0075;    // main bore radius
+rth = 0.003;    // tonehole radius
+scattering = pow(rth,2)*-1 / (pow(rth,2) + 2*pow(rb,2));
+
+// Calculate register hole filter coefficients
+r_rh = 0.0015;         // register vent radius
+teVent = 1.4*r_rh;      // effective length of the open hole
+xi = 0 ;       // series resistance term
+zeta = 347.23 + 2*PI*pow(rb,2)*xi/1.1769;
+psi = 2*PI*pow(rb,2)*teVent/(PI*pow(r_rh,2));
+rhCoeff = (zeta - 2*SR*psi)/(zeta + 2*SR*psi);
+rhGain = -347.23/(zeta + 2*SR*psi);
+ventFilterGain = rhGain*ventOpenness;
+
+// Vent filter
+ventFilter = *(ventFilterGain) : poleZero(1,1,rhCoeff);
+
+teHole = 1.4*rth; // effective length of the open hole
+coeff = (teHole*2*SR - 347.23)/(teHole*2*SR + 347.23);
+scaledCoeff = (toneHoleOpenness*(coeff - 0.9995)) + 0.9995;
+
+//register hole filter using a poleZero filter (declared in instrument.lib)
+toneHoleFilter = *(1) : poleZero(b0,-1,a1)
+       with{
+               b0 = scaledCoeff;
+               a1 = -scaledCoeff;
+       };
+
+//reflexion filter is a one zero filter (delcred in instrument.lib)
+reflexionFilter = oneZero0(0.5,0.5)*-0.95;
+
+//delay lengths in number of samples
+delay0Length = 5*SR/22050;
+delay2Length = 4*SR/22050;
+delay1Length = (SR/freq*0.5 - 3.5) - (delay0Length + delay2Length) - (nlfOrder*nonLinearity)*(typeModulation < 2);
+
+//fractional delay lines
+delay0 = fdelay(4096,delay0Length);
+delay1 = fdelay(4096,delay1Length);
+delay2 = fdelay(4096,delay2Length);
+
+//stereoizer is declared in instrument.lib and implement a stereo spacialisation in function of 
+//the frequency period in number of samples 
+stereo = stereoizer(SR/freq);
+
+//----------------------- Algorithm implementation ----------------------------
+
+//envelope(ADSR) + vibrato + noise
+envelope = (0.55 + pressure*0.3)*asr(pressure*envelopeAttack,100,pressure*envelopeRelease,gate);
+vibratoEnvelope = envVibrato(0.1*2*vibratoAttack,0.9*2*vibratoAttack,100,vibratoRelease,gate);
+vibrato = vibratoGain*osc(vibratoFreq)*vibratoEnvelope;
+breath = envelope + envelope*noiseGain*noise;
+breathPressure = breath + (breath*vibrato);
+
+//two-port junction scattering for register vent
+twoPortJunction(portB) = (pressureDiff : ((_ <: breathPressure + *(reedTable)) <: (+(portB) : ventFilter <: +(portB),_),_))~
+               delay0 : inverter : + ,_
+       with{
+               pressureDiff = -(breathPressure); 
+               inverter(a,b,c) = b,c,a;
+       };
+
+//three-port junction scattering (under tonehole)
+threePortJunction(twoPortOutput) =  (_ <: junctionScattering(twoPortOutput),_ : +(twoPortOutput), + : 
+               reflexionFilter,_)~delay2 : !,_
+       with{
+               toneHole(temp,portA2,portB2) = (portA2 + portB2-_ + temp : toneHoleFilter)~_;
+               junctionScattering(portA2,portB2) = (((portA2+portB2-2*_)*scattering) <: toneHole(_,portA2,portB2),_,_)~_ : !,_,_;
+       };
+
+process = (twoPortJunction : threePortJunction,_) ~ (delay1 : NLFM) : !,*(gain)*1.5 : stereo : instrReverb;