Merge branch 'master' of https://scm.cri.ensmp.fr/git/Faustine
[Faustine.git] / interpreter / preprocessor / faust-0.9.47mr3 / examples / faust-stk / saxophony.dsp
1 declare name "Saxophone";
2 declare description "Nonlinear WaveGuide Saxophone";
3 declare author "Romain Michon";
4 declare copyright "Romain Michon (rmichon@ccrma.stanford.edu)";
5 declare version "1.0";
6 declare licence "STK-4.3"; // Synthesis Tool Kit 4.3 (MIT style license);
7 declare description "This class implements a hybrid digital waveguide instrument that can generate a variety of wind-like sounds. It has also been referred to as the blowed string model. The waveguide section is essentially that of a string, with one rigid and one lossy termination. The non-linear function is a reed table. The string can be blown at any point between the terminations, though just as with strings, it is impossible to excite the system at either end. If the excitation is placed at the string mid-point, the sound is that of a clarinet. At points closer to the bridge, the sound is closer to that of a saxophone. See Scavone (2002) for more details.";
8 declare reference "https://ccrma.stanford.edu/~jos/pasp/Woodwinds.html";
9
10 import("music.lib");
11 import("instrument.lib");
12
13 //==================== GUI SPECIFICATION ================
14
15 freq = nentry("h:Basic_Parameters/freq [1][unit:Hz] [tooltip:Tone frequency]",440,20,20000,1);
16 gain = nentry("h:Basic_Parameters/gain [1][tooltip:Gain (value between 0 and 1)]",1,0,1,0.01);
17 gate = button("h:Basic_Parameters/gate [1][tooltip:noteOn = 1, noteOff = 0]");
18
19 pressure = hslider("h:Physical_and_Nonlinearity/v:Physical_Parameters/Pressure
20 [2][tooltip:Breath pressure (a value between 0 and 1)]",1,0,1,0.01);
21 reedStiffness = hslider("h:Physical_and_Nonlinearity/v:Physical_Parameters/Reed_Stiffness
22 [2][tooltip:A value between 0 and 1]",0.3,0,1,0.01);
23 blowPosition = hslider("h:Physical_and_Nonlinearity/v:Physical_Parameters/Blow_Position
24 [2][tooltip:A value between 0 and 1]",0.5,0,1,0.01);
25 noiseGain = hslider("h:Physical_and_Nonlinearity/v:Physical_Parameters/Noise_Gain",0.05,0,1,0.01);
26
27 typeModulation = nentry("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Modulation_Type
28 [3][tooltip: 0=theta is modulated by the incoming signal; 1=theta is modulated by the averaged incoming signal;
29 2=theta is modulated by the squared incoming signal; 3=theta is modulated by a sine wave of frequency freqMod;
30 4=theta is modulated by a sine wave of frequency freq;]",0,0,4,1);
31 nonLinearity = hslider("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Nonlinearity
32 [3][tooltip:Nonlinearity factor (value between 0 and 1)]",0,0,1,0.01);
33 frequencyMod = hslider("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Modulation_Frequency
34 [3][unit:Hz][tooltip:Frequency of the sine wave for the modulation of theta (works if Modulation Type=3)]",220,20,1000,0.1);
35 nonLinAttack = hslider("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Nonlinearity_Attack
36 [3][unit:s][Attack duration of the nonlinearity]",0.1,0,2,0.01);
37
38 vibratoFreq = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Freq
39 [4][unit:Hz]",6,1,15,0.1);
40 vibratoGain = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Gain
41 [4][tooltip:A value between 0 and 1]",0.1,0,1,0.01);
42 vibratoBegin = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Begin
43 [4][unit:s][tooltip:Vibrato silence duration before attack]",0.05,0,2,0.01);
44 vibratoAttack = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Attack
45 [4][unit:s][tooltip:Vibrato attack duration]",0.3,0,2,0.01);
46 vibratoRelease = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Release
47 [4][unit:s][tooltip:Vibrato release duration]",0.1,0,2,0.01);
48
49 envelopeAttack = hslider("h:Envelopes_and_Vibrato/v:Envelope_Parameters/Envelope_Attack
50 [5][unit:s][tooltip:Envelope attack duration]",0.05,0,2,0.01);
51 envelopeRelease = hslider("h:Envelopes_and_Vibrato/v:Envelope_Parameters/Envelope_Release
52 [5][unit:s][tooltip:Envelope release duration]",0.01,0,2,0.01);
53
54 //==================== SIGNAL PROCESSING ================
55
56 //----------------------- Nonlinear filter ----------------------------
57 //nonlinearities are created by the nonlinear passive allpass ladder filter declared in filter.lib
58
59 //nonlinear filter order
60 nlfOrder = 6;
61
62 //attack - sustain - release envelope for nonlinearity (declared in instrument.lib)
63 envelopeMod = asr(nonLinAttack,100,envelopeRelease,gate);
64
65 //nonLinearModultor is declared in instrument.lib, it adapts allpassnn from filter.lib
66 //for using it with waveguide instruments
67 NLFM = nonLinearModulator((nonLinearity : smooth(0.999)),envelopeMod,freq,
68 typeModulation,(frequencyMod : smooth(0.999)),nlfOrder);
69
70 //----------------------- Synthesis parameters computing and functions declaration ----------------------------
71
72 //stereoizer is declared in instrument.lib and implement a stereo spacialisation in function of
73 //the frequency period in number of samples
74 stereo = stereoizer(SR/freq);
75
76 //reed table parameters
77 reedTableOffset = 0.7;
78 reedTableSlope = 0.1 + (0.4*reedStiffness);
79
80 //the reed function is declared in instrument.lib
81 reedTable = reed(reedTableOffset,reedTableSlope);
82
83 //Delay lines length in number of samples
84 fdel1 = (1-blowPosition) * (SR/freq - 3);
85 fdel2 = (SR/freq - 3)*blowPosition +1 ;
86
87 //Delay lines
88 delay1 = fdelay(4096,fdel1);
89 delay2 = fdelay(4096,fdel2);
90
91 //Breath pressure is controlled by an attack / sustain / release envelope (asr is declared in instrument.lib)
92 envelope = (0.55+pressure*0.3)*asr(pressure*envelopeAttack,100,pressure*envelopeRelease,gate);
93 breath = envelope + envelope*noiseGain*noise;
94
95 //envVibrato is decalred in instrument.lib
96 vibrato = vibratoGain*envVibrato(vibratoBegin,vibratoAttack,100,vibratoRelease,gate)*osc(vibratoFreq);
97 breathPressure = breath + breath*vibratoGain*osc(vibratoFreq);
98
99 //Body filter is a one zero filter (declared in instrument.lib)
100 bodyFilter = *(gain) : oneZero1(b0,b1)
101 with{
102 gain = -0.95;
103 b0 = 0.5;
104 b1 = 0.5;
105 };
106
107 instrumentBody(delay1FeedBack,breathP) = delay1FeedBack <: -(delay2) <:
108 ((breathP - _ <: breathP - _*reedTable) - delay1FeedBack),_;
109
110 process =
111 (bodyFilter,breathPressure : instrumentBody) ~
112 (delay1 : NLFM) : !,
113 //Scaling Output and stereo
114 *(gain) : stereo : instrReverb;