X-Git-Url: https://scm.cri.ensmp.fr/git/Faustine.git/blobdiff_plain/c7f552fd8888da2f0d8cfb228fe0f28d3df3a12c..b4b6f2ea75b9f0f3ca918f5b84016610bf7a4d4f:/interpretor/preprocessor/faust-0.9.47mr3/examples/faust-stk/instrument.lib diff --git a/interpretor/preprocessor/faust-0.9.47mr3/examples/faust-stk/instrument.lib b/interpretor/preprocessor/faust-0.9.47mr3/examples/faust-stk/instrument.lib new file mode 100644 index 0000000..dffdbeb --- /dev/null +++ b/interpretor/preprocessor/faust-0.9.47mr3/examples/faust-stk/instrument.lib @@ -0,0 +1,298 @@ +//instrument.lib - Faust function of various types usefull for building physical model instruments + +declare name "Faust-STK Tools Library"; +declare author "Romain Michon (rmichon@ccrma.stanford.edu)"; +declare copyright "Romain Michon"; +declare version "1.0"; +declare licence "STK-4.3"; // Synthesis Tool Kit 4.3 (MIT style license); + +import("math.lib"); +import("filter.lib"); +import("effect.lib"); + +//========================= ENVELOPE GENERATORS =============================== + +//----------------------- VIBRATO ENVELOPE ---------------------------- +// 4 phases envelope to control vibrato gain +// +// USAGE: +// _ : *(envVibrato(b,a,s,r,t)) : _ +// where +// b = beginning duration (silence) in seconds +// a = attack duration in seconds +// s = sustain as a percentage of the amplitude to be modified +// r = release duration in seconds +// t = trigger signal + +envVibrato(b,a,s,r,t) = env ~ (_,_,_) : (!,!,_) // the 3 'state' signals are fed back +with { + env (p2,cnt,y) = + (t>0) & (p2|(y>=1)), + (cnt + 1)*(t>0), // counter for the first step "b" + (y + p1*p3*u*(s/100) - p4*w*y)*((p4==0)|(y>=eps)) // y = envelop signal + //*(y>=eps) // cut off tails to prevent denormals + with { + p1 = (p2==0) & (t>0) & (y<1) & (cnt>(b*SR)); // p1 = attack phase + p3 = 1-(cnt<(nb)); // p3 = beginning phase + p4 = (t<=0) & (y>0); // p4 = release phase + // #samples in attack, release, must be >0 + nb = SR*b+(b==0.0) ; na = SR*a+(a==0.0); nr = SR*r+(r==0.0); + // attack and (-60dB) release rates + z = s+(s==0.0)*db2linear(-60); + u = 1/na; w = 1-1/pow(z*db2linear(60), 1/nr); + // values below this threshold are considered zero in the release phase + eps = db2linear(-120); + }; +}; + +//----------------------- ATTACK - SUSTAIN - RELEASE ---------------------------- +// Attack - Sustain - Release envelope +// +// USAGE: +// _ : *(asr(a,s,r,t)) : _ +// where +// a = attack duration in seconds +// s = sustain as a percentage of the amplitude to be modified +// r = release duration in seconds +// t = trigger signal + +asr(a,s,r,t) = env ~ (_,_) : (!,_) // the 2 'state' signals are fed back +with { + env (p2,y) = + (t>0) & (p2|(y>=1)), + (y + p1*u*(s/100) - p3*w*y) // y = envelop signal + *((p3==0)|(y>=eps)) // cut off tails to prevent denormals + with { + p1 = (p2==0) & (t>0) & (y<1); // p1 = attack phase + p3 = (t<=0) & (y>0); // p3 = release phase + // #samples in attack, release, must be >0 + na = SR*a+(a==0.0); nr = SR*r+(r==0.0); + // correct zero sustain level + z = s+(s==0.0)*db2linear(-60); + // attack and (-60dB) release rates + u = 1/na; w = 1-1/pow(z*db2linear(60), 1/nr); + // values below this threshold are considered zero in the release phase + eps = db2linear(-120); + }; +}; + +//----------------------- ASYMPT60 ---------------------------- +// Envelope generator which asymptotically approaches a target value. +// +// USAGE: +// asympT60(value,trgt,T60,trig) : _ +// where +// value = starting value +// trgt = target value +// T60 = ramping time +// trig = trigger signal + +asympT60(value,trgt,T60,trig) = (_*factor + constant)~_ + with{ + cntSample = *(trig) + 1~_ : -(1); + attDur = float(2); + cndFirst = ((cntSample < attDur) & (trig > 0)); + target = value*cndFirst + trgt*(cndFirst < 1); + factorAtt = exp(-7/attDur); + factorT60 = exp(-7/(T60*float(SR))); + factor = factorAtt*((cntSample < attDur) & (trig > 0)) + + ((cntSample >= attDur) | (trig < 1))*factorT60; + constant = (1 - factor)*target; + }; + +//========================= TABLES =============================== + +//----------------------- CLIPPING FUNCTION ---------------------------- +// Positive and negative clipping functions. +// +// USAGE: +// _ : saturationPos : _ +// _ : saturationNeg : _ +// _ : saturationPos : saturationNeg : _ + +saturationPos(x) = x <: (_>1),(_<=1 : *(x)) :> +; +saturationNeg(x) = x <: (_<-1),(_>=-1 : *(x)) :> *(-1) + _; + +//----------------------- BOW TABLE ---------------------------- +// Simple bow table. +// +// USAGE: +// index : bow(offset,slope) : _ +// where +// 0 <= index <= 1 + +bow(offset,slope) = pow(abs(sample) + 0.75, -4) : saturationPos + with{ + sample(y) = (y + offset)*slope; + }; + +//----------------------- REED TABLE ---------------------------- +// Simple reed table to be used with waveguide models of clanrinet, saxophone, etc. +// +// USAGE: +// _ : reed(offset,slope) : _ +// where +// offset = offset between 0 and 1 +// slope = slope between 0 and 1 +// REFERENCE: +// https://ccrma.stanford.edu/~jos/pasp/View_Single_Reed_Oscillation.html + +reed(offset,slope) = reedTable : saturationPos : saturationNeg + with{ + reedTable = offset + (slope*_); + }; + +//========================= FILTERS =============================== + +//----------------------- ONE POLE ---------------------------- + +onePole(b0,a1,x) = (b0*x - a1*_)~_; + +//----------------------- ONE POLE SWEPT ---------------------------- + +onePoleSwep(a1,x) = (1 + a1)*x - a1*x'; + +//----------------------- POLE ZERO ---------------------------- + +poleZero(b0,b1,a1,x) = (b0*x + b1*x' - a1*_)~_; + +//----------------------- ONE ZEROS ---------------------------- +// Simple One zero and One zero recursive filters +// +// USAGE: +// _ : oneZero0(b0,b1) : _ +// _ : oneZero1(b0,b1) : _ +// REFERENCE: +// https://ccrma.stanford.edu/~jos/fp2/One_Zero.html + +oneZero0(b0,b1,x) = (*(b1) + x*b0)~_; +oneZero1(b0,b1,x) = (x'*b1 + x*b0); + +//----------------------- BANDPASS FILTER WITH CONSTANT UNITY PEAK GAIN BASED ON A BIQUAD ---------------------------- + +bandPass(resonance,radius) = TF2(b0,b1,b2,a1,a2) + with{ + a2 = radius*radius; + a1 = -2*radius*cos(PI*2*resonance/SR); + b0 = 0.5-0.5*a2; + b1 = 0; + b2 = -b0; + }; + +//----------------------- BANDPASS FILTER BASED ON A BIQUAD ---------------------------- +// Band pass filter using a biquad (TF2 is declared in filter.lib) +// +// USAGE: +// _ : bandPassH(resonance,radius) : _ +// where +// resonance = center frequency +// radius = radius + +bandPassH(resonance,radius) = TF2(b0,b1,b2,a1,a2) + with{ + a2 = radius*radius; + a1 = -2*radius*cos(PI*2*resonance/SR); + b0 = 1; + b1 = 0; + b2 = 0; + }; + +//----------------------- FLUE JET NON-LINEAR FUNCTION ---------------------------- +// Jet Table: flue jet non-linear function, computed by a polynomial calculation + +jetTable(x) = x <: _*(_*_-1) : saturationPos : saturationNeg; + +//----------------------- NON LINEAR MODULATOR ---------------------------- +// nonLinearModulator adapts the function allpassnn from filter.lib for using it with waveguide instruments +// +// USAGE: +// _ : nonLinearModulator(nonlinearity,env,freq,typeMod,freqMod,order) : _ +// where +// nonlinearity = nonlinearity coefficient between 0 and 1 +// env = input to connect any kind of envelope +// freq = current tone frequency +// typeMod = if 0: theta is modulated by the incoming signal; +// if 1: theta is modulated by the averaged incoming signal; +// if 2: theta is modulated by the squared incoming signal; +// if 3: theta is modulated by a sine wave of frequency freqMod; +// if 4: theta is modulated by a sine wave of frequency freq; +// freqMod = frequency of the sine wave modulation +// order = order of the filter + +nonLinearModulator(nonlinearity,env,freq,typeMod,freqMod,order) = + //theta is modulated by a sine wave + _ <: nonLinearFilterOsc*(typeMod >= 3), + //theta is modulated by the incoming signal + (_ <: nonLinearFilterSig*nonlinearity,_*(1 - nonlinearity) :> +)*(typeMod < 3) + :> + + with{ + //which frequency to use for the sine wave oscillator? + freqOscMod = (typeMod == 4)*freq + (typeMod != 4)*freqMod; + + //the incoming signal is scaled and the envelope is applied + tsignorm(x) = nonlinearity*PI*x*env; + tsigsquared(x) = nonlinearity*PI*x*x*env; //incoming signal is squared + tsigav(x) = nonlinearity*PI*((x + x')/2)*env; //incoming signal is averaged with its previous sample + + //select which version of the incoming signal of theta to use + tsig(x) = tsignorm(x)*(typeMod == 0) + tsigav(x)*(typeMod == 1) + + tsigsquared(x)*(typeMod == 2); + + //theta is modulated by a sine wave generator + tosc = nonlinearity*PI*osc(freqOscMod)*env; + + //incoming signal is sent to the nonlinear passive allpass ladder filter + nonLinearFilterSig(x) = x <: allpassnn(order,(par(i,order,tsig(x)))); + nonLinearFilterOsc = _ <: allpassnn(order,(par(i,order,tosc))); + }; + +//========================= WAVE TABLES =============================== + +//----------------------- STICK IMPACT ---------------------------- +// Stick impact table. +// +// USAGE: +// index : readMarmstk1 : _ + +readMarmstk1 = ffunction(float readMarmstk1 (int), ,""); +marmstk1TableSize = 246; + +//========================= TOOLS =============================== + +//----------------------- STEREOIZER ---------------------------- +// This function takes a mono input signal and spacialize it in stereo +// in function of the period duration of the tone being played. +// +// USAGE: +// _ : stereo(periodDuration) : _,_ +// where +// periodDuration = period duration of the tone being played in number of samples +// ACKNOWLEDGMENT +// Formulation initiated by Julius O. Smith in https://ccrma.stanford.edu/realsimple/faust_strings/ + +stereoizer(periodDuration) = _ <: _,widthdelay : stereopanner + with{ + W = hslider("v:Spat/spatial width", 0.5, 0, 1, 0.01); + A = hslider("v:Spat/pan angle", 0.6, 0, 1, 0.01); + widthdelay = delay(4096,W*periodDuration/2); + stereopanner = _,_ : *(1.0-A), *(A); + }; + +//----------------------- INSTRREVERB ---------------------------- +// GUI for zita_rev1_stereo from effect.lib +// +// USAGE: +// _,_ : instrRerveb + +instrReverb = _,_ <: *(reverbGain),*(reverbGain),*(1 - reverbGain),*(1 - reverbGain) : +zita_rev1_stereo(rdel,f1,f2,t60dc,t60m,fsmax),_,_ <: _,!,_,!,!,_,!,_ : +,+ + with{ + reverbGain = hslider("v:Reverb/reverbGain",0.137,0,1,0.01) : smooth(0.999); + roomSize = hslider("v:Reverb/roomSize",0.72,0.01,2,0.01); + rdel = 20; + f1 = 200; + f2 = 6000; + t60dc = roomSize*3; + t60m = roomSize*2; + fsmax = 48000; + };