1 declare name "Voice Formant";
2 declare description "Voice Formant Instrument";
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 "This instrument contains an excitation singing wavetable (looping wave with random and periodic vibrato, smoothing on frequency, etc.), excitation noise, and four sweepable complex resonances. Phoneme preset numbers: 0->eee (beet), 1->ihh (bit), 2->ehh (bet), 3->aaa (bat), 4->ahh (father), 5->aww (bought), 6->ohh (bone), 7->uhh (but), 8->uuu (foot), 9->ooo (boot), 10->rrr (bird), 11->lll (lull), 12->mmm (mom), 13->nnn (nun), 14->nng (sang), 15->ngg (bong), 16->fff, 17->sss, 18->thh, 19->shh, 20->xxx, 21->hee (beet), 22->hoo (boot), 23->hah (father), 24->bbb, 25->ddd, 26->jjj, 27->ggg, 28->vvv, 29->zzz, 30->thz, 31->zhh";
10 import("oscillator.lib");
11 import("instrument.lib");
13 //==================== GUI SPECIFICATION ================
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]");
19 phoneme = hslider("v:Physical_Parameters/Phoneme
20 [2][tooltip:0->eee, 1->ihh, 2->ehh, 3->aaa, 4->ahh, 5->aww, 6->ohh, 7->uhh, 8->uuu, 9->ooo, 10->rrr, 11->lll, 12->mmm, 13->nnn, 14->nng, 15->ngg, 16->fff, 17->sss, 18->thh, 19->shh, 20->xxx, 21->hee, 22->hoo, 23->hah, 24->bbb, 25->ddd, 26->jjj, 27->ggg, 28->vvv, 29->zzz, 30->thz, 31->zhh]",4,0,31,1);
22 vibratoFreq = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Freq
23 [3][unit:Hz]",6,1,15,0.1);
24 vibratoGain = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Gain
25 [3][tooltip:A value between 0 and 1]",0.05,0,1,0.01);
26 vibratoBegin = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Begin
27 [3][unit:s][tooltip:Vibrato silence duration before attack]",0.05,0,2,0.01);
28 vibratoAttack = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Attack
29 [3][unit:s][tooltip:Vibrato attack duration]",0.5,0,2,0.01);
30 vibratoRelease = hslider("h:Envelopes_and_Vibrato/v:Vibrato_Parameters/Vibrato_Release
31 [3][unit:s][tooltip:Vibrato release duration]",0.1,0,2,0.01);
33 voicedEnvelopeAttack = hslider("h:Envelopes_and_Vibrato/v:Envelope_Parameters/Voiced_Attack
34 [4][unit:s][tooltip:Voiced sounds attack duration]",0.01,0,2,0.01);
35 voicedEnvelopeRelease = hslider("h:Envelopes_and_Vibrato/v:Envelope_Parameters/Voiced_Release
36 [4][unit:s][tooltip:Voiced sounds release duration]",0.01,0,2,0.01);
38 noiseEnvelopeAttack = hslider("h:Envelopes_and_Vibrato/v:Envelope_Parameters/Noised_Attack
39 [4][unit:s][tooltip:Noised sounds attack duration]",0.001,0,2,0.001);
40 noiseEnvelopeRelease = hslider("h:Envelopes_and_Vibrato/v:Envelope_Parameters/Noised_Release
41 [4][unit:s][tooltip:Noised sounds release duration]",0.001,0,2,0.001);
43 //==================== SIGNAL PROCESSING ================
45 //----------------------- Synthesis parameters computing and functions declaration ----------------------------
47 //stereoizer is declared in instrument.lib and implement a stereo spacialisation in function of
48 //the frequency period in number of samples
49 stereo = stereoizer(SR/freq);
51 //exitation filters (declared in instrument.lib)
52 onePoleFilter = onePole(b0,a1)
54 pole = 0.97 - (gain*0.2);
58 oneZeroFilter = oneZero1(b0,b1)
65 //implements a formant (resonance) which can be "swept" over time from one frequency setting to another
66 formSwep(frequency,radius,filterGain) = *(gain_) : bandPass(frequency_,radius)
68 //filter's radius, gain and frequency are interpolated
69 radius_ = radius : smooth(0.999);
70 frequency_ = frequency : smooth(0.999);
71 gain_ = filterGain : smooth(0.999);
74 //formants parameters are countained in a C++ file
75 phonemeGains = ffunction(float loadPhonemeGains(int,int), <phonemes.h>,"");
76 phonemeParameters = ffunction(float loadPhonemeParameters(int,int,int), <phonemes.h>,"");
78 //formants frequencies
79 ffreq0 = phonemeParameters(phoneme,0,0);
80 ffreq1 = phonemeParameters(phoneme,1,0);
81 ffreq2 = phonemeParameters(phoneme,2,0);
82 ffreq3 = phonemeParameters(phoneme,3,0);
85 frad0 = phonemeParameters(phoneme,0,1);
86 frad1 = phonemeParameters(phoneme,1,1);
87 frad2 = phonemeParameters(phoneme,2,1);
88 frad3 = phonemeParameters(phoneme,3,1);
91 fgain0 = phonemeParameters(phoneme,0,2) : pow(10,(_/20));
92 fgain1 = phonemeParameters(phoneme,1,2) : pow(10,(_/20));
93 fgain2 = phonemeParameters(phoneme,2,2) : pow(10,(_/20));
94 fgain3 = phonemeParameters(phoneme,3,2) : pow(10,(_/20));
96 //gain of the voiced part od the sound
97 voiceGain = phonemeGains(phoneme,0) : smooth(0.999);
99 //gain of the fricative part of the sound
100 noiseGain = phonemeGains(phoneme,1) : smooth(0.999);
103 filter0 = formSwep(ffreq0,frad0,fgain0);
104 filter1 = formSwep(ffreq1,frad1,fgain1);
105 filter2 = formSwep(ffreq2,frad2,fgain2);
106 filter3 = formSwep(ffreq3,frad3,fgain3);
108 //----------------------- Algorithm implementation ----------------------------
110 //envelopes (declared in instrument.lib) and vibrato
111 vibratoEnvelope = envVibrato(vibratoBegin,vibratoAttack,100,vibratoRelease,gate);
112 voicedEnvelope = asr(voicedEnvelopeAttack,100,voicedEnvelopeRelease,gate);
113 noiseEnvelope = asr(noiseEnvelopeAttack,100,noiseEnvelopeRelease,gate);
114 vibrato = osc(vibratoFreq)*vibratoGain*100*vibratoEnvelope;
116 //the voice source is generated by an impulse train
117 //(imptrain defined in oscillator.lib) that is lowpass filtered
118 voiced = imptrain(freq+vibrato) : lowpass3e(3300) : *(voiceGain*voicedEnvelope);
120 //ficative sounds are produced by a noise generator
121 frica = noise*noiseEnvelope*noiseGain;
123 process = voiced : oneZeroFilter : onePoleFilter :
124 +(frica) <: filter0,filter1,filter2,filter3 :> + : stereo :