2 ZynAddSubFX - a software synthesizer
4 AnalogFilter.C - Several analog filters (lowpass, highpass...)
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
28 #include "filter_base.h"
29 #include "analog_filter.h"
37 unsigned char Fstages
,
42 m_sample_rate
= sample_rate
;
44 m_additional_stages
= Fstages
;
46 for (i
= 0 ; i
< 3 ; i
++)
62 if (m_additional_stages
>= MAX_FILTER_STAGES
)
64 m_additional_stages
= MAX_FILTER_STAGES
;
72 m_old_above_nq
= false;
74 setfreq_and_q(Ffreq
, Fq
);
78 m_d
[0] = 0; // this is not used
81 if (Ftype
>= ZYN_FILTER_ANALOG_TYPE_PKF2
&&
82 Ftype
<= ZYN_FILTER_ANALOG_TYPE_HSH2
)
88 m_outgain
= dB2rap(gain
);
93 AnalogFilter::cleanup()
97 for (i
=0 ; i
< MAX_FILTER_STAGES
+ 1 ; i
++)
109 m_needs_interpolation
= false;
113 AnalogFilter::computefiltercoefs()
116 float omega
, sn
, cs
, alpha
, beta
;
117 int zerocoefs
= 0; // this is used if the freq is too high
121 // do not allow frequencies bigger than samplerate/2
124 if (freq
> m_sample_rate
/ 2 - 500.0)
126 freq
= m_sample_rate
/ 2 - 500.0;
135 // do not allow bogus Q
136 if (m_q_factor
< 0.0)
141 if (m_additional_stages
== 0)
148 tmpq
= (m_q_factor
> 1.0 ? pow(m_q_factor
, 1.0 / (m_additional_stages
+ 1)) : m_q_factor
);
149 tmpgain
= pow(m_gain
, 1.0 / (m_additional_stages
+ 1));
152 // most of theese are implementations of
153 // the "Cookbook formulae for audio EQ" by Robert Bristow-Johnson
154 // The original location of the Cookbook is:
155 // http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
158 case ZYN_FILTER_ANALOG_TYPE_LPF1
:
161 tmp
= exp(-2.0 * PI
* freq
/ m_sample_rate
);
179 case ZYN_FILTER_ANALOG_TYPE_HPF1
:
182 tmp
= exp(-2.0 * PI
* freq
/ m_sample_rate
);
189 m_c
[0] = (1.0 + tmp
) / 2.0;
190 m_c
[1] = -(1.0 + tmp
) / 2.0;
200 case ZYN_FILTER_ANALOG_TYPE_LPF2
:
203 omega
= 2 * PI
* freq
/ m_sample_rate
;
206 alpha
= sn
/ (2 * tmpq
);
208 m_c
[0] = (1.0 - cs
) / 2.0 / tmp
;
209 m_c
[1] = (1.0 - cs
) / tmp
;
210 m_c
[2] = (1.0 - cs
) / 2.0 / tmp
;
211 m_d
[1] = -2 * cs
/ tmp
* (-1);
212 m_d
[2] = (1 - alpha
) / tmp
* (-1);
228 case ZYN_FILTER_ANALOG_TYPE_HPF2
:
231 omega
= 2 * PI
* freq
/ m_sample_rate
;
234 alpha
= sn
/ (2 * tmpq
);
236 m_c
[0] = (1.0 + cs
) / 2.0 / tmp
;
237 m_c
[1] = -(1.0 + cs
) / tmp
;
238 m_c
[2] = (1.0 + cs
) / 2.0 / tmp
;
239 m_d
[1] = -2 * cs
/ tmp
* (-1);
240 m_d
[2] = (1 - alpha
) / tmp
* (-1);
256 case ZYN_FILTER_ANALOG_TYPE_BPF2
:
259 omega
= 2 * PI
* freq
/ m_sample_rate
;
262 alpha
= sn
/ (2 * tmpq
);
264 m_c
[0] = alpha
/ tmp
* sqrt(tmpq
+ 1);
266 m_c
[2] = -alpha
/ tmp
* sqrt(tmpq
+ 1);
267 m_d
[1] = -2 * cs
/ tmp
* (-1);
268 m_d
[2] = (1 - alpha
) / tmp
* (-1);
284 case ZYN_FILTER_ANALOG_TYPE_NF2
:
287 omega
= 2 * PI
* freq
/ m_sample_rate
;
290 alpha
= sn
/ (2 * sqrt(tmpq
));
293 m_c
[1] = -2 * cs
/ tmp
;
295 m_d
[1] = -2 * cs
/ tmp
* (-1);
296 m_d
[2] = (1 - alpha
) / tmp
* (-1);
311 case ZYN_FILTER_ANALOG_TYPE_PKF2
:
314 omega
= 2 * PI
* freq
/ m_sample_rate
;
318 alpha
= sn
/ (2 * tmpq
);
319 tmp
= 1 + alpha
/ tmpgain
;
320 m_c
[0] = (1.0 + alpha
* tmpgain
) / tmp
;
321 m_c
[1] = (-2.0 * cs
) / tmp
;
322 m_c
[2] = (1.0 - alpha
* tmpgain
) / tmp
;
323 m_d
[1] = -2 * cs
/ tmp
* (-1);
324 m_d
[2] = (1 - alpha
/ tmpgain
) / tmp
* (-1);
340 case ZYN_FILTER_ANALOG_TYPE_LSH2
:
343 omega
= 2 * PI
* freq
/ m_sample_rate
;
347 alpha
= sn
/ (2 * tmpq
);
348 beta
= sqrt(tmpgain
) / tmpq
;
349 tmp
= (tmpgain
+ 1.0) + (tmpgain
- 1.0) * cs
+ beta
* sn
;
351 m_c
[0] = tmpgain
* ((tmpgain
+ 1.0) - (tmpgain
- 1.0) * cs
+ beta
* sn
) / tmp
;
352 m_c
[1] = 2.0 * tmpgain
* ((tmpgain
- 1.0) - (tmpgain
+ 1.0) * cs
) / tmp
;
353 m_c
[2] = tmpgain
* ((tmpgain
+ 1.0) - (tmpgain
- 1.0) * cs
- beta
* sn
) / tmp
;
354 m_d
[1] = -2.0 * ((tmpgain
- 1.0) + (tmpgain
+ 1.0) * cs
) / tmp
* (-1);
355 m_d
[2] = ((tmpgain
+ 1.0) + (tmpgain
- 1.0) * cs
- beta
* sn
) / tmp
* (-1);
371 case ZYN_FILTER_ANALOG_TYPE_HSH2
:
374 omega
= 2 * PI
* freq
/ m_sample_rate
;
378 alpha
= sn
/ (2 * tmpq
);
379 beta
= sqrt(tmpgain
) / tmpq
;
380 tmp
= (tmpgain
+ 1.0) - (tmpgain
- 1.0) * cs
+ beta
* sn
;
382 m_c
[0] = tmpgain
* ((tmpgain
+ 1.0) + (tmpgain
- 1.0) * cs
+ beta
* sn
) / tmp
;
383 m_c
[1] = -2.0 * tmpgain
* ((tmpgain
- 1.0) + (tmpgain
+ 1.0) * cs
) / tmp
;
384 m_c
[2] = tmpgain
* ((tmpgain
+ 1.0) + (tmpgain
- 1.0) * cs
- beta
* sn
) / tmp
;
385 m_d
[1] = 2.0 * ((tmpgain
- 1.0) - (tmpgain
+ 1.0) * cs
) / tmp
* (-1);
386 m_d
[2] = ((tmpgain
+ 1.0) - (tmpgain
- 1.0) * cs
- beta
* sn
) / tmp
* (-1);
403 assert(0); // wrong type
409 AnalogFilter::setfreq(float frequency
)
420 rap
= m_frequency
/ frequency
;
426 m_old_above_nq
= m_above_nq
;
427 m_above_nq
= frequency
> (m_sample_rate
/ 2 - 500.0);
429 nyquist_thresh
= ZYN_BOOL_XOR(m_above_nq
, m_old_above_nq
);
431 // if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup)
432 if (rap
> 3.0 || nyquist_thresh
)
434 for (i
= 0 ; i
< 3 ; i
++)
440 for (i
= 0 ; i
< MAX_FILTER_STAGES
+ 1 ; i
++)
448 m_needs_interpolation
= true;
452 m_frequency
= frequency
;
454 computefiltercoefs();
456 m_first_time
= false;
459 void AnalogFilter::setfreq_and_q(float frequency
, float q_factor
)
461 m_q_factor
= q_factor
;
466 void AnalogFilter::setq(float q_factor
)
468 m_q_factor
= q_factor
;
470 computefiltercoefs();
473 void AnalogFilter::settype(int type
)
477 computefiltercoefs();
480 void AnalogFilter::setgain(float dBgain
)
482 m_gain
= dB2rap(dBgain
);
484 computefiltercoefs();
487 void AnalogFilter::setstages(int additional_stages
)
489 if (additional_stages
>= MAX_FILTER_STAGES
)
491 m_additional_stages
= MAX_FILTER_STAGES
- 1;
495 m_additional_stages
= additional_stages
;
500 computefiltercoefs();
504 AnalogFilter::singlefilterout(
506 struct analog_filter_stage
* x
,
507 struct analog_filter_stage
* y
,
514 if (m_order
== 1) // First order filter
516 for (i
=0 ; i
< SOUND_BUFFER_SIZE
; i
++)
518 y0
= smp
[i
] * c
[0] + x
->c1
* c
[1] + y
->c1
* d
[1];
526 if (m_order
== 2) // Second order filter
528 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
530 y0
= smp
[i
] * c
[0] + x
->c1
* c
[1] + x
->c2
* c
[2] + y
->c1
* d
[1] + y
->c2
* d
[2];
541 void AnalogFilter::filterout(float *smp
)
546 if (m_needs_interpolation
)
548 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
550 m_interpolation_buffer
[i
] = smp
[i
];
553 for (i
= 0 ; i
< 1 + m_additional_stages
; i
++)
555 singlefilterout(m_interpolation_buffer
, m_x_old
+ i
, m_y_old
+ i
, m_c_old
, m_d_old
);
559 for (i
= 0 ; i
< 1 + m_additional_stages
; i
++)
561 singlefilterout(smp
, m_x
+ i
, m_y
+ i
, m_c
, m_d
);
564 if (m_needs_interpolation
)
566 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
568 x
= i
/ (float)SOUND_BUFFER_SIZE
;
569 smp
[i
] = m_interpolation_buffer
[i
] * (1.0 - x
) + smp
[i
] * x
;
572 m_needs_interpolation
= false;
575 for (i
= 0 ; i
< SOUND_BUFFER_SIZE
; i
++)
582 AnalogFilter::H(float freq
)
590 fr
= freq
/ m_sample_rate
* PI
* 2.0;
594 for (n
= 1 ; n
< 3 ; n
++)
596 x
+= cos(n
* fr
) * m_c
[n
];
597 y
-= sin(n
* fr
) * m_c
[n
];
605 for (n
= 1 ; n
< 3 ; n
++)
607 x
-= cos(n
* fr
) * m_d
[n
];
608 y
+= sin(n
* fr
) * m_d
[n
];
611 h
= h
/ (x
* x
+ y
* y
);
613 return pow(h
, (m_additional_stages
+ 1.0) / 2.0);