1
/*******************************************/
2
/* 4 Formant Synthesis Instrument */
3
/* by Perry R. Cook, 1995-96 */
4
/* This instrument contains an excitation */
5
/* singing wavetable (looping wave with */
6
/* random and periodic vibrato, smoothing */
7
/* on frequency, etc.), excitation noise, */
8
/* and four sweepable complex resonances. */
10
/* Measured Formant data (from me) is */
11
/* included, and enough data is there to */
12
/* support either parallel or cascade */
13
/* synthesis. In the floating point case */
14
/* cascade synthesis is the most natural */
15
/* so that's what you'll find here. */
17
/*******************************************/
20
#include "SKINI11.msg"
22
VoicForm :: VoicForm() : Instrmnt()
24
// Concatenate the STK RAWWAVE_PATH to the rawwave file
26
strcpy(file, RAWWAVE_PATH);
27
voiced = new SingWave(strcat(file,"rawwaves/impuls20.raw"));
29
voiced->setGainRate((MY_FLOAT) 0.001);
30
voiced->setGainTarget((MY_FLOAT) 0.0);
34
filters[0] = new FormSwep;
35
filters[1] = new FormSwep;
36
filters[2] = new FormSwep;
37
filters[3] = new FormSwep;
38
filters[0]->setSweepRate((MY_FLOAT) 0.001);
39
filters[1]->setSweepRate((MY_FLOAT) 0.001);
40
filters[2]->setSweepRate((MY_FLOAT) 0.001);
41
filters[3]->setSweepRate((MY_FLOAT) 0.001);
43
onezero = new OneZero;
44
onezero->setCoeff((MY_FLOAT) -0.9);
45
onepole = new OnePole;
46
onepole->setPole((MY_FLOAT) 0.9);
48
noiseEnv = new Envelope;
49
noiseEnv->setRate((MY_FLOAT) 0.001);
50
noiseEnv->setTarget((MY_FLOAT) 0.0);
52
this->setPhoneme("eee");
56
VoicForm :: ~VoicForm()
69
void VoicForm :: clear()
79
void VoicForm :: setFreq(MY_FLOAT frequency)
82
if ((frequency * 22) > SRATE) {
83
printf("This note is too high!!\n");
84
frequency = SRATE / 22;
87
temp = fabs(1500 - frequency) + 200;
88
lastGain = 10000.0 / temp / temp;
89
voiced->setFreq(frequency);
92
void VoicForm :: setFormantAll(int whichOne, MY_FLOAT freq,MY_FLOAT reson,MY_FLOAT gain)
94
filters[whichOne]->setTargets(freq,reson,gain);
99
int VoicForm :: setPhoneme(char *phoneme)
103
while(i<32 && !found) {
104
if (!strcmp(phonemes[i],phoneme)) {
106
this->setFormantAll(0,(MY_FLOAT) phonParams[i][0][0],(MY_FLOAT) phonParams[i][0][1],(MY_FLOAT) pow(10.0,phonParams[i][0][2] / 20.0));
107
this->setFormantAll(1,(MY_FLOAT) phonParams[i][1][0],(MY_FLOAT) phonParams[i][1][1],(MY_FLOAT) 1.0);
108
this->setFormantAll(2,(MY_FLOAT) phonParams[i][2][0],(MY_FLOAT) phonParams[i][2][1],(MY_FLOAT) 1.0);
109
this->setFormantAll(3,(MY_FLOAT) phonParams[i][3][0],(MY_FLOAT) phonParams[i][3][1],(MY_FLOAT) 1.0);
110
this->setVoicedUnVoiced((MY_FLOAT) phonGains[i][0],(MY_FLOAT) phonGains[i][1]);
111
printf("Found Formant: %s (number %i)\n",phoneme,i);
115
if (!found) printf("Phoneme %s not found\n",phoneme);
119
void VoicForm :: setVoiced(MY_FLOAT vGain)
121
voiced->setGainTarget(vGain);
124
void VoicForm :: setUnVoiced(MY_FLOAT nGain)
126
noiseEnv->setTarget(nGain);
129
void VoicForm :: setVoicedUnVoiced(MY_FLOAT vGain, MY_FLOAT nGain)
131
this->setVoiced(vGain);
132
this->setUnVoiced(nGain);
135
void VoicForm :: setFiltSweepRate(int whichOne,MY_FLOAT rate)
137
filters[whichOne]->setSweepRate(rate);
140
void VoicForm :: setPitchSweepRate(MY_FLOAT rate)
142
voiced->setSweepRate(rate);
145
void VoicForm :: speak()
150
void VoicForm :: quiet()
153
noiseEnv->setTarget((MY_FLOAT) 0.0);
156
void VoicForm :: noteOn(MY_FLOAT freq, MY_FLOAT amp)
159
voiced->setGainTarget(amp);
160
onepole->setPole((MY_FLOAT) 0.95 - (amp * (MY_FLOAT) NORM_7 * (MY_FLOAT) 0.2));
163
void VoicForm :: noteOff(MY_FLOAT amp)
168
MY_FLOAT VoicForm :: tick()
171
temp = onepole->tick(onezero->tick(voiced->tick()));
172
temp += noiseEnv->tick() * noise->tick();
173
lastOutput = filters[0]->tick(temp);
174
lastOutput = filters[1]->tick(lastOutput);
175
lastOutput = filters[2]->tick(lastOutput);
176
lastOutput = filters[3]->tick(lastOutput);
177
lastOutput *= lastGain;
181
void VoicForm :: controlChange(int number, MY_FLOAT value)
184
printf("VoicForm : ControlChange: Number=%i Value=%f\n",number,value);
186
if (number == __SK_Breath_) {
187
this->setVoiced((MY_FLOAT) 1.0 - (value *(MY_FLOAT) NORM_7));
188
this->setUnVoiced((MY_FLOAT) 0.01 * value * (MY_FLOAT) NORM_7);
190
else if (number == __SK_FootControl_) {
192
int tempi = (int) value;
195
temp = (MY_FLOAT) 0.9;
197
else if (tempi < 64) {
199
temp = (MY_FLOAT) 1.0;
201
else if (tempi < 96) {
203
temp = (MY_FLOAT) 1.1;
205
else if (tempi <= 128) {
207
temp = (MY_FLOAT) 1.2;
209
this->setFormantAll(0,temp*(MY_FLOAT) phonParams[tempi][0][0],
210
(MY_FLOAT) phonParams[tempi][0][1],
211
(MY_FLOAT) pow(10.0,phonParams[tempi][0][2] / 20.0));
212
this->setFormantAll(1,temp*(MY_FLOAT) phonParams[tempi][1][0],
213
(MY_FLOAT) phonParams[tempi][1][1],(MY_FLOAT) 1.0);
214
this->setFormantAll(2,temp*(MY_FLOAT) phonParams[tempi][2][0],
215
(MY_FLOAT) phonParams[tempi][2][1],(MY_FLOAT) 1.0);
216
this->setFormantAll(3,temp*(MY_FLOAT) phonParams[tempi][3][0],
217
(MY_FLOAT) phonParams[tempi][3][1],(MY_FLOAT) 1.0);
218
this->setVoicedUnVoiced(phonGains[tempi][0],phonGains[tempi][1]);
220
else if (number == __SK_ModFrequency_)
221
voiced->setVibFreq(value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 12.0); /* 0 to 12 Hz */
222
else if (number == __SK_ModWheel_)
223
voiced->setVibAmt(value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 0.2);
224
else if (number == __SK_AfterTouch_Cont_) {
225
this->setVoiced(value*NORM_7);
226
onepole->setPole((MY_FLOAT) 0.99 - (value *(MY_FLOAT) NORM_7 * (MY_FLOAT) 0.2));
227
//onepole->setPole((MY_FLOAT) 0.5 - (value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 0.2));
230
printf("VoicForm : Undefined Control Number!!\n");