Minot coding style fix
[zyn.git] / filter_parameters.cpp
blob06d7c9c87dd32f4283ee65a2f835b21ec26be250
1 /*
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
23 #include <math.h>
25 #include "globals.h"
26 #include "filter_parameters.h"
28 void FilterParams::init(
29 float sample_rate,
30 unsigned char Ptype_,
31 unsigned char Pfreq_,
32 unsigned char Pq_)
34 m_sample_rate = sample_rate;
36 Dtype=Ptype_;
37 Dfreq=Pfreq_;
38 Dq=Pq_;
40 defaults();
43 void FilterParams::defaults(){
44 Ptype=Dtype;
45 Pfreq=Dfreq;
46 Pq=Dq;
48 m_additional_stages = 0;
49 m_frequency_tracking = 0;
50 m_gain = 0;
51 m_category = ZYN_FILTER_TYPE_ANALOG;
53 Pnumformants=3;
54 Pformantslowness=64;
55 for (int j=0;j<FF_MAX_VOWELS;j++){
56 defaults(j);
59 Psequencesize=3;
60 for (int i=0;i<FF_MAX_SEQUENCE;i++) Psequence[i].nvowel=i%FF_MAX_VOWELS;
62 Psequencestretch=40;
63 Psequencereversed=0;
64 Pcenterfreq=64;//1 kHz
65 Poctavesfreq=64;
66 Pvowelclearness=64;
69 void FilterParams::defaults(int n){
70 int j=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;
79 * Parameter control
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){
111 if (x>1.0) x=1.0;
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)
129 REALTYPE c[3],d[3];
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;
153 sn=sin(omega);
154 cs=cos(omega);
155 alpha=sn/(2*filter_q);
156 REALTYPE tmp=1+alpha;
157 c[0]=alpha/tmp*sqrt(filter_q+1);
158 c[1]=0;
159 c[2]=-alpha/tmp*sqrt(filter_q+1);
160 d[1]=-2*cs/tmp*(-1);
161 d[2]=(1-alpha)/tmp*(-1);
163 else
165 continue;
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++)
175 freqs[tmp] = 0.0;
178 break;
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++){
184 x+=cos(n*fr)*c[n];
185 y-=sin(n*fr)*c[n];
187 REALTYPE h=x*x+y*y;
188 x=1.0;y=0.0;
189 for (int n=1;n<3;n++){
190 x-=cos(n*fr)*d[n];
191 y+=sin(n*fr)*d[n];
193 h=h/(x*x+y*y);
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;
200 else freqs[i]=-90.0;
206 * Transforms a parameter to the real value
208 REALTYPE FilterParams::getformantfreq(unsigned char freq){
209 REALTYPE result=getfreqx(freq/127.0);
210 return(result);
213 REALTYPE FilterParams::getformantamp(unsigned char amp){
214 REALTYPE result=pow(0.1,(1.0-amp/127.0)*4.0);
215 return(result);
218 REALTYPE FilterParams::getformantq(unsigned char q){
219 //temp
220 REALTYPE result=pow(25.0,(q-32.0)/64.0);
221 return(result);