1 /*
2   ZynAddSubFX - a software synthesizer
3 
4   FormantFilter.cpp - formant filters
5   Copyright (C) 2002-2005 Nasca Octavian Paul
6   Author: Nasca Octavian Paul
7 
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
11   (at your option) any later version.
12 
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License (version 2 or later) for more details.
17 
18   You should have received a copy of the GNU General Public License (version 2)
19   along with this program; if not, write to the Free Software Foundation,
20   Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21 
22 */
23 
24 #include <cmath>
25 #include <cstdio>
26 #include "../Misc/Util.h"
27 #include "FormantFilter.h"
28 #include "AnalogFilter.h"
29 #include "../Params/FilterParams.h"
30 
FormantFilter(FilterParams * pars,unsigned int srate,int bufsize)31 FormantFilter::FormantFilter(FilterParams *pars, unsigned int srate, int bufsize)
32     : Filter(srate, bufsize)
33 {
34     numformants = pars->Pnumformants;
35     for(int i = 0; i < numformants; ++i)
36         formant[i] = new AnalogFilter(4 /*BPF*/, 1000.0f, 10.0f, pars->Pstages, srate, bufsize);
37     cleanup();
38 
39     for(int j = 0; j < FF_MAX_VOWELS; ++j)
40         for(int i = 0; i < numformants; ++i) {
41             formantpar[j][i].freq = pars->getformantfreq(
42                 pars->Pvowels[j].formants[i].freq);
43             formantpar[j][i].amp = pars->getformantamp(
44                 pars->Pvowels[j].formants[i].amp);
45             formantpar[j][i].q = pars->getformantq(
46                 pars->Pvowels[j].formants[i].q);
47         }
48 
49     for(int i = 0; i < FF_MAX_FORMANTS; ++i)
50         oldformantamp[i] = 1.0f;
51     for(int i = 0; i < numformants; ++i) {
52         currentformants[i].freq = 1000.0f;
53         currentformants[i].amp  = 1.0f;
54         currentformants[i].q    = 2.0f;
55     }
56 
57     formantslowness = powf(1.0f - (pars->Pformantslowness / 128.0f), 3.0f);
58 
59     sequencesize = pars->Psequencesize;
60     if(sequencesize == 0)
61         sequencesize = 1;
62     for(int k = 0; k < sequencesize; ++k)
63         sequence[k].nvowel = pars->Psequence[k].nvowel;
64 
65     vowelclearness = powf(10.0f, (pars->Pvowelclearness - 32.0f) / 48.0f);
66 
67     sequencestretch = powf(0.1f, (pars->Psequencestretch - 32.0f) / 48.0f);
68     if(pars->Psequencereversed)
69         sequencestretch *= -1.0f;
70 
71     outgain = dB2rap(pars->getgain());
72 
73     oldinput   = -1.0f;
74     Qfactor    = 1.0f;
75     oldQfactor = Qfactor;
76     firsttime  = 1;
77 }
78 
~FormantFilter()79 FormantFilter::~FormantFilter()
80 {
81     for(int i = 0; i < numformants; ++i)
82         delete (formant[i]);
83 }
84 
cleanup()85 void FormantFilter::cleanup()
86 {
87     for(int i = 0; i < numformants; ++i)
88         formant[i]->cleanup();
89 }
90 
setpos(float input)91 void FormantFilter::setpos(float input)
92 {
93     int p1, p2;
94 
95     if(firsttime != 0)
96         slowinput = input;
97     else
98         slowinput = slowinput
99                     * (1.0f - formantslowness) + input * formantslowness;
100 
101     if((fabsf(oldinput - input) < 0.001f) && (fabsf(slowinput - input) < 0.001f)
102        && (fabsf(Qfactor - oldQfactor) < 0.001f)) {
103         //	oldinput=input; daca setez asta, o sa faca probleme la schimbari foarte lente
104         firsttime = 0;
105         return;
106     }
107     else
108         oldinput = input;
109 
110     float pos = fmodf(input * sequencestretch, 1.0f);
111     if(pos < 0.0f)
112         pos += 1.0f;
113 
114     F2I(pos * sequencesize, p2);
115     p1 = p2 - 1;
116     if(p1 < 0)
117         p1 += sequencesize;
118 
119     pos = fmodf(pos * sequencesize, 1.0f);
120     if(pos < 0.0f)
121         pos = 0.0f;
122     else
123     if(pos > 1.0f)
124         pos = 1.0f;
125     pos =
126         (atanf((pos * 2.0f
127                 - 1.0f)
128                * vowelclearness) / atanf(vowelclearness) + 1.0f) * 0.5f;
129 
130     p1 = sequence[p1].nvowel;
131     p2 = sequence[p2].nvowel;
132 
133     if(firsttime != 0) {
134         for(int i = 0; i < numformants; ++i) {
135             currentformants[i].freq =
136                 formantpar[p1][i].freq
137                 * (1.0f - pos) + formantpar[p2][i].freq * pos;
138             currentformants[i].amp =
139                 formantpar[p1][i].amp
140                 * (1.0f - pos) + formantpar[p2][i].amp * pos;
141             currentformants[i].q =
142                 formantpar[p1][i].q * (1.0f - pos) + formantpar[p2][i].q * pos;
143             formant[i]->setfreq_and_q(currentformants[i].freq,
144                                       currentformants[i].q * Qfactor);
145             oldformantamp[i] = currentformants[i].amp;
146         }
147         firsttime = 0;
148     }
149     else
150         for(int i = 0; i < numformants; ++i) {
151             currentformants[i].freq =
152                 currentformants[i].freq * (1.0f - formantslowness)
153                 + (formantpar[p1][i].freq
154                    * (1.0f - pos) + formantpar[p2][i].freq * pos)
155                 * formantslowness;
156 
157             currentformants[i].amp =
158                 currentformants[i].amp * (1.0f - formantslowness)
159                 + (formantpar[p1][i].amp * (1.0f - pos)
160                    + formantpar[p2][i].amp * pos) * formantslowness;
161 
162             currentformants[i].q = currentformants[i].q
163                                    * (1.0f - formantslowness)
164                                    + (formantpar[p1][i].q * (1.0f - pos)
165                                       + formantpar[p2][i].q
166                                       * pos) * formantslowness;
167 
168 
169             formant[i]->setfreq_and_q(currentformants[i].freq,
170                                       currentformants[i].q * Qfactor);
171         }
172 
173     oldQfactor = Qfactor;
174 }
175 
setfreq(float frequency)176 void FormantFilter::setfreq(float frequency)
177 {
178     setpos(frequency);
179 }
180 
setq(float q_)181 void FormantFilter::setq(float q_)
182 {
183     Qfactor = q_;
184     for(int i = 0; i < numformants; ++i)
185         formant[i]->setq(Qfactor * currentformants[i].q);
186 }
187 
setgain(float)188 void FormantFilter::setgain(float /*dBgain*/)
189 {}
190 
log_2(float x)191 inline float log_2(float x)
192 {
193     return logf(x) / logf(2.0f);
194 }
195 
setfreq_and_q(float frequency,float q_)196 void FormantFilter::setfreq_and_q(float frequency, float q_)
197 {
198     //Convert form real freq[Hz]
199     const float freq = log_2(frequency) - 9.96578428f; //log2(1000)=9.95748f.
200 
201     Qfactor = q_;
202     setpos(freq);
203 }
204 
205 
filterout(float * smp)206 void FormantFilter::filterout(float *smp)
207 {
208     float inbuffer[buffersize];
209 
210     memcpy(inbuffer, smp, bufferbytes);
211     memset(smp, 0, bufferbytes);
212 
213     for(int j = 0; j < numformants; ++j) {
214         float tmpbuf[buffersize];
215         for(int i = 0; i < buffersize; ++i)
216             tmpbuf[i] = inbuffer[i] * outgain;
217         formant[j]->filterout(tmpbuf);
218 
219         if(ABOVE_AMPLITUDE_THRESHOLD(oldformantamp[j], currentformants[j].amp))
220             for(int i = 0; i < buffersize; ++i)
221                 smp[i] += tmpbuf[i]
222                           * INTERPOLATE_AMPLITUDE(oldformantamp[j],
223                                                   currentformants[j].amp,
224                                                   i,
225                                                   buffersize);
226         else
227             for(int i = 0; i < buffersize; ++i)
228                 smp[i] += tmpbuf[i] * currentformants[j].amp;
229         oldformantamp[j] = currentformants[j].amp;
230     }
231 }
232