1 declare name "Harpsichord";
2 declare description "Nonlinear WaveGuide Commuted Harpsichord";
3 declare author "Romain Michon (rmichon@ccrma.stanford.edu)";
4 declare copyright "Romain Michon";
6 declare licence "STK-4.3"; // Synthesis Tool Kit 4.3 (MIT style license);
7 declare description "A commuted WaveGuide Harpsichord.";
10 import("instrument.lib");
12 //==================== GUI SPECIFICATION ================
14 freq = nentry("h:Basic_Parameters/freq [1][unit:Hz] [tooltip:Tone frequency]",440,20,20000,1);
15 gain = nentry("h:Basic_Parameters/gain [1][tooltip:Gain (value between 0 and 1)]",0.8,0,1,0.01);
16 gate = button("h:Basic_Parameters/gate [1][tooltip:noteOn = 1, noteOff = 0]");
18 typeModulation = nentry("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Modulation_Type
19 [2][tooltip: 0=theta is modulated by the incoming signal; 1=theta is modulated by the averaged incoming signal;
20 2=theta is modulated by the squared incoming signal; 3=theta is modulated by a sine wave of frequency freqMod;
21 4=theta is modulated by a sine wave of frequency freq;]",0,0,4,1);
22 nonLinearity = hslider("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Nonlinearity
23 [2][tooltip:Nonlinearity factor (value between 0 and 1)]",0,0,1,0.01);
24 frequencyMod = hslider("h:Physical_and_Nonlinearity/v:Nonlinear_Filter_Parameters/Modulation_Frequency
25 [2][unit:Hz][tooltip:Frequency of the sine wave for the modulation of theta (works if Modulation Type=3)]",220,20,1000,0.1);
27 //==================== PROCESSING ================
29 //----------------------- Nonlinear filter ----------------------------
30 //nonlinearities are created by the nonlinear passive allpass ladder filter declared in filter.lib
32 //nonlinear filter order
35 //nonLinearModultor is declared in instrument.lib, it adapts allpassnn from filter.lib
36 //for using it with waveguide instruments
37 NLFM = nonLinearModulator((nonLinearity : smooth(0.999)),1,freq,
38 typeModulation,(frequencyMod : smooth(0.999)),nlfOrder);
40 //----------------------- Synthesis parameters computing and functions declaration ----------------------------
42 //convert a frequency in a midi note number
43 freqToNoteNumber = (log-log(440))/log(2)*12+69+0.5 : int;
44 freqn = freq : freqToNoteNumber;
47 soundBoard = dryTapAmp*noise
49 dryTapAmpT60 = ffunction(float getValueDryTapAmpT60(float), <harpsichord.h>,"");
50 noteCutOffTime = freqn : dryTapAmpT60*gain;
51 dryTapAmp = asympT60(0.15,0,noteCutOffTime,gate);
54 //loopfilter is a biquad filter whose coefficients are extracted from a C++ file using the foreign function mechanism
55 loopFilter = TF2(b0,b1,b2,a1,a2)
57 //functions are imported from the C++ file
58 loopFilterb0 = ffunction(float getValueLoopFilterb0(float), <harpsichord.h>,"");
59 loopFilterb1 = ffunction(float getValueLoopFilterb1(float), <harpsichord.h>,"");
60 loopFilterb2 = ffunction(float getValueLoopFilterb2(float), <harpsichord.h>,"");
61 loopFiltera1 = ffunction(float getValueLoopFiltera1(float), <harpsichord.h>,"");
62 loopFiltera2 = ffunction(float getValueLoopFiltera2(float), <harpsichord.h>,"");
63 //coefficients are extracted from the functions
64 b0 = loopFilterb0(freqn);
65 b1 = loopFilterb1(freqn);
66 b2 = loopFilterb2(freqn);
67 a1 = loopFiltera1(freqn);
68 a2 = loopFiltera2(freqn);
71 //delay length as a number of samples
72 delayLength = SR/freq;
74 //stereoizer is declared in instrument.lib and implement a stereo spacialisation in function of
75 //the frequency period in number of samples
76 stereo = stereoizer(delayLength);
78 //----------------------- Algorithm implementation ----------------------------
80 //envelope for string loop resonance time
81 stringLoopGainT = gate*0.9996 + (gate<1)*releaseLoopGain(freqn)*0.9 : smooth(0.999)
83 releaseLoopGain = ffunction(float getValueReleaseLoopGain(float), <harpsichord.h>,"");
87 string = (*(stringLoopGainT)+_ : delay(4096,delayLength) : loopFilter)~NLFM;
89 process = soundBoard : string : stereo : instrReverb;