1
/******************************************/
2
/* WaveGuide Flute ala Karjalainen, */
3
/* Smith, Waryznyk, etc. */
4
/* with polynomial Jet ala Cook */
5
/* by Perry Cook, 1995-96 */
7
/* This is a waveguide model, and thus */
8
/* relates to various Stanford Univ. */
9
/* and possibly Yamaha and other patents.*/
11
/* Controls: CONTROL1 = jetDelay */
12
/* CONTROL2 = noiseGain */
13
/* CONTROL3 = vibFreq */
14
/* MOD_WHEEL= vibAmt */
15
/******************************************/
18
#include "SKINI11.msg"
20
Flute :: Flute(MY_FLOAT lowestFreq)
23
length = (long) (SRATE / lowestFreq + 1);
24
boreDelay = new DLineL(length);
26
jetDelay = new DLineL(length);
27
jetTable = new JetTabl;
29
dcBlock = new DCBlock;
33
// Concatenate the STK RAWWAVE_PATH to the rawwave file
35
strcpy(file, RAWWAVE_PATH);
36
vibr = new RawWvIn(strcat(file,"rawwaves/sinewave.raw"),"looping");
39
boreDelay->setDelay((MY_FLOAT) 100.0);
40
jetDelay->setDelay((MY_FLOAT) 49.0);
42
filter->setPole((MY_FLOAT) 0.7 - ((MY_FLOAT) 0.1 * (MY_FLOAT) 22050.0 / SRATE));
43
filter->setGain((MY_FLOAT) -1.0);
44
vibr->setFreq((MY_FLOAT) 5.925);
45
adsr->setAllTimes((MY_FLOAT) 0.005, (MY_FLOAT) 0.01, (MY_FLOAT) 0.8, (MY_FLOAT) 0.010);
46
endRefl = (MY_FLOAT) 0.5;
47
jetRefl = (MY_FLOAT) 0.5;
48
noiseGain = (MY_FLOAT) 0.15; /* Breath pressure random component */
49
vibrGain = (MY_FLOAT) 0.05; /* breath periodic vibrato component */
50
jetRatio = (MY_FLOAT) 0.32;
52
maxPressure = (MY_FLOAT) 0.0;
75
void Flute :: setFreq(MY_FLOAT frequency)
78
lastFreq = frequency * (MY_FLOAT) 0.66666; /* we're overblowing here */
79
temp = SRATE / lastFreq - (MY_FLOAT) 2.0; /* Length - approx. filter delay */
80
boreDelay->setDelay(temp); /* Length of bore tube */
81
jetDelay->setDelay(temp * jetRatio); /* jet delay shorter */
84
void Flute :: startBlowing(MY_FLOAT amplitude, MY_FLOAT rate)
86
adsr->setAttackRate(rate);
87
maxPressure = amplitude / (MY_FLOAT) 0.8;
91
void Flute :: stopBlowing(MY_FLOAT rate)
93
adsr->setReleaseRate(rate);
97
void Flute :: noteOn(MY_FLOAT freq, MY_FLOAT amp)
100
this->startBlowing((MY_FLOAT) 1.1 + (amp * (MY_FLOAT) 0.20),amp * (MY_FLOAT) 0.02);
101
outputGain = amp + (MY_FLOAT) 0.001;
103
printf("Flute : NoteOn: Freq=%lf Amp=%lf\n",freq,amp);
107
void Flute :: noteOff(MY_FLOAT amp)
109
this->stopBlowing(amp * (MY_FLOAT) 0.02);
111
printf("Flute : NoteOff: Amp=%lf\n",amp);
115
void Flute :: setJetRefl(MY_FLOAT refl)
120
void Flute :: setEndRefl(MY_FLOAT refl)
125
void Flute :: setJetDelay(MY_FLOAT aRatio)
128
temp = SRATE / lastFreq - (MY_FLOAT) 2.0; /* Length - approx. filter delay */
130
jetDelay->setDelay(temp * aRatio); /* Scaled by ratio */
133
MY_FLOAT Flute :: tick()
136
MY_FLOAT pressureDiff;
137
MY_FLOAT randPressure;
138
MY_FLOAT breathPressure;
140
breathPressure = maxPressure * adsr->tick(); /* Breath Pressure */
141
randPressure = noiseGain * noise->tick(); /* Random Deviation */
142
randPressure += vibrGain * vibr->tick(); /* + breath vibrato */
143
randPressure *= breathPressure; /* All scaled by Breath Pressure */
145
temp = filter->tick(boreDelay->lastOut());
146
temp = dcBlock->tick(temp); /* Block DC on reflection */
147
pressureDiff = breathPressure + randPressure - /* Breath Pressure */
148
(jetRefl * temp); /* - reflected */
149
pressureDiff = jetDelay->tick(pressureDiff); /* Jet Delay Line */
150
pressureDiff = jetTable->lookup(pressureDiff) /* Non-Lin Jet + reflected */
152
lastOutput = (MY_FLOAT) 0.3 * boreDelay->tick(pressureDiff); /* Bore Delay and "bell" filter */
154
lastOutput *= outputGain;
159
void Flute :: controlChange(int number, MY_FLOAT value)
162
printf("Flute : ControlChange: Number=%i Value=%f\n",number,value);
164
if (number == __SK_JetDelay_)
165
this->setJetDelay((MY_FLOAT) 0.08 + ((MY_FLOAT) 0.48 * value * NORM_7));
166
else if (number == __SK_NoiseLevel_)
167
noiseGain = (value * NORM_7 * (MY_FLOAT) 0.4);
168
else if (number == __SK_ModFrequency_)
169
vibr->setFreq((value * NORM_7 * (MY_FLOAT) 12.0));
170
else if (number == __SK_ModWheel_)
171
vibrGain = (value * NORM_7 * (MY_FLOAT) 0.4);
172
else if (number == __SK_AfterTouch_Cont_)
173
adsr->setTarget(value * NORM_7);
175
printf("Flute : Undefined Control Number!!\n");