summaryrefslogtreecommitdiffstats
path: root/src/mame/audio/polepos.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/audio/polepos.cpp')
-rw-r--r--src/mame/audio/polepos.cpp170
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;