Add a differentiator bandpass filter primitive to flt_biquad.cpp. [Lord Nightmare]

This commit is contained in:
Lord-Nightmare 2021-07-04 00:52:13 -04:00
parent ffae83ced3
commit a79bc2d558
4 changed files with 68 additions and 5 deletions

View File

@ -167,10 +167,11 @@ filter_biquad_device::biquad_params filter_biquad_device::opamp_sk_lowpass_calc(
return r;
}
// Multiple-Feedback filters
// (This is sometimes called a 'Rauch' filter circuit.)
/* 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.
@ -232,10 +233,15 @@ filter_biquad_device::biquad_params filter_biquad_device::opamp_mfb_lowpass_calc
}
/* Setup a biquad filter structure based on a single op-amp Multiple-Feedback band-pass filter circuit.
* NOTE: vRef is not definable when setting up the filter.
* This is sometimes called a "modified Deliyannis" or "Deliyannis-friend" filter circuit,
* or an "Infinite Gain Multiple-Feedback [band-pass] Filter", or "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.
* NOTE2: If r2 is not used, then set it to 0 ohms, the code will ignore it and assume a fixed gain of 1.
* 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 0 ohms, the code will switch to an Infinite Gain MFB Bandpass
*
* .--------+---------.
* | | |
@ -315,6 +321,58 @@ filter_biquad_device& filter_biquad_device::opamp_mfb_highpass_setup(double r1,
return setup(biquad_type::HIGHPASS, fc, q, gain);
}
/* 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.
*
* .--------+---------.
* | | |
* --- c2 Z |
* --- Z r2 |
* | Z |
* r1 c1 | | |\ |
* In >----ZZZZ-----||-----+--------+ | \ |
* '--|- \ |
* | >--+------> out
* .--|+ /
* | | /
* vRef >---' |/
*
*/
filter_biquad_device& filter_biquad_device::opamp_diff_bandpass_setup(double r1, double r2, double c1, double c2)
{
filter_biquad_device::biquad_params p = opamp_diff_bandpass_calc(r1, r2, c1, c2);
return setup(p);
}
void filter_biquad_device::opamp_diff_bandpass_modify(double r1, double r2, double c1, double c2)
{
filter_biquad_device::biquad_params p = opamp_diff_bandpass_calc(r1, r2, c1, c2);
modify(p);
}
filter_biquad_device::biquad_params filter_biquad_device::opamp_diff_bandpass_calc(double r1, double r2, double c1, double c2)
{
filter_biquad_device::biquad_params r;
if ((r1 == 0) || (r2 == 0) || (c1 == 0) || (c2 == 0))
{
fatalerror("filter_biquad_device::opamp_diff_bandpass_calc() - no parameters can be 0; parameters were: r1: %f, r2: %f, c1: %f, c2: %f", r1, r2, c1, c2); /* Filter can not be setup. Undefined results. */
}
r.gain = -r2 / r1;
double const f1 = 1.0 / (2 * M_PI * r1 * c1);
double const f2 = 1.0 / (2 * M_PI * r2 * c2);
double const fct = (log10(f1) + log10(f2)) / 2.0;
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<int>(r.type), r.fc, f1, f2, r.q, r.gain);
#endif
return r;
}
//-------------------------------------------------
// device_start - device-specific startup

View File

@ -68,6 +68,11 @@ public:
// Multiple-Feedback high-pass
filter_biquad_device& opamp_mfb_highpass_setup(double r1, double r2, double c1, double c2, double c3);
// Differentiator band-pass
filter_biquad_device& opamp_diff_bandpass_setup(double r1, double r2, double c1, double c2);
void opamp_diff_bandpass_modify(double r1, double r2, double c1, double c2);
biquad_params opamp_diff_bandpass_calc(double r1, double r2, double c1, double c2);
protected:
// device-level overrides

View File

@ -63,7 +63,7 @@
* W5 : enables /RESET from J1 P14 (this makes the board reset on S11 power up reset only). absent.
* W6 : enables the 3.579545MHz clock to the YM2151. present.
* W7 : ties J4 pin 1 and 2 to GND. absent, despite being present on the schematics.
* W8 : ties J4 pin 5-through-inductor and the final audio power amp + pins to +12v. absent, as power is presuambly delivered in through J4 pin 5 instead.
* W8 : ties J4 pin 5-through-inductor and the final audio power amp + pins to +12v. absent, as power is presumably delivered in through J4 pin 5 instead.
* see https://a.allegroimg.com/s1024/0c2cfa/0433164f4bfa94aa99cec60874f5 re: W2 being connected on the real board. (also see undumped REV1 rom)
* see https://a.allegroimg.com/s1024/0c3dce/74cdfa004e1dbac943986a94999b re: W8 being absent

View File

@ -7,7 +7,7 @@
XTAL: Y1 16MHz
XTAL: Y2 32.768KHz
LCDC: ST7626 (https://www.crystalfontz.com/controllers/Sitronix/ST7626/)
the ST7626 is embedded into a epoxy part just below the screen glass with the flex cable attached to iter_swap
the ST7626 is embedded into a epoxy part just below the screen glass with the flex cable attached to it
it has internal 98x68x16bit ram
Extremely preliminary