[SCM] calf/master: + Biquads: separate the biquad template into coefficients, direct-I form biquad and direct-II form biquad
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:38:17 UTC 2013
The following commit has been merged in the master branch:
commit 43417280324d6a8634090b43c1fa00453a608621
Author: Krzysztof Foltman <wdev at foltman.com>
Date: Mon Nov 3 20:00:36 2008 +0000
+ Biquads: separate the biquad template into coefficients, direct-I form biquad and direct-II form biquad
diff --git a/src/benchmark.cpp b/src/benchmark.cpp
index 1fef413..645862c 100644
--- a/src/benchmark.cpp
+++ b/src/benchmark.cpp
@@ -51,12 +51,13 @@ struct empty_benchmark
double scaler() { return BUF_SIZE; }
};
+template<class filter_class>
struct filter_lp24dB_benchmark
{
enum { BUF_SIZE = 256 };
float buffer[BUF_SIZE];
float result;
- dsp::biquad<float> biquad, biquad2;
+ filter_class biquad, biquad2;
void prepare()
{
for (int i = 0; i < BUF_SIZE; i++)
@@ -69,70 +70,70 @@ struct filter_lp24dB_benchmark
double scaler() { return BUF_SIZE; }
};
-struct filter_24dB_lp_twopass_d1: public filter_lp24dB_benchmark
+struct filter_24dB_lp_twopass_d1: public filter_lp24dB_benchmark<biquad_d1<> >
{
void run()
{
for (int i = 0; i < BUF_SIZE; i++)
- buffer[i] = biquad.process_d1(buffer[i]);
+ buffer[i] = biquad.process(buffer[i]);
for (int i = 0; i < BUF_SIZE; i++)
- buffer[i] = biquad2.process_d1(buffer[i]);
+ buffer[i] = biquad2.process(buffer[i]);
}
};
-struct filter_24dB_lp_onepass_d1: public filter_lp24dB_benchmark
+struct filter_24dB_lp_onepass_d1: public filter_lp24dB_benchmark<biquad_d1<> >
{
void run()
{
for (int i = 0; i < BUF_SIZE; i++)
- buffer[i] = biquad2.process_d1(biquad.process_d2(buffer[i]));
+ buffer[i] = biquad2.process(biquad.process(buffer[i]));
}
};
-struct filter_12dB_lp_d1: public filter_lp24dB_benchmark
+struct filter_12dB_lp_d1: public filter_lp24dB_benchmark<biquad_d1<> >
{
void run()
{
for (int i = 0; i < BUF_SIZE; i++)
- buffer[i] = biquad.process_d1(buffer[i]);
+ buffer[i] = biquad.process(buffer[i]);
}
};
-struct filter_24dB_lp_twopass_d2: public filter_lp24dB_benchmark
+struct filter_24dB_lp_twopass_d2: public filter_lp24dB_benchmark<biquad_d2<> >
{
void run()
{
for (int i = 0; i < BUF_SIZE; i++)
- buffer[i] = biquad.process_d1(buffer[i]);
+ buffer[i] = biquad.process(buffer[i]);
for (int i = 0; i < BUF_SIZE; i++)
- buffer[i] = biquad2.process_d1(buffer[i]);
+ buffer[i] = biquad2.process(buffer[i]);
}
};
-struct filter_24dB_lp_onepass_d2: public filter_lp24dB_benchmark
+struct filter_24dB_lp_onepass_d2: public filter_lp24dB_benchmark<biquad_d2<> >
{
void run()
{
for (int i = 0; i < BUF_SIZE; i++)
- buffer[i] = biquad2.process_d2(biquad.process_d2(buffer[i]));
+ buffer[i] = biquad2.process(biquad.process(buffer[i]));
}
};
-struct filter_24dB_lp_onepass_d2_lp: public filter_lp24dB_benchmark
+struct filter_24dB_lp_onepass_d2_lp: public filter_lp24dB_benchmark<biquad_d2<> >
{
void run()
{
for (int i = 0; i < BUF_SIZE; i++)
- buffer[i] = biquad2.process_d2_lp(biquad.process_d2_lp(buffer[i]));
+ buffer[i] = biquad2.process_lp(biquad.process_lp(buffer[i]));
}
};
-struct filter_12dB_lp_d2: public filter_lp24dB_benchmark
+struct filter_12dB_lp_d2: public filter_lp24dB_benchmark<biquad_d2<> >
{
void run()
{
for (int i = 0; i < BUF_SIZE; i++)
- buffer[i] = biquad.process_d2(buffer[i]);
+ buffer[i] = biquad.process(buffer[i]);
}
};
diff --git a/src/calf/biquad.h b/src/calf/biquad.h
index 9039e34..5b7bb64 100644
--- a/src/calf/biquad.h
+++ b/src/calf/biquad.h
@@ -28,26 +28,25 @@
namespace dsp {
/**
- * Two-pole two-zero filter, for floating point values.
- * Coefficient calculation is based on famous Robert Bristow-Johnson's equations.
+ * Coefficients for two-pole two-zero filter, for floating point values,
+ * plus a bunch of functions to set them to typical values.
+ *
+ * Coefficient calculation is based on famous Robert Bristow-Johnson's equations,
+ * except where it's not.
* The coefficient calculation is NOT mine, the only exception is the lossy
* optimization in Zoelzer and rbj HP filter code.
* don't use this for integers because it won't work
*/
-template<class T = float, class Coeff = float>
-class biquad
+template<class Coeff = float>
+class biquad_coeffs
{
public:
- // type I filter state variables
- T x1, y1, x2, y2;
- // type II filter state variables
- T w1, w2;
// filter coefficients
Coeff a0, a1, a2, b1, b2;
- biquad()
+ biquad_coeffs()
{
- reset();
+ set_null();
}
inline void set_null()
@@ -184,8 +183,9 @@ public:
b2 = (ab0-ab1+ab2)*q;
}
+ /// copy coefficients from another biquad
template<class U>
- inline void copy_coeffs(const biquad<U> &src)
+ inline void copy_coeffs(const biquad_coeffs<U> &src)
{
a0 = src.a0;
a1 = src.a1;
@@ -193,9 +193,36 @@ public:
b1 = src.b1;
b2 = src.b2;
}
+};
- // direct I form with four state variables
- inline T process_d1(T in)
+/**
+ * Two-pole two-zero filter, for floating point values.
+ * Uses "traditional" Direct I form (separate FIR and IIR halves).
+ * don't use this for integers because it won't work
+ */
+template<class Coeff = float, class T = float>
+struct biquad_d1: public biquad_coeffs<Coeff>
+{
+ using biquad_coeffs<Coeff>::a0;
+ using biquad_coeffs<Coeff>::a1;
+ using biquad_coeffs<Coeff>::a2;
+ using biquad_coeffs<Coeff>::b1;
+ using biquad_coeffs<Coeff>::b2;
+ /// input[n-1]
+ T x1;
+ /// input[n-2]
+ T x2;
+ /// output[n-1]
+ T y1;
+ /// output[n-2]
+ T y2;
+ /// Constructor (initializes state to all zeros)
+ biquad_d1()
+ {
+ reset();
+ }
+ /// direct I form with four state variables
+ inline T process(T in)
{
T out = in * a0 + x1 * a1 + x2 * a2 - y1 * b1 - y2 * b2;
x2 = x1;
@@ -205,8 +232,8 @@ public:
return out;
}
- // direct I form with zero input
- inline T process_d1_zeroin()
+ /// direct I form with zero input
+ inline T process_zeroin()
{
T out = - y1 * b1 - y2 * b2;
y2 = y1;
@@ -214,8 +241,8 @@ public:
return out;
}
- // simplified version for lowpass case with two zeros at -1
- inline T process_d1_lp(T in)
+ /// simplified version for lowpass case with two zeros at -1
+ inline T process_lp(T in)
{
T out = a0*(in + x1 + x1 + x2) - y1 * b1 - y2 * b2;
x2 = x1;
@@ -224,9 +251,54 @@ public:
y1 = out;
return out;
}
+ /// Sanitize (set to 0 if potentially denormal) filter state
+ inline void sanitize()
+ {
+ dsp::sanitize(x1);
+ dsp::sanitize(y1);
+ dsp::sanitize(x2);
+ dsp::sanitize(y2);
+ }
+ /// Reset state variables
+ inline void reset()
+ {
+ dsp::zero(x1);
+ dsp::zero(y1);
+ dsp::zero(x2);
+ dsp::zero(y2);
+ }
+ inline bool empty() {
+ return (y1 == 0.f && y2 == 0.f);
+ }
- // direct II form with two state variables
- inline T process_d2(T in)
+};
+
+/**
+ * Two-pole two-zero filter, for floating point values.
+ * Uses slightly faster Direct II form (combined FIR and IIR halves).
+ * However, when used with wildly varying coefficients, it may
+ * make more zipper noise than Direct I form, so it's better to
+ * use it when filter coefficients are not changed mid-stream.
+ */
+template<class Coeff = float, class T = float>
+struct biquad_d2: public biquad_coeffs<Coeff>
+{
+ using biquad_coeffs<Coeff>::a0;
+ using biquad_coeffs<Coeff>::a1;
+ using biquad_coeffs<Coeff>::a2;
+ using biquad_coeffs<Coeff>::b1;
+ using biquad_coeffs<Coeff>::b2;
+ /// state[n-1]
+ float w1;
+ /// state[n-2]
+ float w2;
+ /// Constructor (initializes state to all zeros)
+ biquad_d2()
+ {
+ reset();
+ }
+ /// direct II form with two state variables
+ inline T process(T in)
{
T tmp = in - w1 * b1 - w2 * b2;
T out = tmp * a0 + w1 * a1 + w2 * a2;
@@ -237,7 +309,7 @@ public:
// direct II form with two state variables, lowpass version
// interesting fact: this is actually slower than the general version!
- inline T process_d2_lp(T in)
+ inline T process_lp(T in)
{
T tmp = in - w1 * b1 - w2 * b2;
T out = (tmp + w2 + w1* 2) * a0;
@@ -245,47 +317,23 @@ public:
w1 = tmp;
return out;
}
-
- inline bool empty_d1() {
- return (y1 == 0.f && y2 == 0.f);
- }
-
- inline bool empty_d2() {
+
+ /// Is the filter state completely silent? (i.e. set to 0 by sanitize function)
+ inline bool empty() {
return (w1 == 0.f && w2 == 0.f);
}
- inline void sanitize_d1()
- {
- dsp::sanitize(x1);
- dsp::sanitize(y1);
- dsp::sanitize(x2);
- dsp::sanitize(y2);
- }
- inline void sanitize_d2()
+ /// Sanitize (set to 0 if potentially denormal) filter state
+ inline void sanitize()
{
dsp::sanitize(w1);
dsp::sanitize(w2);
}
+ /// Reset state variables
inline void reset()
{
- dsp::zero(x1);
- dsp::zero(y1);
- dsp::zero(w1);
- dsp::zero(x2);
- dsp::zero(y2);
- dsp::zero(w2);
- }
- inline void reset_d1()
- {
- dsp::zero(x1);
- dsp::zero(y1);
- dsp::zero(x2);
- dsp::zero(y2);
- }
- inline void reset_d2()
- {
dsp::zero(w1);
dsp::zero(w2);
}
diff --git a/src/calf/modules.h b/src/calf/modules.h
index 89afd15..dbf4a5a 100644
--- a/src/calf/modules.h
+++ b/src/calf/modules.h
@@ -268,7 +268,7 @@ public:
float *outs[out_count];
float *params[param_count];
static const char *port_names[];
- dsp::biquad<float> left[3], right[3];
+ dsp::biquad_d1<float> left[3], right[3];
uint32_t srate;
static parameter_properties param_props[];
static synth::ladspa_plugin_info plugin_info;
@@ -341,51 +341,51 @@ public:
void set_sample_rate(uint32_t sr) {
srate = sr;
}
- inline int process_channel(dsp::biquad<float> *filter, float *in, float *out, uint32_t numsamples, int inmask) {
+ inline int process_channel(dsp::biquad_d1<float> *filter, float *in, float *out, uint32_t numsamples, int inmask) {
if (inmask) {
switch(order) {
case 1:
for (uint32_t i = 0; i < numsamples; i++)
- out[i] = filter[0].process_d1(in[i]);
+ out[i] = filter[0].process(in[i]);
break;
case 2:
for (uint32_t i = 0; i < numsamples; i++)
- out[i] = filter[1].process_d1(filter[0].process_d1(in[i]));
+ out[i] = filter[1].process(filter[0].process(in[i]));
break;
case 3:
for (uint32_t i = 0; i < numsamples; i++)
- out[i] = filter[2].process_d1(filter[1].process_d1(filter[0].process_d1(in[i])));
+ out[i] = filter[2].process(filter[1].process(filter[0].process(in[i])));
break;
}
} else {
- if (filter[order - 1].empty_d1())
+ if (filter[order - 1].empty())
return 0;
switch(order) {
case 1:
for (uint32_t i = 0; i < numsamples; i++)
- out[i] = filter[0].process_d1_zeroin();
+ out[i] = filter[0].process_zeroin();
break;
case 2:
- if (filter[0].empty_d1())
+ if (filter[0].empty())
for (uint32_t i = 0; i < numsamples; i++)
- out[i] = filter[1].process_d1_zeroin();
+ out[i] = filter[1].process_zeroin();
else
for (uint32_t i = 0; i < numsamples; i++)
- out[i] = filter[1].process_d1(filter[0].process_d1_zeroin());
+ out[i] = filter[1].process(filter[0].process_zeroin());
break;
case 3:
- if (filter[1].empty_d1())
+ if (filter[1].empty())
for (uint32_t i = 0; i < numsamples; i++)
- out[i] = filter[2].process_d1_zeroin();
+ out[i] = filter[2].process_zeroin();
else
for (uint32_t i = 0; i < numsamples; i++)
- out[i] = filter[2].process_d1(filter[1].process_d1(filter[0].process_d1_zeroin()));
+ out[i] = filter[2].process(filter[1].process(filter[0].process_zeroin()));
break;
}
}
for (int i = 0; i < order; i++)
- filter[i].sanitize_d1();
- return filter[order - 1].empty_d1() ? 0 : inmask;
+ filter[i].sanitize();
+ return filter[order - 1].empty() ? 0 : inmask;
}
uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
// printf("sr=%d cutoff=%f res=%f mode=%f\n", srate, *params[par_cutoff], *params[par_resonance], *params[par_mode]);
@@ -428,7 +428,7 @@ public:
int bufptr, deltime_l, deltime_r, mixmode, medium, old_medium;
gain_smoothing amt_left, amt_right, fb_left, fb_right;
- dsp::biquad<float> biquad_left[2], biquad_right[2];
+ dsp::biquad_d2<float> biquad_left[2], biquad_right[2];
uint32_t srate;
static parameter_properties param_props[];
@@ -503,20 +503,20 @@ public:
{
for(uint32_t i = offset; i < end; i++)
{
- buffers[0][bufptr] = biquad_left[0].process_d2_lp(biquad_left[1].process_d2(buffers[0][bufptr]));
- buffers[1][bufptr] = biquad_right[0].process_d2_lp(biquad_right[1].process_d2(buffers[1][bufptr]));
+ buffers[0][bufptr] = biquad_left[0].process_lp(biquad_left[1].process(buffers[0][bufptr]));
+ buffers[1][bufptr] = biquad_right[0].process_lp(biquad_right[1].process(buffers[1][bufptr]));
bufptr = (bufptr + 1) & (MAX_DELAY - 1);
}
- biquad_left[0].sanitize_d2();biquad_right[0].sanitize_d2();
+ biquad_left[0].sanitize();biquad_right[0].sanitize();
} else {
for(uint32_t i = offset; i < end; i++)
{
- buffers[0][bufptr] = biquad_left[1].process_d2(buffers[0][bufptr]);
- buffers[1][bufptr] = biquad_right[1].process_d2(buffers[1][bufptr]);
+ buffers[0][bufptr] = biquad_left[1].process(buffers[0][bufptr]);
+ buffers[1][bufptr] = biquad_right[1].process(buffers[1][bufptr]);
bufptr = (bufptr + 1) & (MAX_DELAY - 1);
}
}
- biquad_left[1].sanitize_d2();biquad_right[1].sanitize_d2();
+ biquad_left[1].sanitize();biquad_right[1].sanitize();
}
return ostate;
@@ -536,7 +536,7 @@ public:
/// Current phases and phase deltas for bass and treble rotors
uint32_t phase_l, dphase_l, phase_h, dphase_h;
dsp::simple_delay<1024, float> delay;
- dsp::biquad<float> crossover1l, crossover1r, crossover2l, crossover2r;
+ dsp::biquad_d2<float> crossover1l, crossover1r, crossover2l, crossover2r;
dsp::simple_delay<8, float> phaseshift;
uint32_t srate;
int vibrato_mode;
@@ -671,10 +671,10 @@ public:
float out_lo_l = in_mono + delay.get_interp_1616(shift + md * xl); // + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yl);
float out_lo_r = in_mono + delay.get_interp_1616(shift + md * yl); // - delay.get_interp_1616(shift + pdelta + md * yl);
- out_hi_l = crossover2l.process_d2(out_hi_l); // sanitize(out_hi_l);
- out_hi_r = crossover2r.process_d2(out_hi_r); // sanitize(out_hi_r);
- out_lo_l = crossover1l.process_d2(out_lo_l); // sanitize(out_lo_l);
- out_lo_r = crossover1r.process_d2(out_lo_r); // sanitize(out_lo_r);
+ out_hi_l = crossover2l.process(out_hi_l); // sanitize(out_hi_l);
+ out_hi_r = crossover2r.process(out_hi_r); // sanitize(out_hi_r);
+ out_lo_l = crossover1l.process(out_lo_l); // sanitize(out_lo_l);
+ out_lo_r = crossover1r.process(out_lo_r); // sanitize(out_lo_r);
float out_l = out_hi_l + out_lo_l;
float out_r = out_hi_r + out_lo_r;
@@ -688,10 +688,10 @@ public:
phase_l += dphase_l;
phase_h += dphase_h;
}
- crossover1l.sanitize_d2();
- crossover1r.sanitize_d2();
- crossover2l.sanitize_d2();
- crossover2r.sanitize_d2();
+ crossover1l.sanitize();
+ crossover1r.sanitize();
+ crossover2l.sanitize();
+ crossover2r.sanitize();
float delta = nsamples * 1.0 / srate;
if (vibrato_mode == 5)
update_speed_manual(delta);
diff --git a/src/calf/modules_synths.h b/src/calf/modules_synths.h
index 24c594b..db6cabf 100644
--- a/src/calf/modules_synths.h
+++ b/src/calf/modules_synths.h
@@ -59,8 +59,8 @@ public:
float buffer[step_size], buffer2[step_size];
uint32_t output_pos;
dsp::onepole<float> phaseshifter;
- dsp::biquad<float> filter;
- dsp::biquad<float> filter2;
+ dsp::biquad_d1<float> filter;
+ dsp::biquad_d1<float> filter2;
int wave1, wave2, filter_type, last_filter_type;
float freq, start_freq, target_freq, cutoff, decay_factor, fgain, fgain_delta, separation;
float detune, xpose, xfade, pitchbend, ampctl, fltctl, queue_vel;
diff --git a/src/calf/organ.h b/src/calf/organ.h
index 767086f..bb62063 100644
--- a/src/calf/organ.h
+++ b/src/calf/organ.h
@@ -232,7 +232,7 @@ protected:
float aux_buffers[3][BlockSize][Channels];
};
dsp::fixed_point<int64_t, 52> phase, dphase;
- dsp::biquad<float> filterL[2], filterR[2];
+ dsp::biquad_d1<float> filterL[2], filterR[2];
adsr envs[EnvCount];
dsp::inertia<dsp::linear_ramp> expression;
organ_vibrato vibrato;
diff --git a/src/modules_small.cpp b/src/modules_small.cpp
index d7aae88..53b1065 100644
--- a/src/modules_small.cpp
+++ b/src/modules_small.cpp
@@ -67,15 +67,15 @@ public:
pii->control_port("res", "Resonance", 0.707).input().log_range(0.707, 20);
pii->audio_port("out", "Out").output();
}
- dsp::biquad<float> filter;
+ dsp::biquad_d1<float> filter;
void activate() {
- filter.reset_d1();
+ filter.reset();
}
inline void process_inner(uint32_t count) {
for (uint32_t i = 0; i < count; i++)
- outs[out_signal][i] = filter.process_d1(ins[in_signal][i]);
- filter.sanitize_d1();
+ outs[out_signal][i] = filter.process(ins[in_signal][i]);
+ filter.sanitize();
}
};
diff --git a/src/monosynth.cpp b/src/monosynth.cpp
index 73ca1c0..7befd29 100644
--- a/src/monosynth.cpp
+++ b/src/monosynth.cpp
@@ -388,7 +388,7 @@ bool monosynth_audio_module::get_graph(int index, int subindex, float *data, int
double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points) * M_PI / srate;
cfloat z = 1.0 / exp(cfloat(0.0, freq));
- biquad<float> &f = subindex ? filter2 : filter;
+ biquad_d1<float> &f = subindex ? filter2 : filter;
float level = abs((cfloat(f.a0) + double(f.a1) * z + double(f.a2) * z*z) / (cfloat(1.0) + double(f.b1) * z + double(f.b2) * z*z));
if (!is_stereo_filter())
level *= abs((cfloat(filter2.a0) + double(filter2.a1) * z + double(filter2.a2) * z*z) / (cfloat(1.0) + double(filter2.b1) * z + double(filter2.b2) * z*z));
@@ -408,8 +408,8 @@ void monosynth_audio_module::calculate_buffer_ser()
float osc1val = osc1.get();
float osc2val = osc2.get();
float wave = fgain * (osc1val + (osc2val - osc1val) * xfade);
- wave = filter.process_d1(wave);
- wave = filter2.process_d1(wave);
+ wave = filter.process(wave);
+ wave = filter2.process(wave);
buffer[i] = wave;
fgain += fgain_delta;
}
@@ -422,7 +422,7 @@ void monosynth_audio_module::calculate_buffer_single()
float osc1val = osc1.get();
float osc2val = osc2.get();
float wave = fgain * (osc1val + (osc2val - osc1val) * xfade);
- wave = filter.process_d1(wave);
+ wave = filter.process(wave);
buffer[i] = wave;
fgain += fgain_delta;
}
@@ -436,8 +436,8 @@ void monosynth_audio_module::calculate_buffer_stereo()
float osc2val = osc2.get();
float wave1 = osc1val + (osc2val - osc1val) * xfade;
float wave2 = phaseshifter.process_ap(wave1);
- buffer[i] = fgain * filter.process_d1(wave1);
- buffer2[i] = fgain * filter2.process_d1(wave2);
+ buffer[i] = fgain * filter.process(wave1);
+ buffer2[i] = fgain * filter2.process(wave2);
fgain += fgain_delta;
}
}
diff --git a/src/organ.cpp b/src/organ.cpp
index c5fb9f6..856eb6c 100644
--- a/src/organ.cpp
+++ b/src/organ.cpp
@@ -1160,23 +1160,23 @@ void organ_voice::render_block() {
if (parameters->filter_chain >= 0.5f)
{
for (int i=0; i < (int) BlockSize; i++) {
- output_buffer[i][0] = a3 * (a0 * output_buffer[i][0] + a2 * filterL[1].process_d1(a1 * filterL[0].process_d1(aux_buffers[1][i][0]) + aux_buffers[2][i][0]));
- output_buffer[i][1] = a3 * (a0 * output_buffer[i][1] + a2 * filterR[1].process_d1(a1 * filterR[0].process_d1(aux_buffers[1][i][1]) + aux_buffers[2][i][1]));
+ output_buffer[i][0] = a3 * (a0 * output_buffer[i][0] + a2 * filterL[1].process(a1 * filterL[0].process(aux_buffers[1][i][0]) + aux_buffers[2][i][0]));
+ output_buffer[i][1] = a3 * (a0 * output_buffer[i][1] + a2 * filterR[1].process(a1 * filterR[0].process(aux_buffers[1][i][1]) + aux_buffers[2][i][1]));
a0 += d0, a1 += d1, a2 += d2, a3 += d3;
}
}
else
{
for (int i=0; i < (int) BlockSize; i++) {
- output_buffer[i][0] = a3 * (a0 * output_buffer[i][0] + a1 * filterL[0].process_d1(aux_buffers[1][i][0]) + a2 * filterL[1].process_d1(aux_buffers[2][i][0]));
- output_buffer[i][1] = a3 * (a0 * output_buffer[i][1] + a1 * filterR[0].process_d1(aux_buffers[1][i][1]) + a2 * filterR[1].process_d1(aux_buffers[2][i][1]));
+ output_buffer[i][0] = a3 * (a0 * output_buffer[i][0] + a1 * filterL[0].process(aux_buffers[1][i][0]) + a2 * filterL[1].process(aux_buffers[2][i][0]));
+ output_buffer[i][1] = a3 * (a0 * output_buffer[i][1] + a1 * filterR[0].process(aux_buffers[1][i][1]) + a2 * filterR[1].process(aux_buffers[2][i][1]));
a0 += d0, a1 += d1, a2 += d2, a3 += d3;
}
}
- filterL[0].sanitize_d1();
- filterR[0].sanitize_d1();
- filterL[1].sanitize_d1();
- filterR[1].sanitize_d1();
+ filterL[0].sanitize();
+ filterR[0].sanitize();
+ filterL[1].sanitize();
+ filterR[1].sanitize();
if (vibrato_mode == lfomode_voice)
vibrato.process(parameters, output_buffer, BlockSize, sample_rate);
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list