getdetune() coding style cleanup
[zyn.git] / formant_filter.cpp
blobb472cca0ddb6cb9f54fdc96c7dd650deabe7cc1e
1 /*
2 ZynAddSubFX - a software synthesizer
4 FormantFilter.C - formant filters
5 Copyright (C) 2002-2005 Nasca Octavian Paul
6 Author: Nasca Octavian Paul
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of version 2 of the GNU General Public License
10 as published by the Free Software Foundation.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License (version 2) for more details.
17 You should have received a copy of the GNU General Public License (version 2)
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <math.h>
24 #include <stdio.h>
26 #include "globals.h"
27 #include "filter_base.h"
28 #include "analog_filter.h"
29 #include "filter_parameters.h"
30 #include "formant_filter.h"
32 void FormantFilter::init(float sample_rate, FilterParams *pars)
34 int i, j;
36 m_numformants = pars->Pnumformants;
38 for (i = 0 ; i < m_numformants ; i++)
40 m_formants[i].init(sample_rate, ZYN_FILTER_ANALOG_TYPE_BPF2, 1000.0, 10.0, pars->m_additional_stages, 0.0);
43 cleanup();
45 for (j = 0 ; j < FF_MAX_VOWELS ; j++)
47 for (i = 0 ; i < m_numformants ; i++)
49 m_formantpar[j][i].frequency = pars->getformantfreq(pars->Pvowels[j].formants[i].freq);
50 m_formantpar[j][i].amplitude = pars->getformantamp(pars->Pvowels[j].formants[i].amp);
51 m_formantpar[j][i].q_factor = pars->getformantq(pars->Pvowels[j].formants[i].q);
55 for (i = 0 ; i < FF_MAX_FORMANTS ; i++)
57 m_oldformantamp[i] = 1.0;
60 for (i = 0 ; i < m_numformants ; i++)
62 m_currentformants[i].frequency = 1000.0;
63 m_currentformants[i].amplitude = 1.0;
64 m_currentformants[i].q_factor = 2.0;
67 m_formantslowness = pow(1.0 - pars->Pformantslowness / 128.0, 3.0);
69 m_sequencesize = pars->Psequencesize;
70 if (m_sequencesize == 0)
72 m_sequencesize = 1;
75 for (i = 0 ; i < m_sequencesize ; i++)
77 m_sequence[i].nvowel = pars->Psequence[i].nvowel;
80 m_vowelclearness = pow(10.0, (pars->Pvowelclearness - 32.0) / 48.0);
82 m_sequencestretch = pow(0.1, (pars->Psequencestretch - 32.0) / 48.0);
83 if (pars->Psequencereversed)
85 m_sequencestretch *= -1.0;
88 m_outgain = dB2rap(pars->m_gain);
90 m_oldinput = -1.0;
92 m_Qfactor = 1.0;
93 m_oldQfactor = m_Qfactor;
95 m_firsttime = 1;
98 void FormantFilter::cleanup()
100 int i;
102 for (i = 0 ; i < m_numformants ; i++)
104 m_formants[i].cleanup();
108 void FormantFilter::setpos(float input)
110 int p1;
111 int p2;
112 float pos;
113 int i;
115 if (m_firsttime != 0)
117 m_slowinput = input;
119 else
121 m_slowinput = m_slowinput * (1.0 - m_formantslowness) + input * m_formantslowness;
124 if ((fabs(m_oldinput - input) < 0.001) &&
125 (fabs(m_slowinput - input) < 0.001) &&
126 (fabs(m_Qfactor - m_oldQfactor) < 0.001))
128 // m_oldinput = input; // daca setez asta, o sa faca probleme la schimbari foarte lente
129 m_firsttime=0;
130 return;
132 else
134 m_oldinput = input;
137 pos = fmod(input * m_sequencestretch, 1.0);
138 if (pos < 0.0)
140 pos += 1.0;
143 F2I(pos * m_sequencesize, p2);
144 p1 = p2 - 1;
145 if (p1 < 0)
147 p1 += m_sequencesize;
150 pos = fmod(pos * m_sequencesize, 1.0);
151 if (pos < 0.0)
153 pos = 0.0;
155 else if (pos > 1.0)
157 pos = 1.0;
159 pos = (atan((pos * 2.0 - 1.0) * m_vowelclearness) / atan(m_vowelclearness) + 1.0) * 0.5;
161 p1 = m_sequence[p1].nvowel;
162 p2 = m_sequence[p2].nvowel;
164 if (m_firsttime != 0)
166 for (i = 0 ; i < m_numformants ; i++)
168 m_currentformants[i].frequency = m_formantpar[p1][i].frequency * (1.0 - pos) + m_formantpar[p2][i].frequency*pos;
169 m_currentformants[i].amplitude = m_formantpar[p1][i].amplitude * (1.0 - pos) + m_formantpar[p2][i].amplitude*pos;
170 m_currentformants[i].q_factor = m_formantpar[p1][i].q_factor*(1.0 - pos) + m_formantpar[p2][i].q_factor * pos;
171 m_formants[i].setfreq_and_q(m_currentformants[i].frequency, m_currentformants[i].q_factor * m_Qfactor);
172 m_oldformantamp[i] = m_currentformants[i].amplitude;
175 m_firsttime = 0;
177 else
179 for (i = 0 ; i < m_numformants ; i++)
181 m_currentformants[i].frequency = m_currentformants[i].frequency * (1.0 - m_formantslowness)
182 + (m_formantpar[p1][i].frequency * (1.0 - pos) + m_formantpar[p2][i].frequency * pos) * m_formantslowness;
184 m_currentformants[i].amplitude = m_currentformants[i].amplitude * (1.0 - m_formantslowness)
185 + (m_formantpar[p1][i].amplitude * (1.0 - pos) + m_formantpar[p2][i].amplitude * pos) * m_formantslowness;
187 m_currentformants[i].q_factor = m_currentformants[i].q_factor * (1.0 - m_formantslowness)
188 + (m_formantpar[p1][i].q_factor * (1.0 - pos) + m_formantpar[p2][i].q_factor * pos) * m_formantslowness;
190 m_formants[i].setfreq_and_q(m_currentformants[i].frequency, m_currentformants[i].q_factor * m_Qfactor);
194 m_oldQfactor = m_Qfactor;
197 void FormantFilter::setfreq(float frequency)
199 setpos(frequency);
202 void FormantFilter::setq(float q_)
204 int i;
206 m_Qfactor = q_;
208 for (i = 0 ; i < m_numformants ; i++)
210 m_formants[i].setq(m_Qfactor * m_currentformants[i].q_factor);
214 void FormantFilter::setfreq_and_q(float frequency, float q_)
216 m_Qfactor = q_;
217 setpos(frequency);
220 void FormantFilter::filterout(float *smp)
222 int i;
223 int j;
225 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
227 m_inbuffer[i] = smp[i];
228 smp[i] = 0.0;
231 for (j = 0 ; j < m_numformants ; j++)
233 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
235 m_tmpbuf[i] = m_inbuffer[i] * m_outgain;
238 m_formants[j].filterout(m_tmpbuf);
240 if (ABOVE_AMPLITUDE_THRESHOLD(m_oldformantamp[j], m_currentformants[j].amplitude))
242 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
244 smp[i] += m_tmpbuf[i] * INTERPOLATE_AMPLITUDE(m_oldformantamp[j], m_currentformants[j].amplitude, i, SOUND_BUFFER_SIZE);
247 else
249 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
251 smp[i] += m_tmpbuf[i] * m_currentformants[j].amplitude;
255 m_oldformantamp[j] = m_currentformants[j].amplitude;