1
// ------------------------------------------------------------------------
2
// audiofx_filter.cpp: Routines for filter effects.
3
// Copyright (C) 1999,2004 Kai Vehmanen
6
// eca-style-version: 2
8
// This program is free software; you can redistribute it and/or modify
9
// it under the terms of the GNU General Public License as published by
10
// the Free Software Foundation; either version 2 of the License, or
11
// (at your option) any later version.
13
// This program is distributed in the hope that it will be useful,
14
// but WITHOUT ANY WARRANTY; without even the implied warranty of
15
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
// GNU General Public License for more details.
18
// You should have received a copy of the GNU General Public License
19
// along with this program; if not, write to the Free Software
20
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
// ------------------------------------------------------------------------
25
#include <kvu_utils.h>
27
#include "samplebuffer_iterators.h"
28
#include "sample-ops_impl.h"
29
#include "eca-logger.h"
30
#include "audiofx_filter.h"
33
EFFECT_FILTER::~EFFECT_FILTER(void)
37
EFFECT_BANDPASS::EFFECT_BANDPASS (CHAIN_OPERATOR::parameter_t centerf, CHAIN_OPERATOR::parameter_t w)
39
/* to avoid accessing uninitialized data */
44
set_parameter(1, centerf);
48
void EFFECT_BANDPASS::set_parameter(int param, CHAIN_OPERATOR::parameter_t value)
53
D = 2 * cos(2 * M_PI * center / (CHAIN_OPERATOR::parameter_t)samples_per_second());
57
if (value != 0) width = value;
58
else width = center / 2;
59
C = 1.0 / tan(M_PI * width / (CHAIN_OPERATOR::parameter_t)samples_per_second());
60
D = 2 * cos(2 * M_PI * center / (CHAIN_OPERATOR::parameter_t)samples_per_second());
61
a[0] = 1.0 / (1.0 + C);
65
b[1] = (C - 1.0) * a[0];
70
CHAIN_OPERATOR::parameter_t EFFECT_BANDPASS::get_parameter(int param) const
81
EFFECT_BANDREJECT::EFFECT_BANDREJECT (CHAIN_OPERATOR::parameter_t centerf, CHAIN_OPERATOR::parameter_t w)
83
set_parameter(1, centerf);
87
void EFFECT_BANDREJECT::set_parameter(int param, CHAIN_OPERATOR::parameter_t value)
92
D = 2 * cos(2 * M_PI * center / (CHAIN_OPERATOR::parameter_t)samples_per_second());
97
if (value != 0) width = value;
98
else width = center / 2;
99
C = tan(M_PI * width / (CHAIN_OPERATOR::parameter_t)samples_per_second());
100
a[0] = 1.0 / (1.0 + C);
104
b[1] = (1.0 - C) * a[0];
109
CHAIN_OPERATOR::parameter_t EFFECT_BANDREJECT::get_parameter(int param) const
120
void EFFECT_BW_FILTER::init(SAMPLE_BUFFER *insample)
124
set_channels(insample->number_of_channels());
126
sin.resize(insample->number_of_channels(), std::vector<SAMPLE_SPECS::sample_t> (2));
127
sout.resize(insample->number_of_channels(), std::vector<SAMPLE_SPECS::sample_t> (2));
130
void EFFECT_BW_FILTER::process(void)
134
outputSample = ecaops_flush_to_zero(a[0] * (*i.current()) +
135
a[1] * sin[i.channel()][0] +
136
a[2] * sin[i.channel()][1] -
137
b[0] * sout[i.channel()][0] -
138
b[1] * sout[i.channel()][1]);
139
sin[i.channel()][1] = sin[i.channel()][0];
140
sin[i.channel()][0] = *i.current();
142
sout[i.channel()][1] = sout[i.channel()][0];
143
sout[i.channel()][0] = outputSample;
145
*i.current() = outputSample;
150
void EFFECT_BW_FILTER::process_notused(SAMPLE_BUFFER* sbuf)
153
// while(sbuf->is_readable()) {
154
// outputSample = *sbuf->current_sample() * a[0]
161
// sin[0] = *(sbuf->current_sample());
163
// sout[1] = sout[0];
164
// sout[0] = outputSample;
166
// sbuf->current_sample()->operator=(outputSample);
171
void EFFECT_BW_FILTER::init_values(void)
173
// for(int j = 0; j < 2;j++) {
174
// sin[j].sample[SAMPLE_BUFFER::ch_left] = 0.0;
175
// sin[j].sample[SAMPLE_BUFFER::ch_right] = 0.0;
176
// sout[j].sample[SAMPLE_BUFFER::ch_left] = 0.0;
177
// sout[j].sample[SAMPLE_BUFFER::ch_right] = 0.0;
181
EFFECT_HIGHPASS::EFFECT_HIGHPASS (CHAIN_OPERATOR::parameter_t cutoff)
183
set_parameter(1, cutoff);
186
void EFFECT_HIGHPASS::set_parameter(int param, CHAIN_OPERATOR::parameter_t value)
191
C = tan(M_PI * cutOffFreq / (CHAIN_OPERATOR::parameter_t)samples_per_second());
192
a[0] = 1.0 / (1.0 + sqrt(2.0) * C + C * C);
195
b[0] = 2 * (C * C - 1.0) * a[0];
196
b[1] = (1.0 - sqrt(2.0) * C + C * C) * a[0];
201
CHAIN_OPERATOR::parameter_t EFFECT_HIGHPASS::get_parameter(int param) const
210
EFFECT_ALLPASS_FILTER::EFFECT_ALLPASS_FILTER (void)
211
: feedback_gain(0.0),
217
void EFFECT_ALLPASS_FILTER::set_parameter(int param, CHAIN_OPERATOR::parameter_t value)
222
// assert(inbuf.size() == outbuf.size());
223
for(int n = 0; n < static_cast<int>(inbuf.size()); n++) {
224
if (inbuf[n].size() > D) inbuf[n].resize(static_cast<unsigned int>(D));
225
// if (outbuf[n].size() > D) inbuf[n].resize(D);
229
feedback_gain = value / 100.0;
234
CHAIN_OPERATOR::parameter_t EFFECT_ALLPASS_FILTER::get_parameter(int param) const
240
return feedback_gain * 100.0;
245
void EFFECT_ALLPASS_FILTER::init(SAMPLE_BUFFER* insample)
249
set_channels(insample->number_of_channels());
251
inbuf.resize(insample->number_of_channels());
252
// outbuf.resize(insample->number_of_channels());
255
void EFFECT_ALLPASS_FILTER::process(void)
259
if (inbuf[i.channel()].size() >= D) {
260
inbuf[i.channel()].push_back(*i.current());
262
// *i.current() = -feedback_gain * (*i.current()) +
263
// inbuf[i.channel()].front() +
264
// feedback_gain * outbuf[i.channel()].front();
266
*i.current() = ecaops_flush_to_zero(-feedback_gain * (*i.current()) +
267
(feedback_gain * inbuf[i.channel()].front() +
269
(1.0 - feedback_gain * feedback_gain));
271
// feedback_gain * outbuf[i.channel()].front();
272
// outbuf[i.channel()].push_back(*i.current());
274
inbuf[i.channel()].pop_front();
275
// outbuf[i.channel()].pop_front();
278
inbuf[i.channel()].push_back(*i.current());
279
*i.current() = ecaops_flush_to_zero(*i.current() * (1.0 - feedback_gain));
280
// outbuf[i.channel()].push_back(*i.current());
286
EFFECT_COMB_FILTER::EFFECT_COMB_FILTER (int delay_in_samples, CHAIN_OPERATOR::parameter_t radius)
288
set_parameter(1, (CHAIN_OPERATOR::parameter_t)delay_in_samples);
289
set_parameter(2, radius);
292
void EFFECT_COMB_FILTER::set_parameter(int param, CHAIN_OPERATOR::parameter_t value)
298
std::vector<std::deque<SAMPLE_SPECS::sample_t> >::iterator p = buffer.begin();
299
while(p != buffer.end()) {
301
p->resize(static_cast<unsigned int>(C));
314
CHAIN_OPERATOR::parameter_t EFFECT_COMB_FILTER::get_parameter(int param) const
325
void EFFECT_COMB_FILTER::init(SAMPLE_BUFFER* insample)
329
set_channels(insample->number_of_channels());
331
buffer.resize(insample->number_of_channels());
334
void EFFECT_COMB_FILTER::process(void)
338
if (buffer[i.channel()].size() >= C) {
339
*i.current() = (*i.current()) + (pow(D, C) *
340
buffer[i.channel()].front());
341
buffer[i.channel()].push_back(*i.current());
342
buffer[i.channel()].pop_front();
345
buffer[i.channel()].push_back(*i.current());
351
EFFECT_INVERSE_COMB_FILTER::EFFECT_INVERSE_COMB_FILTER (int delay_in_samples, CHAIN_OPERATOR::parameter_t radius)
354
// delay in number of samples
357
set_parameter(1, (CHAIN_OPERATOR::parameter_t)delay_in_samples);
358
set_parameter(2, radius);
361
void EFFECT_INVERSE_COMB_FILTER::set_parameter(int param, CHAIN_OPERATOR::parameter_t value)
373
CHAIN_OPERATOR::parameter_t EFFECT_INVERSE_COMB_FILTER::get_parameter(int param) const
384
void EFFECT_INVERSE_COMB_FILTER::init(SAMPLE_BUFFER* insample)
388
set_channels(insample->number_of_channels());
390
buffer.resize(insample->number_of_channels());
391
laskuri.resize(insample->number_of_channels(), parameter_t(0.0));
394
void EFFECT_INVERSE_COMB_FILTER::process(void)
398
buffer[i.channel()].push_back(*i.current());
400
if (laskuri[i.channel()] >= C) {
401
*i.current() = (*i.current()) - (pow(D, C) *
402
buffer[i.channel()].front());
403
buffer[i.channel()].pop_front();
406
laskuri[i.channel()]++;
412
EFFECT_LOWPASS::EFFECT_LOWPASS (CHAIN_OPERATOR::parameter_t cutoff)
414
set_parameter(1, cutoff);
417
void EFFECT_LOWPASS::set_parameter(int param, CHAIN_OPERATOR::parameter_t value) {
420
set_cutoff(value, samples_per_second());
425
CHAIN_OPERATOR::parameter_t EFFECT_LOWPASS::get_parameter(int param) const
434
void EFFECT_LOWPASS::set_cutoff(CHAIN_OPERATOR::parameter_t value, long int srate)
437
C = 1.0 / tan(M_PI * cutOffFreq / (CHAIN_OPERATOR::parameter_t)srate);
438
a[0] = 1.0 / (1.0 + sqrt(2.0) * C + C * C);
441
b[0] = 2 * (1.0 - C * C) * a[0];
442
b[1] = (1.0 - sqrt(2.0) * C + C * C) * a[0];
445
EFFECT_LOWPASS_SIMPLE::EFFECT_LOWPASS_SIMPLE (CHAIN_OPERATOR::parameter_t cutoff)
447
set_parameter(1, cutoff);
450
void EFFECT_LOWPASS_SIMPLE::set_parameter(int param, CHAIN_OPERATOR::parameter_t value)
455
A = 2.0 * M_PI * cutOffFreq / samples_per_second();
456
B = exp(-A / samples_per_second());
461
CHAIN_OPERATOR::parameter_t EFFECT_LOWPASS_SIMPLE::get_parameter(int param) const
470
void EFFECT_LOWPASS_SIMPLE::init(SAMPLE_BUFFER *insample)
474
set_channels(insample->number_of_channels());
476
outhist.resize(insample->number_of_channels());
477
tempin.resize(insample->number_of_channels());
478
temphist.resize(insample->number_of_channels());
481
void EFFECT_LOWPASS_SIMPLE::process(void)
485
tempin[i.channel()] = *i.current();
486
temphist[i.channel()] = outhist[i.channel()];
487
outhist[i.channel()] = tempin[i.channel()];
489
tempin[i.channel()] *= A * 0.5;
490
temphist[i.channel()] *= B * 0.5;
492
*i.current() = ecaops_flush_to_zero(tempin[i.channel()] + temphist[i.channel()]);
498
EFFECT_RESONANT_BANDPASS::EFFECT_RESONANT_BANDPASS (CHAIN_OPERATOR::parameter_t centerf,
499
CHAIN_OPERATOR::parameter_t w)
501
/* to avoid accessing uninitialized data */
505
set_parameter(1, centerf);
509
void EFFECT_RESONANT_BANDPASS::set_parameter(int param, CHAIN_OPERATOR::parameter_t value)
516
if (value != 0) width = value;
517
else width = center / 2.0;
520
// R = 1.0 - M_PI * width / (CHAIN_OPERATOR::parameter_t)samples_per_second();
521
// R = 1.0 - ((width / (CHAIN_OPERATOR::parameter_t)samples_per_second()) / 2.0);
522
R = 1.0 - M_PI * (width / (CHAIN_OPERATOR::parameter_t)samples_per_second());
524
pole_angle = (((2.0 * R) / (1.0 + c)) * cos((center /
525
(CHAIN_OPERATOR::parameter_t)samples_per_second() * 2.0 * M_PI)));
526
pole_angle = acos(pole_angle);
527
a = (1.0 - c) * sin(pole_angle);
528
b = 2.0 * R * cos(pole_angle);
531
CHAIN_OPERATOR::parameter_t EFFECT_RESONANT_BANDPASS::get_parameter(int param) const
542
void EFFECT_RESONANT_BANDPASS::init(SAMPLE_BUFFER* insample)
546
set_channels(insample->number_of_channels());
548
outhist1.resize(insample->number_of_channels());
549
outhist2.resize(insample->number_of_channels());
552
void EFFECT_RESONANT_BANDPASS::process(void)
556
*i.current() = ecaops_flush_to_zero(a * (*i.current()) +
557
b * outhist1[i.channel()] -
558
c * outhist2[i.channel()]);
560
outhist2[i.channel()] = outhist1[i.channel()];
561
outhist1[i.channel()] = *i.current();
567
EFFECT_RESONANT_LOWPASS::EFFECT_RESONANT_LOWPASS (CHAIN_OPERATOR::parameter_t co, CHAIN_OPERATOR::parameter_t
568
res, CHAIN_OPERATOR::parameter_t g)
569
: ProtoCoef(2), Coef(2)
574
gain_orig = gain = g;
578
pi = 4.0 * atan(1.0);
581
// Setup filter s-domain coefficients
584
ProtoCoef[0].a0 = 1.0;
587
ProtoCoef[0].b0 = 1.0;
588
ProtoCoef[0].b1 = 0.765367 / Q; // Divide by resonance or Q
589
ProtoCoef[0].b2 = 1.0;
591
ProtoCoef[1].a0 = 1.0;
594
ProtoCoef[1].b0 = 1.0;
595
ProtoCoef[1].b1 = 1.847759 / Q; // Divide by resonance or Q
596
ProtoCoef[1].b2 = 1.0;
602
void EFFECT_RESONANT_LOWPASS::set_parameter(int param, CHAIN_OPERATOR::parameter_t value)
618
CHAIN_OPERATOR::parameter_t EFFECT_RESONANT_LOWPASS::get_parameter(int param) const
631
void EFFECT_RESONANT_LOWPASS::refresh_values(void)
633
if (cutoff == 0.0) cutoff = 0.1;
637
// ProtoCoef[0].a0 = 1.0;
640
// ProtoCoef[0].b0 = 1.0;
641
ProtoCoef[0].b1 = 0.765367 / Q; // Divide by resonance or Q
642
ProtoCoef[0].b2 = 1.0;
644
// ProtoCoef[1].a0 = 1.0;
647
// ProtoCoef[1].b0 = 1.0;
648
ProtoCoef[1].b1 = 1.847759 / Q; // Divide by resonance or Q
649
ProtoCoef[1].b2 = 1.0;
655
void EFFECT_RESONANT_LOWPASS::szxform(int section)
657
wp = 2.0 * (CHAIN_OPERATOR::parameter_t)samples_per_second() * tan(pi * cutoff / (CHAIN_OPERATOR::parameter_t)samples_per_second());
660
// a0 and b0 are presumed to be 1, so...
662
ProtoCoef[section].a2 = ProtoCoef[section].a2 / (wp * wp);
663
ProtoCoef[section].a1 = ProtoCoef[section].a1 / wp;
665
ProtoCoef[section].b2 = ProtoCoef[section].b2 / (wp * wp);
666
ProtoCoef[section].b1 = ProtoCoef[section].b1 / wp;
669
// alpha (Numerator in s-domain)
670
ad = 4.0 * ProtoCoef[section].a2 * (CHAIN_OPERATOR::parameter_t)samples_per_second() * (CHAIN_OPERATOR::parameter_t)samples_per_second() + 2.0 * ProtoCoef[section].a1
671
* (CHAIN_OPERATOR::parameter_t)samples_per_second() + ProtoCoef[section].a0;
673
// beta (Denominator in s-domain)
674
bd = 4.0 * ProtoCoef[section].b2 * (CHAIN_OPERATOR::parameter_t)samples_per_second() * (CHAIN_OPERATOR::parameter_t)samples_per_second() + 2.0 * ProtoCoef[section].b1
675
* (CHAIN_OPERATOR::parameter_t)samples_per_second() + ProtoCoef[section].b0;
678
/* update gain constant for this section */
683
Coef[section].A = (2.0 * ProtoCoef[section].b0 - 8.0 * ProtoCoef[section].b2
684
* (CHAIN_OPERATOR::parameter_t)samples_per_second() * (CHAIN_OPERATOR::parameter_t)samples_per_second()) / bd;
687
Coef[section].B = (4.0 * ProtoCoef[section].b2 * (CHAIN_OPERATOR::parameter_t)samples_per_second() * (CHAIN_OPERATOR::parameter_t)samples_per_second() - 2.0 * ProtoCoef[section].b1
688
* (CHAIN_OPERATOR::parameter_t)samples_per_second() + ProtoCoef[section].b0) / bd;
694
Coef[section].C = (2.0 * ProtoCoef[section].a0 - 8.0 * ProtoCoef[section].a2
695
* (CHAIN_OPERATOR::parameter_t)samples_per_second() * (CHAIN_OPERATOR::parameter_t)samples_per_second()) / ad;
698
Coef[section].D = (4.0 * ProtoCoef[section].a2 * (CHAIN_OPERATOR::parameter_t)samples_per_second() * (CHAIN_OPERATOR::parameter_t)samples_per_second() - 2.0
699
* ProtoCoef[section].a1 * (CHAIN_OPERATOR::parameter_t)samples_per_second() + ProtoCoef[section].a0) / ad;
704
void EFFECT_RESONANT_LOWPASS::init(SAMPLE_BUFFER* insample)
708
set_channels(insample->number_of_channels());
710
outhist0.resize(insample->number_of_channels());
711
outhist1.resize(insample->number_of_channels());
712
outhist2.resize(insample->number_of_channels());
713
outhist3.resize(insample->number_of_channels());
715
newhist0.resize(insample->number_of_channels());
716
newhist1.resize(insample->number_of_channels());
719
void EFFECT_RESONANT_LOWPASS::process(void)
723
*i.current() = (*i.current()) * gain;
729
*i.current() = (*i.current()) - outhist0[i.channel()] * Coef[0].A;
730
newhist0[i.channel()] = ecaops_flush_to_zero((*i.current()) - outhist1[i.channel()] * Coef[0].B);
733
*i.current() = newhist0[i.channel()] + outhist0[i.channel()] * Coef[0].C;
734
*i.current() = (*i.current()) + outhist1[i.channel()] * Coef[0].D;
736
outhist1[i.channel()] = outhist0[i.channel()];
737
outhist0[i.channel()] = newhist0[i.channel()];
743
*i.current() = (*i.current()) - outhist2[i.channel()] * Coef[1].A;
744
newhist1[i.channel()] = ecaops_flush_to_zero((*i.current()) - outhist3[i.channel()] * Coef[1].B);
747
*i.current() = newhist1[i.channel()] + outhist2[i.channel()] * Coef[1].C;
748
*i.current() = (*i.current()) + outhist3[i.channel()] * Coef[1].D;
750
outhist3[i.channel()] = outhist2[i.channel()];
751
outhist2[i.channel()] = newhist1[i.channel()];
757
// EFFECT_RESONANT_LOWPASS::EFFECT_RESONANT_LOWPASS (const
758
// EFFECT_RESONANT_LOWPASS& x)
759
// : outhist(4), newhist(2), ProtoCoef(2), Coef(2)
761
// outhist = x.outhist;
762
// newhist = x.newhist;
763
// for(vector<BIQUAD>::size_type p = 0; p != x.ProtoCoef.size(); p++) {
764
// ProtoCoef[p].a0 = x.ProtoCoef[p].a0;
765
// ProtoCoef[p].a1 = x.ProtoCoef[p].a1;
766
// ProtoCoef[p].a2 = x.ProtoCoef[p].a2;
767
// ProtoCoef[p].b0 = x.ProtoCoef[p].b0;
768
// ProtoCoef[p].b1 = x.ProtoCoef[p].b1;
769
// ProtoCoef[p].b2 = x.ProtoCoef[p].b2;
772
// for(vector<BIQUAD>::size_type p = 0; p != x.Coef.size(); p++) {
773
// Coef[p].A = x.Coef[p].A;
774
// Coef[p].B = x.Coef[p].B;
775
// Coef[p].C = x.Coef[p].C;
776
// Coef[p].D = x.Coef[p].D;
779
// cutoff = x.cutoff;
782
// gain_orig = x.gain_orig;
784
// laskuri = x.laskuri;
790
EFFECT_RESONATOR::EFFECT_RESONATOR (CHAIN_OPERATOR::parameter_t centerf, CHAIN_OPERATOR::parameter_t w)
793
/* to avoid accessing uninitialized data */
797
set_parameter(1, centerf);
801
void EFFECT_RESONATOR::set_parameter(int param, CHAIN_OPERATOR::parameter_t value)
808
if (value != 0) width = value;
809
else width = center / 2;
812
conb[1] = exp(-(2 * M_PI) * (width / (CHAIN_OPERATOR::parameter_t)samples_per_second()));
813
conb[0] = (-4.0 * conb[1]) / (1.0 + conb[1]) * cos(2 * M_PI * (center / (CHAIN_OPERATOR::parameter_t)samples_per_second()));
814
cona[0] = (1.0 - conb[1]) * sqrt(1.0 - (conb[0] * conb[0]) / (4.0 * conb[1]));
817
CHAIN_OPERATOR::parameter_t EFFECT_RESONATOR::get_parameter(int param) const {
827
void EFFECT_RESONATOR::init(SAMPLE_BUFFER* insample) {
830
set_channels(insample->number_of_channels());
832
saout0.resize(insample->number_of_channels());
833
saout1.resize(insample->number_of_channels());
836
void EFFECT_RESONATOR::process(void)
840
*i.current() = cona[0] * (*i.current()) -
841
conb[0] * saout0[i.channel()] -
842
conb[1] * saout1[i.channel()];
844
saout1[i.channel()] = saout0[i.channel()];
845
saout0[i.channel()] = ecaops_flush_to_zero(*i.current());