Expose all 8 voices
[zyn.git] / sv_filter.cpp
blob529d41bc9545ab90aa17bf8b43ae6f6e89259f73
1 /*
2 ZynAddSubFX - a software synthesizer
4 SVFilter.C - Several state-variable 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>
25 #include <assert.h>
27 #include "globals.h"
28 #include "filter_base.h"
29 #include "sv_filter.h"
31 void SVFilter::init(float sample_rate, int type, REALTYPE Ffreq, REALTYPE Fq, unsigned char Fstages, float gain)
33 m_sample_rate = sample_rate;
34 stages = Fstages;
35 m_type = type;
36 freq = Ffreq;
37 q = Fq;
38 m_gain = 1.0;
39 m_outgain = 1.0;
40 needsinterpolation = 0;
41 firsttime = 1;
43 if (stages >= MAX_FILTER_STAGES)
45 stages = MAX_FILTER_STAGES;
48 cleanup();
49 setfreq_and_q(Ffreq,Fq);
51 m_outgain = dB2rap(gain);
52 if (m_outgain > 1.0)
54 m_outgain = sqrt(m_outgain);
58 void SVFilter::cleanup()
60 int i;
62 for (i = 0 ; i < MAX_FILTER_STAGES + 1 ; i++)
64 st[i].low = 0.0;
65 st[i].high = 0.0;
66 st[i].band = 0.0;
67 st[i].notch = 0.0;
70 oldabovenq = 0;
72 abovenq = 0;
75 void SVFilter::computefiltercoefs()
77 par.f = freq / m_sample_rate * 4.0;
79 if (par.f > 0.99999)
81 par.f = 0.99999;
84 par.q = 1.0 - atan(sqrt(q)) * 2.0 / PI;
85 par.q = pow(par.q, 1.0 / (stages + 1));
86 par.q_sqrt = sqrt(par.q);
89 void SVFilter::setfreq(REALTYPE frequency)
91 REALTYPE rap;
92 int nyquistthresh;
94 if (frequency < 0.1)
96 frequency = 0.1;
99 rap = freq / frequency;
100 if (rap < 1.0)
102 rap = 1.0 / rap;
105 oldabovenq = abovenq;
106 abovenq = frequency > (m_sample_rate / 2 - 500.0);
108 nyquistthresh = (abovenq ^ oldabovenq);
110 if (rap > 3.0 || nyquistthresh != 0)
112 // if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup)
113 if (firsttime == 0)
115 needsinterpolation = 1;
118 ipar = par;
121 freq = frequency;
123 computefiltercoefs();
125 firsttime = 0;
128 void SVFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_)
130 q = q_;
132 setfreq(frequency);
135 void SVFilter::setq(REALTYPE q_)
137 q = q_;
138 computefiltercoefs();
141 void SVFilter::settype(int type)
143 m_type = type;
145 computefiltercoefs();
148 void SVFilter::setgain(REALTYPE dBgain)
150 m_gain = dB2rap(dBgain);
151 computefiltercoefs();
154 void SVFilter::setstages(int stages_)
156 if (stages_ >= MAX_FILTER_STAGES)
158 stages_ = MAX_FILTER_STAGES - 1;
161 stages=stages_;
163 cleanup();
165 computefiltercoefs();
168 void SVFilter::singlefilterout(REALTYPE *smp,fstage &x,parameters &par)
170 int i;
171 REALTYPE *out=NULL;
173 switch(m_type)
175 case ZYN_FILTER_SV_TYPE_LOWPASS:
176 out = &x.low;
177 break;
178 case ZYN_FILTER_SV_TYPE_HIGHPASS:
179 out = &x.high;
180 break;
181 case ZYN_FILTER_SV_TYPE_BANDPASS:
182 out = &x.band;
183 break;
184 case ZYN_FILTER_SV_TYPE_NOTCH:
185 out = &x.notch;
186 break;
187 default:
188 assert(0);
189 return;
192 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
194 x.low = x.low + par.f * x.band;
195 x.high = par.q_sqrt * smp[i] - x.low - par.q * x.band;
196 x.band = par.f * x.high + x.band;
197 x.notch = x.high + x.low;
199 smp[i] = *out;
203 void SVFilter::filterout(REALTYPE *smp)
205 int i;
206 REALTYPE x;
208 if (needsinterpolation != 0)
210 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
212 m_ismp[i] = smp[i];
215 for (i=0 ; i < stages + 1 ; i++)
217 singlefilterout(m_ismp, st[i], ipar);
221 for (i = 0 ; i < stages + 1 ; i++)
223 singlefilterout(smp, st[i], par);
226 if (needsinterpolation != 0)
228 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
230 x = i / (REALTYPE)SOUND_BUFFER_SIZE;
231 smp[i] = m_ismp[i] * (1.0 - x) + smp[i] * x;
234 needsinterpolation = 0;
237 for (i = 0 ; i < SOUND_BUFFER_SIZE ; i++)
239 smp[i] *= m_outgain;