1 // samplv1_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 "samplv1_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 samplv1_formant::Vtab samplv1_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 samplv1_formant::Vtab samplv1_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 samplv1_formant::Vtab samplv1_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 samplv1_formant::Vtab samplv1_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 samplv1_formant::Vtab samplv1_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 samplv1_formant::Vtab *samplv1_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 samplv1_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 samplv1_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 samplv1_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 samplv1_formant.cpp
228