1 // padthv1_formant.cpp
2 //
3 /****************************************************************************
4    Copyright (C) 2012-2021, rncbc aka Rui Nuno Capela. All rights reserved.
5 
6    This program is free software; you can redistribute it and/or
7    modify it under the terms of the GNU General Public License
8    as published by the Free Software Foundation; either version 2
9    of the License, or (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License along
17    with this program; if not, write to the Free Software Foundation, Inc.,
18    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 
20 *****************************************************************************/
21 
22 #include "padthv1_formant.h"
23 
24 
25 //---------------------------------------------------------------------
26 // formant filter.
27 //
28 // A formant parallel filter after Dennis H. Klatt's
29 // Software for a cascade/parallel formant synthesizer
30 // 1979 MIT; 1980 Acoustical Society of America.
31 //
32 
33 // formant tables.
34 //
35 // The Canonical Csound Reference Manual
36 // Appendix D. Formant Values
37 // http://www.csounds.com/manual/html/MiscFormants.html
38 //
39 
40 padthv1_formant::Vtab padthv1_formant::g_alto_vtab[NUM_VOWELS] = {
41 	// Table D.1. alto “a”
42 	{{  800.0f, 1150.0f, 2800.0f, 3500.0f, 4950.0f },
43 	 {    0.0f,   -4.0f,  -20.0f,  -36.0f,  -60.0f },
44 	 {   80.0f,   90.0f,  120.0f,  130.0f,  140.0f }},
45 	// Table D.2. alto “e”
46 	{{  400.0f, 1600.0f, 2700.0f, 3300.0f, 4950.0f },
47 	 {    0.0f,  -24.0f,  -30.0f,  -35.0f,  -60.0f },
48 	 {   60.0f,   80.0f,  120.0f,  150.0f,  200.0f }},
49 	// Table D.3. alto “i”
50 	{{  350.0f, 1700.0f, 2700.0f, 3700.0f, 4950.0f },
51 	 {    0.0f,  -20.0f,  -30.0f,  -36.0f,  -60.0f },
52 	 {   50.0f,  100.0f,  120.0f,  150.0f,  200.0f }},
53 	// Table D.4. alto “o”
54 	{{  450.0f,  800.0f, 2830.0f, 3500.0f, 4950.0f },
55 	 {    0.0f,   -9.0f,  -16.0f,  -28.0f,  -55.0f },
56 	 {   70.0f,   80.0f,  100.0f,  130.0f,  135.0f }},
57 	// Table D.5. alto “u”
58 	{{  325.0f,  700.0f, 2530.0f, 3500.0f, 4950.0f },
59 	 {    0.0f,  -12.0f,  -30.0f,  -40.0f,  -64.0f },
60 	 {   50.0f,   60.0f,  170.0f,  180.0f,  200.0f }}
61 };
62 
63 padthv1_formant::Vtab padthv1_formant::g_bass_vtab[NUM_VOWELS] = {
64 	// Table D.6. bass “a”
65 	{{  600.0f, 1040.0f, 2250.0f, 2450.0f, 2750.0f },
66 	 {    0.0f,   -7.0f,   -9.0f,   -9.0f,  -20.0f },
67 	 {   60.0f,   70.0f,  110.0f,  120.0f,  130.0f }},
68 	// Table D.7. bass “e”
69 	{{  400.0f, 1620.0f, 2400.0f, 2800.0f, 3100.0f },
70 	 {    0.0f,  -12.0f,   -9.0f,  -12.0f,  -18.0f },
71 	 {   40.0f,   80.0f,  100.0f,  120.0f,  120.0f }},
72 	// Table D.8. bass “i”
73 	{{  250.0f, 1750.0f, 2600.0f, 3050.0f, 3340.0f },
74 	 {    0.0f,  -30.0f,  -16.0f,  -22.0f,  -28.0f },
75 	 {   60.0f,   90.0f,  100.0f,  120.0f,  120.0f }},
76 	// Table D.9. bass “o”
77 	{{  400.0f,  750.0f, 2400.0f, 2600.0f, 2900.0f },
78 	 {    0.0f,  -11.0f,  -21.0f,  -20.0f,  -40.0f },
79 	 {   40.0f,   80.0f,  100.0f,  120.0f,  120.0f }},
80 	// Table D.10. bass “u”
81 	{{  350.0f, 600.0f,  2400.0f, 2675.0f, 2950.0f },
82 	 {    0.0f,  -20.0f,  -32.0f,  -28.0f,  -36.0f },
83 	 {   40.0f,   80.0f,  100.0f,  120.0f,  120.0f }}
84 };
85 
86 padthv1_formant::Vtab padthv1_formant::g_countertenor_vtab[NUM_VOWELS] = {
87 	// Table D.11. countertenor “a”
88 	{{  660.0f, 1120.0f, 2750.0f, 3000.0f, 3350.0f },
89 	 {    0.0f,   -6.0f,  -23.0f,  -24.0f,  -38.0f },
90 	 {   80.0f,   90.0f,  120.0f,  130.0f,  140.0f }},
91 	// Table D.12. countertenor “e”
92 	{{  440.0f, 1800.0f, 2700.0f, 3000.0f, 3300.0f },
93 	 {    0.0f,  -14.0f,  -18.0f,  -20.0f,  -20.0f },
94 	 {   70.0f,   80.0f,  100.0f,  120.0f,  120.0f }},
95 	// Table D.13. countertenor “i”
96 	{{  270.0f, 1850.0f, 2900.0f, 3350.0f, 3590.0f },
97 	 {    0.0f,  -24.0f,  -24.0f,  -36.0f,  -36.0f },
98 	 {   40.0f,   90.0f,  100.0f,  120.0f,  120.0f }},
99 	// Table D.14. countertenor “o”
100 	{{  430.0f,  820.0f, 2700.0f, 3000.0f, 3300.0f },
101 	 {    0.0f,  -10.0f,  -26.0f,  -22.0f,  -34.0f },
102 	 {   40.0f,   80.0f,  100.0f,  120.0f,  120.0f }},
103 	// Table D.15. countertenor “u”
104 	{{  370.0f,  630.0f, 2750.0f, 3000.0f, 3400.0f },
105 	 {    0.0f,  -20.0f,  -23.0f,  -30.0f,  -34.0f },
106 	 {   40.0f,   60.0f,  100.0f,  120.0f,  120.0f }}
107 };
108 
109 padthv1_formant::Vtab padthv1_formant::g_soprano_vtab[NUM_VOWELS] = {
110 	// Table D.16. soprano “a”
111 	{{  800.0f, 1150.0f, 2900.0f, 3900.0f, 4950.0f },
112 	 {    0.0f,   -6.0f,  -32.0f,  -20.0f,  -50.0f },
113 	 {   80.0f,   90.0f,  120.0f,  130.0f,  140.0f }},
114 	// Table D.17. soprano “e”
115 	{{  350.0f, 2000.0f, 2800.0f, 3600.0f, 4950.0f },
116 	 {    0.0f,  -20.0f,  -15.0f,  -40.0f,  -56.0f },
117 	 {   60.0f,  100.0f,  120.0f,  150.0f,  200.0f }},
118 	// Table D.18. soprano “i”
119 	{{  270.0f, 2140.0f, 2950.0f, 3900.0f, 4950.0f },
120 	 {    0.0f,  -12.0f,  -26.0f,  -26.0f,  -44.0f },
121 	 {   60.0f,   90.0f,  100.0f,  120.0f,  120.0f }},
122 	// Table D.19. soprano “o”
123 	{{  450.0f,  800.0f, 2830.0f, 3800.0f, 4950.0f },
124 	 {    0.0f,  -11.0f,  -22.0f,  -22.0f,  -50.0f },
125 	 {   40.0f,   80.0f,  100.0f,  120.0f,  120.0f }},
126 	// Table D.20. soprano “u”
127 	{{  325.0f,  700.0f, 2700.0f, 3800.0f, 4950.0f },
128 	 {    0.0f,  -16.0f,  -35.0f,  -40.0f,  -60.0f },
129 	 {   50.0f,   60.0f,  170.0f,  180.0f,  200.0f }}
130 };
131 
132 padthv1_formant::Vtab padthv1_formant::g_tenor_vtab[NUM_VOWELS] = {
133 	// Table D.21. tenor “a”
134 	{{  650.0f, 1080.0f, 2650.0f, 2900.0f, 3250.0f },
135 	 {    0.0f,   -6.0f,   -7.0f,   -8.0f,  -22.0f },
136 	 {   80.0f,   90.0f,  120.0f,  130.0f,  140.0f }},
137 	// Table D.22. tenor “e”
138 	{{  400.0f, 1700.0f, 2600.0f, 3200.0f, 3580.0f },
139 	 {    0.0f,  -14.0f,  -12.0f,  -14.0f,  -20.0f },
140 	 {   70.0f,   80.0f,  100.0f,  120.0f,  120.0f }},
141 	// Table D.23. tenor “i”
142 	{{  290.0f, 1870.0f, 2800.0f, 3250.0f, 3540.0f },
143 	 {    0.0f,  -15.0f,  -18.0f,  -20.0f,  -30.0f },
144 	 {   40.0f,   90.0f,  100.0f,  120.0f,  120.0f }},
145 	// Table D.24. tenor “o”
146 	{{  400.0f,  800.0f, 2600.0f, 2800.0f, 3000.0f },
147 	 {    0.0f,  -10.0f,  -12.0f,  -12.0f,  -26.0f },
148 	 {   70.0f,   80.0f,  100.0f,  130.0f,  135.0f }},
149 	// Table D.25. tenor “u”
150 	{{  350.0f,  600.0f, 2700.0f, 2900.0f, 3300.0f },
151 	 {    0.0f,  -20.0f,  -17.0f,  -14.0f,  -26.0f },
152 	 {   40.0f,   60.0f,  100.0f,  120.0f,  120.0f }}
153 };
154 
155 // base vocal tables.
156 padthv1_formant::Vtab *padthv1_formant::g_vtabs[NUM_VTABS] = {
157 	g_bass_vtab,
158 	g_tenor_vtab,
159 	g_countertenor_vtab,
160 	g_soprano_vtab,
161 	g_alto_vtab
162 };
163 
164 
165 // compute coeffs. for given vocal formant table
vtab_coeffs(Coeffs & coeffs,const Vtab * vtab,uint32_t i,float p)166 void padthv1_formant::Impl::vtab_coeffs (
167 	Coeffs& coeffs, const Vtab *vtab, uint32_t i, float p )
168 {
169 	const float Fi = vtab->freq[i];
170 	const float Gi = vtab->gain[i];
171 	const float Bi = vtab->band[i] * p;
172 
173 	const float Ai = ::powf(10.0f, (0.05f * Gi));
174 	const float Ri = ::expf(-M_PI * Bi / m_srate);
175 
176 	coeffs.b2 = Ri * Ri;
177 	coeffs.b1 = 2.0f * Ri * ::cosf(2.0f * M_PI * Fi / m_srate);
178 	coeffs.a0 = Ai * (1.0f - coeffs.b1 + coeffs.b2);
179 }
180 
181 
182 // reset method impl.
reset_coeffs(float cutoff,float reso)183 void padthv1_formant::Impl::reset_coeffs ( float cutoff, float reso )
184 {
185 	const float   fK = cutoff * float(NUM_VTABS - 1);
186 	const uint32_t k = uint32_t(fK);
187 	const float   fJ = (fK - float(k)) * float(NUM_VOWELS - 1);
188 	const uint32_t j = uint32_t(fJ);
189 	const float   dJ = (fJ - float(j)); // vowel morph fraction
190 
191 	const float q = 4.0f * reso * reso + 1.0f;
192 	const float p = 1.0f / q;
193 
194 	// vocal/vowel formant morphing
195 	const Vtab *vtabs = g_vtabs[k];
196 	const Vtab *vtab1 = &vtabs[j];
197 	const Vtab *vtab2 = vtab1;
198 	if (j < NUM_VOWELS - 1)
199 		vtab2 = &vtabs[j + 1];
200 	else
201 	if (k < NUM_VTABS - 1)
202 		vtab2 = &g_vtabs[k + 1][0];
203 
204 	Coeffs coeff2;
205 	for (uint32_t i = 0; i < NUM_FORMANTS; ++i) {
206 		Coeffs& coeff1 = m_ctabs[i];
207 		vtab_coeffs(coeff1, vtab1, i, p);
208 		vtab_coeffs(coeff2, vtab2, i, p);
209 		coeff1.a0 += dJ * (coeff2.a0 - coeff1.a0);
210 		coeff1.b1 += dJ * (coeff2.b1 - coeff1.b1);
211 		coeff1.b2 += dJ * (coeff2.b2 - coeff1.b2);
212 	}
213 }
214 
215 
216 // reset coeffs. method
reset_coeffs(void)217 void padthv1_formant::reset_coeffs (void)
218 {
219 	if (m_pImpl) {
220 		m_pImpl->reset_coeffs(m_cutoff, m_reso);
221 		for (uint32_t i = 0; i < NUM_FORMANTS; ++i)
222 			m_filters[i].reset_coeffs(m_pImpl->coeffs(i));
223 	}
224 }
225 
226 
227 // end of padthv1_formant.cpp
228