diff --git a/src/devices/sound/flt_biquad.cpp b/src/devices/sound/flt_biquad.cpp index 6ae1bde0109..f74bf6bae73 100644 --- a/src/devices/sound/flt_biquad.cpp +++ b/src/devices/sound/flt_biquad.cpp @@ -11,7 +11,7 @@ This biquad filter implementation is based on one written by Frank Palazzolo, K. Wilkins, Couriersud, and Derrick Renaud, with some changes: - * It uses the Q factor directly in the filter definitions, rather than the damping factor (1/Q) + * It uses the Q factor directly in the filter definitions, rather than the damping factor (1/2Q) * It implements every common type of digital biquad filter which I could find documentation for. * The filter is Direct-form II instead of Direct-form I, which results in shorter compiled code. * Optional direct control of the 5 normalized biquad parameters for a custom/raw parameter filter. @@ -23,14 +23,23 @@ #include "emu.h" #include "flt_biquad.h" +// enable this to display debug info about the filters being set up +#define LOG_SETUP (1U << 1) +// enable this to display the filter parameters upon being recalculated +#define LOG_PARAMS (1U << 2) +// enable this to display the biquad parameters upon being recalculated +#define LOG_CALC (1U << 3) + +#define LOG_ALL (LOG_SETUP|LOG_PARAMS|LOG_CALC) + +//#define VERBOSE (LOG_SETUP) +#include "logmacro.h" + // we need the M_SQRT2 constant #ifndef M_SQRT2 #define M_SQRT2 1.41421356237309504880 #endif -// define this to display debug info about the filters being set up -#undef FLT_BIQUAD_DEBUG_SETUP - // device type definition DEFINE_DEVICE_TYPE(FILTER_BIQUAD, filter_biquad_device, "filter_biquad", "Biquad Filter") @@ -134,6 +143,9 @@ void filter_biquad_device::modify_raw(double a1, double a2, double b0, double b1 //------------------------------------------------- // NOTE: if a resistor doesn't exist, pass a value of RES_M(999.99) or the like, i.e. an 'infinite resistor' // NOTE: if a resistor is a direct short, set its resistance to RES_R(0.001) +// NOTE: in all of these filters, vRef is not definable when setting up the filter. +// If the analog effects caused by vRef are important to the operation of the specific filter +// in question, a netlist implementation may work better under those circumstances. // Sallen-Key filters @@ -186,24 +198,22 @@ filter_biquad_device::biquad_params filter_biquad_device::opamp_sk_lowpass_calc( r.gain = 1.0 + (r4 / r3); // == (r3 + r4) / r3 r.fc = 1.0 / (2 * M_PI * sqrt(r1 * r2 * c1 * c2)); r.q = sqrt(r1 * r2 * c1 * c2) / ((r1 * c2) + (r2 * c2) + ((r2 * c1) * (1.0 - r.gain))); -#ifdef FLT_BIQUAD_DEBUG_SETUP - logerror("filter_biquad_device::opamp_sk_lowpass_calc(%f, %f, %f, %f, %f, %f) yields: fc = %f, Q = %f, gain = %f\n", r1, r2, r3, r4, c1*1000000, c2*1000000, r.fc, r.q, r.gain); -#endif + LOGMASKED(LOG_SETUP,"filter_biquad_device::opamp_sk_lowpass_calc(%f, %f, %f, %f, %f, %f) yields: fc = %f, Q = %f, gain = %f\n", r1, r2, r3, r4, c1*1000000, c2*1000000, r.fc, r.q, r.gain); return r; } +// TODO when needed: Sallen-Key high-pass filter + // Multiple-Feedback filters /* Setup a biquad filter structure based on a single op-amp Multiple-Feedback low-pass filter circuit. * This is sometimes called a "Rauch" filter circuit. - * NOTE: vRef is not definable when setting up the filter. - * If the analog effects caused by vRef are important to the operation of the specific - * filter in question, a netlist implementation may work better under those circumstances. - * NOTE2: There is a well known 'proper' 1st order version of this circuit where r2 is - * a dead short, and c1 omitted. set both c1 and r2 to 0 in this case. - * NOTE3: a variant of NOTE2 has only the c1 capacitor left off, and r2 present. if so, - * set c1 to 0 and r2 to its expected value. + * NOTE: There is a well known 'proper' 1st order version of this circuit where + * r2 is a dead short, and c1 omitted. As an exception to the usual rule about + * missing components, set both c1 and r2 to 0 in this case. + * NOTE: There is a variant of this filter with the c1 capacitor left off, and + * r2 present. if so, set c1 to 0 and r2 to its expected value. * TODO: make this compatible with the RES_M(999.99) and RES_R(0.001) rules! * * .--------+---------. @@ -252,22 +262,17 @@ filter_biquad_device::biquad_params filter_biquad_device::opamp_mfb_lowpass_calc r.q = sqrt(r2 * r3 * c1 * c2) / ((r3 * c2) + (r2 * c2) + ((r2 * c2) * -r.gain)); r.type = biquad_type::LOWPASS; } -#ifdef FLT_BIQUAD_DEBUG_SETUP - logerror("filter_biquad_device::opamp_mfb_lowpass_calc(%f, %f, %f, %f, %f) yields:\n\ttype = %d, fc = %f, Q = %f, gain = %f\n", r1, r2, r3, c1*1000000, c2*1000000, static_cast(r.type), r.fc, r.q, r.gain); -#endif + LOGMASKED(LOG_SETUP,"filter_biquad_device::opamp_mfb_lowpass_calc(%f, %f, %f, %f, %f) yields:\n\ttype = %d, fc = %f, Q = %f, gain = %f\n", r1, r2, r3, c1*1000000, c2*1000000, static_cast(r.type), r.fc, r.q, r.gain); return r; } /* Setup a biquad filter structure based on a single op-amp Multiple-Feedback band-pass filter circuit. * This is sometimes called a "modified Deliyannis" or "Deliyannis-friend" filter circuit, * or an "Infinite Gain Multiple-Feedback [band-pass] Filter" aka "IGMF". - * NOTE: vRef is not definable when setting up the filter, and is assumed to be grounded. - * If the analog effects caused by vRef are important to the operation of the specific filter - * in question, a netlist implementation may work better under those circumstances. * TODO: There is a documented modification to this filter which adds a resistor ladder between * ground and the op-amp output, with the 'rung' of the ladder connecting to the + input of * the op-amp, and this allows more control of the filter. - * NOTE2: If r2 is not used, then set it to RES_M(999.99), the code will effectively be an Infinite Gain MFB Bandpass. + * NOTE2: If r2 is not present, then set it to RES_M(999.99), the code will effectively be an Infinite Gain MFB Bandpass. * * .--------+---------. * | | | @@ -290,23 +295,15 @@ filter_biquad_device& filter_biquad_device::opamp_mfb_bandpass_setup(double r1, fatalerror("filter_biquad_device::opamp_mfb_bandpass_setup() - no parameters can be 0; parameters were: r1: %f, r2: %f, r3: %f, c1: %f, c2: %f", r1, r2, r3, c1, c2); /* Filter can not be setup. Undefined results. */ } - double const r_in = 1.0 / (1.0/r1 + 1.0/r2); // TODO: verify - // gain = (r2 / (r1 + r2)) * (-r3 / r_in * c2 / (c1 + c2)); // ??? wrong? - double const gain = -r3 / (2.0 * r1); - // q = sqrt(r3 / r_in * c1 * c2) / (c1 + c2); // ??? wrong? - double const q = 0.5 * sqrt(r3 / r1); - - double const fc = 1.0 / (sqrt(r_in * r3 * c1 * c2)); // technically this is the center frequency of the bandpass -#ifdef FLT_BIQUAD_DEBUG_SETUP - logerror("filter_biquad_device::opamp_mfb_bandpass_setup() yields: fc = %f, Q = %f, gain = %f\n", fc, q, gain); -#endif + double const r_in = 1.0 / ((1.0 / r1) + (1.0 / r2)); + double const gain = (r3 / r1) * (-c2 / (c1 + c2)); + double const q = sqrt((r3 / r_in) * c1 * c2) / (c1 + c2); + double const fc = 1.0 / (2 * M_PI * sqrt(r_in * r3 * c1 * c2)); // technically this is the center frequency of the bandpass + LOGMASKED(LOG_SETUP,"filter_biquad_device::opamp_mfb_bandpass_setup() yields: fc = %f, Q = %f, gain = %f\n", fc, q, gain); return setup(biquad_type::BANDPASS, fc, q, gain); } /* Setup a biquad filter structure based on a single op-amp Multiple-Feedback high-pass filter circuit. - * NOTE: vRef is not definable when setting up the filter. - * If the analog effects caused by vRef are important to the operation of the specific filter - * in question, a netlist implementation may work better under those circumstances. * * .--------+---------. * | | | @@ -332,17 +329,14 @@ filter_biquad_device& filter_biquad_device::opamp_mfb_highpass_setup(double r1, double const gain = -c1 / c3; double const fc = 1.0 / (2 * M_PI * sqrt(c2 * c3 * r1 * r2)); double const q = sqrt(c2 * c3 * r1 * r2) / ((c2 * r1) + (c3 * r1) + ((c3 * r1) * -gain)); -#ifdef FLT_BIQUAD_DEBUG_SETUP - logerror("filter_biquad_device::opamp_mfb_highpass_setup() yields: fc = %f, Q = %f, gain = %f\n", fc, q, gain); -#endif + LOGMASKED(LOG_SETUP,"filter_biquad_device::opamp_mfb_highpass_setup() yields: fc = %f, Q = %f, gain = %f\n", fc, q, gain); return setup(biquad_type::HIGHPASS, fc, q, gain); } +// Differentiator Filter + /* Setup a biquad filter structure based on a single op-amp Differentiator band-pass filter circuit. * This circuit is sometimes called an "Inverting Band Pass Filter Circuit" - * NOTE: vRef is not definable when setting up the filter. - * If the analog effects caused by vRef are important to the operation of the specific filter - * in question, a netlist implementation may work better under those circumstances. * * .--------+---------. * | | | @@ -384,9 +378,7 @@ filter_biquad_device::biquad_params filter_biquad_device::opamp_diff_bandpass_ca r.fc = pow(10.0, fct); r.q = r.fc / (f2 - f1); r.type = biquad_type::BANDPASS; -#ifdef FLT_BIQUAD_DEBUG_SETUP - logerror("filter_biquad_device::opamp_diff_bandpass_calc(%f, %f, %f, %f) yields:\n\ttype = %d, fc = %f (f1 = %f, f2 = %f), Q = %f, gain = %f\n", r1, r2, c1*1000000, c2*1000000, static_cast(r.type), r.fc, f1, f2, r.q, r.gain); -#endif + LOGMASKED(LOG_SETUP,"filter_biquad_device::opamp_diff_bandpass_calc(%f, %f, %f, %f) yields:\n\ttype = %d, fc = %f (f1 = %f, f2 = %f), Q = %f, gain = %f\n", r1, r2, c1*1000000, c2*1000000, static_cast(r.type), r.fc, f1, f2, r.q, r.gain); return r; } @@ -445,139 +437,174 @@ void filter_biquad_device::sound_stream_update(sound_stream &stream, std::vector /* Calculate the filter context based on the passed filter type info. * m_type - 1 of the 9 defined filter types - * m_fc - center frequency - * m_q - 'Q' (quality) factor of filter (1/damp) + * m_fc - cutoff or center frequency + * m_q - 'Q' (quality) factor of filter (1/(2*damp)) * m_gain - overall filter gain. Set to 1.0 if not needed. The exact meaning of gain changes depending on the filter type. */ void filter_biquad_device::recalc() { + LOGMASKED(LOG_PARAMS,"Filter type is: %d\n",static_cast(m_type)); if (m_type == biquad_type::RAWPARAMS) return; // if we're dealing with raw parameters, just return, don't touch anything. + LOGMASKED(LOG_PARAMS,"Filter cutoff is: %f Hz\n",m_fc); + LOGMASKED(LOG_PARAMS,"Filter Q factor is: %f (damping ratio is: %f)\n",m_q,(1.0/(2.0*m_q))); + LOGMASKED(LOG_PARAMS,"Filter (multiplicative) gain is: %f\n",m_gain); + LOGMASKED(LOG_PARAMS,"Stream sample rate is: %f\n",m_stream->sample_rate()); - double const MGain = fabs(m_gain); // absolute multiplicative gain - double const DBGain = log10(MGain) * 20.0; // gain in dB - double const AMGain = pow(10, fabs(DBGain) / 20.0); // multiplicative gain of absolute DB - double const K = tan(M_PI * m_fc / m_stream->sample_rate()); - double const Ksquared = K * K; - double const KoverQ = K / m_q; - double normal = 1.0 / (1.0 + KoverQ + Ksquared); - - switch (m_type) + // if the nyquist frequency of the stream sample rate is below the cutoff, + // we need to sanely bail out or we'll get all sorts of horrible aliasing + // and noise. + if (m_fc >= m_stream->sample_rate() / 2.0) { - case biquad_type::LOWPASS1P: - m_a1 = exp(-2.0 * M_PI * (m_fc / m_stream->sample_rate())); - m_b0 = 1.0 - m_a1; - m_a1 = -m_a1; - m_b1 = m_b2 = m_a2 = 0.0; - break; - case biquad_type::HIGHPASS1P: - m_a1 = -exp(-2.0 * M_PI * (0.5 - m_fc / m_stream->sample_rate())); - m_b0 = 1.0 + m_a1; - m_a1 = -m_a1; - m_b1 = m_b2 = m_a2 = 0.0; - break; - case biquad_type::LOWPASS: - m_b0 = Ksquared * normal; - m_b1 = 2.0 * m_b0; - m_b2 = 1.0 * m_b0; - m_a1 = 2.0 * (Ksquared - 1.0) * normal; - m_a2 = (1.0 - KoverQ + Ksquared) * normal; - break; - case biquad_type::HIGHPASS: - m_b0 = 1.0 * normal; - m_b1 = -2.0 * m_b0; - m_b2 = 1.0 * m_b0; - m_a1 = 2.0 * (Ksquared - 1.0) * normal; - m_a2 = (1.0 - KoverQ + Ksquared) * normal; - break; - case biquad_type::BANDPASS: - m_b0 = KoverQ * normal; - m_b1 = 0.0; - m_b2 = -1.0 * m_b0; - m_a1 = 2.0 * (Ksquared - 1.0) * normal; - m_a2 = (1.0 - KoverQ + Ksquared) * normal; - break; - case biquad_type::NOTCH: - m_b0 = (1.0 + Ksquared) * normal; - m_b1 = 2.0 * (Ksquared - 1.0) * normal; - m_b2 = 1.0 * m_b0; - m_a1 = 1.0 * m_b1; - m_a2 = (1.0 - KoverQ + Ksquared) * normal; - break; - case biquad_type::PEAK: - if (DBGain >= 0.0) - { - m_b0 = (1.0 + (AMGain * KoverQ) + Ksquared) * normal; + switch (m_type) + { + // For lowpass and friends, just let the signal through unchanged. + case biquad_type::LOWPASS1P: + case biquad_type::LOWPASS: + case biquad_type::NOTCH: + case biquad_type::LOWSHELF: + default: + m_b0 = 1.0; + break; + // For highpass and friends, block the entire signal. + case biquad_type::HIGHPASS1P: + case biquad_type::HIGHPASS: + case biquad_type::BANDPASS: + case biquad_type::PEAK: + case biquad_type::HIGHSHELF: + m_b0 = 0.0; + break; + } + m_a1 = m_a2 = 0.0; + m_b1 = m_b2 = 0.0; + LOGMASKED(LOG_CALC,"Warning: Nyquist frequency of the stream sample rate is below the filter cutoff!\n"); + LOGMASKED(LOG_CALC,"Filter is mostly disabled (except for gain), and output is forced to %f * input [* gain]!\n", m_b0); + } + else + { + double const MGain = fabs(m_gain); // absolute multiplicative gain + double const DBGain = log10(MGain) * 20.0; // gain in dB + double const AMGain = pow(10, fabs(DBGain) / 20.0); // multiplicative gain of absolute DB + double const K = tan(M_PI * m_fc / m_stream->sample_rate()); + double const Ksquared = K * K; + double const KoverQ = K / m_q; + double normal = 1.0 / (1.0 + KoverQ + Ksquared); + + switch (m_type) + { + case biquad_type::LOWPASS1P: + m_a1 = exp(-2.0 * M_PI * (m_fc / m_stream->sample_rate())); + m_b0 = 1.0 - m_a1; + m_a1 = -m_a1; + m_b1 = m_b2 = m_a2 = 0.0; + break; + case biquad_type::HIGHPASS1P: + m_a1 = -exp(-2.0 * M_PI * (0.5 - m_fc / m_stream->sample_rate())); + m_b0 = 1.0 + m_a1; + m_a1 = -m_a1; + m_b1 = m_b2 = m_a2 = 0.0; + break; + case biquad_type::LOWPASS: + m_b0 = Ksquared * normal; + m_b1 = 2.0 * m_b0; + m_b2 = 1.0 * m_b0; + m_a1 = 2.0 * (Ksquared - 1.0) * normal; + m_a2 = (1.0 - KoverQ + Ksquared) * normal; + break; + case biquad_type::HIGHPASS: + m_b0 = 1.0 * normal; + m_b1 = -2.0 * m_b0; + m_b2 = 1.0 * m_b0; + m_a1 = 2.0 * (Ksquared - 1.0) * normal; + m_a2 = (1.0 - KoverQ + Ksquared) * normal; + break; + case biquad_type::BANDPASS: + m_b0 = KoverQ * normal; + m_b1 = 0.0; + m_b2 = -1.0 * m_b0; + m_a1 = 2.0 * (Ksquared - 1.0) * normal; + m_a2 = (1.0 - KoverQ + Ksquared) * normal; + break; + case biquad_type::NOTCH: + m_b0 = (1.0 + Ksquared) * normal; m_b1 = 2.0 * (Ksquared - 1.0) * normal; - m_b2 = (1.0 - (AMGain * KoverQ) + Ksquared) * normal; + m_b2 = 1.0 * m_b0; m_a1 = 1.0 * m_b1; m_a2 = (1.0 - KoverQ + Ksquared) * normal; - } - else - { - normal = 1.0 / (1.0 + (AMGain * KoverQ) + Ksquared); - m_b0 = (1.0 + KoverQ + Ksquared) * normal; - m_b1 = 2.0 * (Ksquared - 1.0) * normal; - m_b2 = (1.0 - KoverQ + Ksquared) * normal; - m_a1 = 1.0 * m_b1; - m_a2 = (1.0 - (AMGain * KoverQ) + Ksquared) * normal; - } - break; - case biquad_type::LOWSHELF: - if (DBGain >= 0.0) - { - normal = 1.0 / (1.0 + M_SQRT2 * K + Ksquared); - m_b0 = (1.0 + sqrt(2.0 * AMGain) * K + AMGain * Ksquared) * normal; - m_b1 = 2.0 * (AMGain * Ksquared - 1.0) * normal; - m_b2 = (1.0 - sqrt(2.0 * AMGain) * K + AMGain * Ksquared) * normal; - m_a1 = 2.0 * (Ksquared - 1.0) * normal; - m_a2 = (1.0 - M_SQRT2 * K + Ksquared) * normal; - } - else - { - normal = 1.0 / (1.0 + sqrt(2.0 * AMGain) * K + AMGain * Ksquared); - m_b0 = (1.0 + M_SQRT2 * K + Ksquared) * normal; - m_b1 = 2.0 * (Ksquared - 1.0) * normal; - m_b2 = (1.0 - M_SQRT2 * K + Ksquared) * normal; - m_a1 = 2.0 * (AMGain * Ksquared - 1.0) * normal; - m_a2 = (1.0 - sqrt(2.0 * AMGain) * K + AMGain * Ksquared) * normal; - } - break; - case biquad_type::HIGHSHELF: - if (DBGain >= 0.0) - { - normal = 1.0 / (1.0 + M_SQRT2 * K + Ksquared); - m_b0 = (AMGain + sqrt(2.0 * AMGain) * K + Ksquared) * normal; - m_b1 = 2.0 * (Ksquared - AMGain) * normal; - m_b2 = (AMGain - sqrt(2.0 * AMGain) * K + Ksquared) * normal; - m_a1 = 2.0 * (Ksquared - 1.0) * normal; - m_a2 = (1.0 - M_SQRT2 * K + Ksquared) * normal; - } - else - { - normal = 1.0 / (AMGain + sqrt(2.0 * AMGain) * K + Ksquared); - m_b0 = (1.0 + M_SQRT2 * K + Ksquared) * normal; - m_b1 = 2.0 * (Ksquared - 1.0) * normal; - m_b2 = (1.0 - M_SQRT2 * K + Ksquared) * normal; - m_a1 = 2.0 * (Ksquared - AMGain) * normal; - m_a2 = (AMGain - sqrt(2.0 * AMGain) * K + Ksquared) * normal; - } - break; - default: - fatalerror("filter_biquad_device::recalc() - Invalid filter type!"); - break; + break; + case biquad_type::PEAK: + if (DBGain >= 0.0) + { + m_b0 = (1.0 + (AMGain * KoverQ) + Ksquared) * normal; + m_b1 = 2.0 * (Ksquared - 1.0) * normal; + m_b2 = (1.0 - (AMGain * KoverQ) + Ksquared) * normal; + m_a1 = 1.0 * m_b1; + m_a2 = (1.0 - KoverQ + Ksquared) * normal; + } + else + { + normal = 1.0 / (1.0 + (AMGain * KoverQ) + Ksquared); + m_b0 = (1.0 + KoverQ + Ksquared) * normal; + m_b1 = 2.0 * (Ksquared - 1.0) * normal; + m_b2 = (1.0 - KoverQ + Ksquared) * normal; + m_a1 = 1.0 * m_b1; + m_a2 = (1.0 - (AMGain * KoverQ) + Ksquared) * normal; + } + break; + case biquad_type::LOWSHELF: + if (DBGain >= 0.0) + { + normal = 1.0 / (1.0 + M_SQRT2 * K + Ksquared); + m_b0 = (1.0 + sqrt(2.0 * AMGain) * K + AMGain * Ksquared) * normal; + m_b1 = 2.0 * (AMGain * Ksquared - 1.0) * normal; + m_b2 = (1.0 - sqrt(2.0 * AMGain) * K + AMGain * Ksquared) * normal; + m_a1 = 2.0 * (Ksquared - 1.0) * normal; + m_a2 = (1.0 - M_SQRT2 * K + Ksquared) * normal; + } + else + { + normal = 1.0 / (1.0 + sqrt(2.0 * AMGain) * K + AMGain * Ksquared); + m_b0 = (1.0 + M_SQRT2 * K + Ksquared) * normal; + m_b1 = 2.0 * (Ksquared - 1.0) * normal; + m_b2 = (1.0 - M_SQRT2 * K + Ksquared) * normal; + m_a1 = 2.0 * (AMGain * Ksquared - 1.0) * normal; + m_a2 = (1.0 - sqrt(2.0 * AMGain) * K + AMGain * Ksquared) * normal; + } + break; + case biquad_type::HIGHSHELF: + if (DBGain >= 0.0) + { + normal = 1.0 / (1.0 + M_SQRT2 * K + Ksquared); + m_b0 = (AMGain + sqrt(2.0 * AMGain) * K + Ksquared) * normal; + m_b1 = 2.0 * (Ksquared - AMGain) * normal; + m_b2 = (AMGain - sqrt(2.0 * AMGain) * K + Ksquared) * normal; + m_a1 = 2.0 * (Ksquared - 1.0) * normal; + m_a2 = (1.0 - M_SQRT2 * K + Ksquared) * normal; + } + else + { + normal = 1.0 / (AMGain + sqrt(2.0 * AMGain) * K + Ksquared); + m_b0 = (1.0 + M_SQRT2 * K + Ksquared) * normal; + m_b1 = 2.0 * (Ksquared - 1.0) * normal; + m_b2 = (1.0 - M_SQRT2 * K + Ksquared) * normal; + m_a1 = 2.0 * (Ksquared - AMGain) * normal; + m_a2 = (AMGain - sqrt(2.0 * AMGain) * K + Ksquared) * normal; + } + break; + default: + fatalerror("filter_biquad_device::recalc() - Invalid filter type!"); + break; + } + LOGMASKED(LOG_CALC,"Calculated Parameters:\n"); + LOGMASKED(LOG_CALC,"Gain (dB): %f, (raw): %f\n", DBGain, MGain); + LOGMASKED(LOG_CALC,"k: %f\n", K); + LOGMASKED(LOG_CALC,"normal: %f\n", normal); + LOGMASKED(LOG_CALC,"b0: %f\n", m_b0); + LOGMASKED(LOG_CALC,"b1: %f\n", m_b1); + LOGMASKED(LOG_CALC,"b2: %f\n", m_b2); + LOGMASKED(LOG_CALC,"a1: %f\n", m_a1); + LOGMASKED(LOG_CALC,"a2: %f\n", m_a2); } -#ifdef FLT_BIQUAD_DEBUG - logerror("Calculated Parameters:\n"); - logerror( "Gain (dB): %f, (raw): %f\n", DBGain, MGain); - logerror( "k: %f\n", K); - logerror( "normal: %f\n", normal); - logerror("b0: %f\n", m_b0); - logerror("b1: %f\n", m_b1); - logerror("b2: %f\n", m_b2); - logerror("a1: %f\n", m_a1); - logerror("a2: %f\n", m_a2); -#endif // peak and shelf filters do not use gain for the entire signal, only for the peak/shelf portions // side note: the first order lowpass and highpass filter analogs technically don't have gain either, // but this can be 'faked' by adjusting the bx factors, so we support that anyway, even if it isn't realistic. @@ -588,11 +615,9 @@ void filter_biquad_device::recalc() m_b0 *= m_gain; m_b1 *= m_gain; m_b2 *= m_gain; -#ifdef FLT_BIQUAD_DEBUG - logerror("b0g: %f\n", m_b0); - logerror("b1g: %f\n", m_b1); - logerror("b2g: %f\n", m_b2); -#endif + LOGMASKED(LOG_CALC,"b0g: %f\n", m_b0); + LOGMASKED(LOG_CALC,"b1g: %f\n", m_b1); + LOGMASKED(LOG_CALC,"b2g: %f\n", m_b2); } }