2 ZynAddSubFX - a software synthesizer
4 FilterParams.C - Parameters for filter
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
26 #include "filter_parameters.h"
28 void FilterParams::init(
34 m_sample_rate
= sample_rate
;
43 void FilterParams::defaults(){
48 m_additional_stages
= 0;
49 m_frequency_tracking
= 0;
51 m_category
= ZYN_FILTER_TYPE_ANALOG
;
55 for (int j
=0;j
<FF_MAX_VOWELS
;j
++){
60 for (int i
=0;i
<FF_MAX_SEQUENCE
;i
++) Psequence
[i
].nvowel
=i
%FF_MAX_VOWELS
;
64 Pcenterfreq
=64;//1 kHz
69 void FilterParams::defaults(int n
){
71 for (int i
=0;i
<FF_MAX_FORMANTS
;i
++){
72 Pvowels
[j
].formants
[i
].freq
=(int)(RND
*127.0);//some random freqs
73 Pvowels
[j
].formants
[i
].q
=64;
74 Pvowels
[j
].formants
[i
].amp
=127;
81 REALTYPE
FilterParams::getfreq(){
82 return((Pfreq
/64.0-1.0)*5.0);
85 REALTYPE
FilterParams::getq(){
86 return(exp(pow((REALTYPE
) Pq
/127.0,2)*log(1000.0))-0.9);
88 REALTYPE
FilterParams::getfreqtracking(REALTYPE notefreq
)
90 return log(notefreq
/ 440.0) * m_frequency_tracking
/ LOG_2
;
94 * Get the center frequency of the formant's graph
96 REALTYPE
FilterParams::getcenterfreq(){
97 return(10000.0*pow(10,-(1.0-Pcenterfreq
/127.0)*2.0));
101 * Get the number of octave that the formant functions applies to
103 REALTYPE
FilterParams::getoctavesfreq(){
104 return(0.25+10.0*Poctavesfreq
/127.0);
108 * Get the frequency from x, where x is [0..1]
110 REALTYPE
FilterParams::getfreqx(REALTYPE x
){
112 REALTYPE octf
=pow(2.0,getoctavesfreq());
113 return(getcenterfreq()/sqrt(octf
)*pow(octf
,x
));
117 * Get the x coordinate from frequency (used by the UI)
119 REALTYPE
FilterParams::getfreqpos(REALTYPE freq
){
120 return((log(freq
)-log(getfreqx(0.0)))/log(2.0)/getoctavesfreq());
125 * Get the freq. response of the formant filter
127 void FilterParams::formantfilterH(int nvowel
,int nfreqs
,REALTYPE
*freqs
)
130 REALTYPE filter_freq
,filter_q
,filter_amp
;
131 REALTYPE omega
,sn
,cs
,alpha
;
133 for (int i
=0;i
<nfreqs
;i
++) freqs
[i
]=0.0;
135 //for each formant...
136 for (int nformant
=0;nformant
<Pnumformants
;nformant
++)
138 //compute formant parameters(frequency,amplitude,etc.)
139 filter_freq
=getformantfreq(Pvowels
[nvowel
].formants
[nformant
].freq
);
140 filter_q
=getformantq(Pvowels
[nvowel
].formants
[nformant
].q
)*getq();
142 if (m_additional_stages
> 0)
144 filter_q
= (filter_q
> 1.0 ? pow(filter_q
, 1.0 / (m_additional_stages
+ 1)) : filter_q
);
147 filter_amp
=getformantamp(Pvowels
[nvowel
].formants
[nformant
].amp
);
150 if (filter_freq
<= (m_sample_rate
/ 2 - 100.0))
152 omega
= 2 * PI
* filter_freq
/ m_sample_rate
;
155 alpha
=sn
/(2*filter_q
);
156 REALTYPE tmp
=1+alpha
;
157 c
[0]=alpha
/tmp
*sqrt(filter_q
+1);
159 c
[2]=-alpha
/tmp
*sqrt(filter_q
+1);
161 d
[2]=(1-alpha
)/tmp
*(-1);
168 for (int i
=0;i
<nfreqs
;i
++) {
169 REALTYPE freq
=getfreqx(i
/(REALTYPE
) nfreqs
);
171 if (freq
> m_sample_rate
/ 2)
173 for (int tmp
= i
; tmp
< nfreqs
; tmp
++)
181 REALTYPE fr
= freq
/ m_sample_rate
* PI
* 2.0;
182 REALTYPE x
=c
[0],y
=0.0;
183 for (int n
=1;n
<3;n
++){
189 for (int n
=1;n
<3;n
++){
195 freqs
[i
] += pow(h
, (m_additional_stages
+ 1.0) / 2.0) * filter_amp
;
198 for (int i
=0;i
<nfreqs
;i
++) {
199 if (freqs
[i
]>0.000000001) freqs
[i
]=rap2dB(freqs
[i
]) + m_gain
;
206 * Transforms a parameter to the real value
208 REALTYPE
FilterParams::getformantfreq(unsigned char freq
){
209 REALTYPE result
=getfreqx(freq
/127.0);
213 REALTYPE
FilterParams::getformantamp(unsigned char amp
){
214 REALTYPE result
=pow(0.1,(1.0-amp
/127.0)*4.0);
218 REALTYPE
FilterParams::getformantq(unsigned char q
){
220 REALTYPE result
=pow(25.0,(q
-32.0)/64.0);