diff options
author | 2018-05-06 00:40:40 +1000 | |
---|---|---|
committer | 2018-05-06 00:51:27 +1000 | |
commit | 4ea3cd0bc1f54e47a0d38a47afac38101549e9ee (patch) | |
tree | bbadc20010b6bad48cf321b1c864655587e4b8ad /src/mame/audio/polepos.cpp | |
parent | bba5127d7a73ca44fdc0dcab7286846c81206771 (diff) |
Streamline machine configuration macros - everyone's a device edition.
Start replacing special device macros with additional constructors,
starting with ISA, INTELLEC 4 and RS-232 buses.
Allow an object finder to take on the target of another object finder.
(For a combination of the previous two things in action, see either the
INTELLEC 4 driver, or the Apple 2 PC Exporter card. Also check out
looping over a device finder array to instantiate devices in some
places. Lots of things no longer need to pass tags around.)
Start supplying default clocks for things that have a standard clock or
have all clocks internal.
Eliminate the separate DEV versions of the DEVCB_ macros. Previously,
the plain versions were a shortcut for DEVICE_SELF as the target. You
can now supply a string tag (relative to current device being
configured), an object finder (takes on the base and relative tag), or
a reference to a device/interface (only do this if you know the device
won't be replaced out from under it, but that's a safe assumption for
your subdevices). In almost all cases, you can get the effect you want
by supplying *this as the target.
Eliminate sound and CPU versions of macros. They serve no useful
purpose, provide no extra checks, make error messages longer, add
indirection, and mislead newbies into thinking there's a difference.
Remove a lot of now-unnecessary ":" prefixes binding things relative to
machine root.
Clean up some miscellaneous rot.
Examples of new functionality in use in (some more subtle than others):
* src/mame/drivers/intellec4.cpp
* src/mame/drivers/tranz330.cpp
* src/mame/drivers/osboren1.cpp
* src/mame/drivers/zorba.cpp
* src/mame/devices/smioc.cpp
* src/devices/bus/a2bus/pc_xporter.cpp
* src/devices/bus/isa/isa.h
* src/devices/bus/isa/isa.h
* src/devices/bus/intellec4/intellec4.h
Diffstat (limited to 'src/mame/audio/polepos.cpp')
-rw-r--r-- | src/mame/audio/polepos.cpp | 170 |
1 files changed, 74 insertions, 96 deletions
diff --git a/src/mame/audio/polepos.cpp b/src/mame/audio/polepos.cpp index cd3ee6a62c7..ee706143f4e 100644 --- a/src/mame/audio/polepos.cpp +++ b/src/mame/audio/polepos.cpp @@ -5,7 +5,7 @@ Sound handler ****************************************************************************/ #include "emu.h" -#include "includes/polepos.h" +#include "polepos.h" #include "namco52.h" #include "namco54.h" @@ -71,25 +71,81 @@ struct filter_state #define Q_TO_DAMP(q) (1.0/q) + /* Setup the filter context based on the passed filter type info. * type - 1 of the 3 defined filter types * fc - center frequency * d - damp = 1/Q * gain - overall filter gain. Set to 1 if not needed. */ -static void filter2_setup(device_t *device, int type, double fc, double d, double gain, - filter2_context *filter2); +void polepos_sound_device::filter2_context::setup(device_t *device, int type, double fc, double d, double gain) +{ + int const sample_rate = device->machine().sample_rate(); + double const two_over_T = 2*sample_rate; + double const two_over_T_squared = two_over_T * two_over_T; + + /* calculate digital filter coefficents */ + /* cutoff freq, in radians/sec */ + /*w = 2.0*M_PI*fc; no pre-warping */ + double const w = sample_rate*2.0*tan(M_PI*fc/sample_rate); /* pre-warping */ + double const w_squared = w*w; + + /* temp variable */ + double const den = two_over_T_squared + d*w*two_over_T + w_squared; + + a1 = 2.0*(-two_over_T_squared + w_squared)/den; + a2 = (two_over_T_squared - d*w*two_over_T + w_squared)/den; + + switch (type) + { + case FILTER_LOWPASS: + b0 = b2 = w_squared/den; + b1 = 2.0*(b0); + break; + case FILTER_BANDPASS: + b0 = d*w*two_over_T/den; + b1 = 0.0; + b2 = -(b0); + break; + case FILTER_HIGHPASS: + b0 = b2 = two_over_T_squared/den; + b1 = -2.0*(b0); + break; + default: + device->logerror("filter2_setup() - Invalid filter type for 2nd order filter."); + break; + } + + b0 *= gain; + b1 *= gain; + b2 *= gain; +} /* Reset the input/output voltages to 0. */ -static void filter2_reset(filter2_context *filter2); +void polepos_sound_device::filter2_context::reset() +{ + x0 = 0; + x1 = 0; + x2 = 0; + y0 = 0; + y1 = 0; + y2 = 0; +} /* Step the filter. * x0 is the new input, which needs to be set before stepping. * y0 is the new filter output. */ -static void filter2_step(filter2_context *filter2); +void polepos_sound_device::filter2_context::step() +{ + y0 = -a1 * y1 - a2 * y2 + b0 * x0 + b1 * x1 + b2 * x2; + x2 = x1; + x1 = x0; + y2 = y1; + y1 = y0; +} /* Setup a filter2 structure based on an op-amp multipole bandpass circuit. @@ -110,92 +166,16 @@ static void filter2_step(filter2_context *filter2); * gnd vRef >---' |/ * */ -static void filter_opamp_m_bandpass_setup(device_t *device, double r1, double r2, double r3, double c1, double c2, - filter2_context *filter2); - - -static void filter2_setup(device_t *device, int type, double fc, double d, double gain, - filter2_context *filter2) -{ - int sample_rate = device->machine().sample_rate(); - double w; /* cutoff freq, in radians/sec */ - double w_squared; - double den; /* temp variable */ - double two_over_T = 2*sample_rate; - double two_over_T_squared = two_over_T * two_over_T; - - /* calculate digital filter coefficents */ - /*w = 2.0*M_PI*fc; no pre-warping */ - w = sample_rate*2.0*tan(M_PI*fc/sample_rate); /* pre-warping */ - w_squared = w*w; - - den = two_over_T_squared + d*w*two_over_T + w_squared; - - filter2->a1 = 2.0*(-two_over_T_squared + w_squared)/den; - filter2->a2 = (two_over_T_squared - d*w*two_over_T + w_squared)/den; - - switch (type) - { - case FILTER_LOWPASS: - filter2->b0 = filter2->b2 = w_squared/den; - filter2->b1 = 2.0*(filter2->b0); - break; - case FILTER_BANDPASS: - filter2->b0 = d*w*two_over_T/den; - filter2->b1 = 0.0; - filter2->b2 = -(filter2->b0); - break; - case FILTER_HIGHPASS: - filter2->b0 = filter2->b2 = two_over_T_squared/den; - filter2->b1 = -2.0*(filter2->b0); - break; - default: - device->logerror("filter2_setup() - Invalid filter type for 2nd order filter."); - break; - } - - filter2->b0 *= gain; - filter2->b1 *= gain; - filter2->b2 *= gain; -} - - -/* Reset the input/output voltages to 0. */ -static void filter2_reset(filter2_context *filter2) -{ - filter2->x0 = 0; - filter2->x1 = 0; - filter2->x2 = 0; - filter2->y0 = 0; - filter2->y1 = 0; - filter2->y2 = 0; -} - - -/* Step the filter. */ -static void filter2_step(filter2_context *filter2) +void polepos_sound_device::filter2_context::opamp_m_bandpass_setup(device_t *device, double r1, double r2, double r3, double c1, double c2) { - filter2->y0 = -filter2->a1 * filter2->y1 - filter2->a2 * filter2->y2 + - filter2->b0 * filter2->x0 + filter2->b1 * filter2->x1 + filter2->b2 * filter2->x2; - filter2->x2 = filter2->x1; - filter2->x1 = filter2->x0; - filter2->y2 = filter2->y1; - filter2->y1 = filter2->y0; -} - - -/* Setup a filter2 structure based on an op-amp multipole bandpass circuit. */ -static void filter_opamp_m_bandpass_setup(device_t *device, double r1, double r2, double r3, double c1, double c2, - filter2_context *filter2) -{ - double r_in, fc, d, gain; - if (r1 == 0) { device->logerror("filter_opamp_m_bandpass_setup() - r1 can not be 0"); return; /* Filter can not be setup. Undefined results. */ } + double r_in, gain; + if (r2 == 0) { gain = 1; @@ -207,16 +187,16 @@ static void filter_opamp_m_bandpass_setup(device_t *device, double r1, double r2 r_in = 1.0 / (1.0/r1 + 1.0/r2); } - fc = 1.0 / (2 * M_PI * sqrt(r_in * r3 * c1 * c2)); - d = (c1 + c2) / sqrt(r3 / r_in * c1 * c2); + double const fc = 1.0 / (2 * M_PI * sqrt(r_in * r3 * c1 * c2)); + double const d = (c1 + c2) / sqrt(r3 / r_in * c1 * c2); gain *= -r3 / r_in * c2 / (c1 + c2); - filter2_setup(device, FILTER_BANDPASS, fc, d, gain, filter2); + setup(device, FILTER_BANDPASS, fc, d, gain); } // device type definition -DEFINE_DEVICE_TYPE(POLEPOS, polepos_sound_device, "polepos_sound", "Pole Position Custom Sound") +DEFINE_DEVICE_TYPE(POLEPOS_SOUND, polepos_sound_device, "polepos_sound", "Pole Position Custom Sound") //************************************************************************** @@ -228,7 +208,7 @@ DEFINE_DEVICE_TYPE(POLEPOS, polepos_sound_device, "polepos_sound", "Pole Positio //------------------------------------------------- polepos_sound_device::polepos_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, POLEPOS, tag, owner, clock), + : device_t(mconfig, POLEPOS_SOUND, tag, owner, clock), device_sound_interface(mconfig, *this), m_current_position(0), m_sample_msb(0), @@ -250,13 +230,11 @@ void polepos_sound_device::device_start() m_sample_enable = 0; /* setup the filters */ - filter_opamp_m_bandpass_setup(this, RES_K(220), RES_K(33), RES_K(390), CAP_U(.01), CAP_U(.01), - &m_filter_engine[0]); - filter_opamp_m_bandpass_setup(this, RES_K(150), RES_K(22), RES_K(330), CAP_U(.0047), CAP_U(.0047), - &m_filter_engine[1]); + m_filter_engine[0].opamp_m_bandpass_setup(this, RES_K(220), RES_K(33), RES_K(390), CAP_U(.01), CAP_U(.01)); + m_filter_engine[1].opamp_m_bandpass_setup(this, RES_K(150), RES_K(22), RES_K(330), CAP_U(.0047), CAP_U(.0047)); /* Filter 3 is a little different. Because of the input capacitor, it is * a high pass filter. */ - filter2_setup(this, FILTER_HIGHPASS, 950, Q_TO_DAMP(.707), 1, &m_filter_engine[2]); + m_filter_engine[2].setup(this, FILTER_HIGHPASS, 950, Q_TO_DAMP(.707), 1); } @@ -268,7 +246,7 @@ void polepos_sound_device::device_reset() { int loop; for (loop = 0; loop < 3; loop++) - filter2_reset(&m_filter_engine[loop]); + m_filter_engine[loop].reset(); } @@ -310,7 +288,7 @@ void polepos_sound_device::sound_stream_update(sound_stream &stream, stream_samp i_total = 0; for (loop = 0; loop < 3; loop++) { - filter2_step(&m_filter_engine[loop]); + m_filter_engine[loop].step(); /* The op-amp powered @ 5V will clip to 0V & 3.5V. * Adjusted to vRef of 2V, we will clip as follows: */ if (m_filter_engine[loop].y0 > 1.5) m_filter_engine[loop].y0 = 1.5; |