From 97a195ef03cc2bfa735d2d077cac7bb5ca7c5e6b Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 23 Apr 2016 13:31:47 +0200 Subject: [PATCH] Removed specific filter implementation and merged it with placed where used (nw) --- scripts/src/emu.lua | 2 - src/emu/sound/filter.cpp | 234 ------------------------------------ src/emu/sound/filter.h | 133 -------------------- src/mame/audio/polepos.cpp | 184 ++++++++++++++++++++++++++++ src/mame/includes/polepos.h | 23 +++- 5 files changed, 206 insertions(+), 370 deletions(-) delete mode 100644 src/emu/sound/filter.cpp delete mode 100644 src/emu/sound/filter.h diff --git a/scripts/src/emu.lua b/scripts/src/emu.lua index 97a312cd492..373aa92d5fc 100644 --- a/scripts/src/emu.lua +++ b/scripts/src/emu.lua @@ -205,8 +205,6 @@ files { MAME_DIR .. "src/emu/debug/express.h", MAME_DIR .. "src/emu/debug/textbuf.cpp", MAME_DIR .. "src/emu/debug/textbuf.h", - MAME_DIR .. "src/emu/sound/filter.cpp", - MAME_DIR .. "src/emu/sound/filter.h", MAME_DIR .. "src/emu/sound/wavwrite.cpp", MAME_DIR .. "src/emu/sound/wavwrite.h", MAME_DIR .. "src/emu/drivers/empty.cpp", diff --git a/src/emu/sound/filter.cpp b/src/emu/sound/filter.cpp deleted file mode 100644 index b01ec7efc4b..00000000000 --- a/src/emu/sound/filter.cpp +++ /dev/null @@ -1,234 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Derrick Renaud, Couriersud -#include "emu.h" -#include "filter.h" - -static filter* filter_alloc(void) { - auto f = global_alloc(filter); - return f; -} - -void filter_free(filter* f) { - global_free(f); -} - -void filter_state_reset(filter* f, filter_state* s) { - int i; - s->prev_mac = 0; - for(i=0;iorder;++i) { - s->xprev[i] = 0; - } -} - -filter_state* filter_state_alloc(void) { - int i; - auto s = global_alloc(filter_state); - s->prev_mac = 0; - for(i=0;ixprev[i] = 0; - return s; -} - -void filter_state_free(filter_state* s) { - global_free(s); -} - -/****************************************************************************/ -/* FIR */ - -filter_real filter_compute(filter* f, filter_state* s) { - unsigned order = f->order; - unsigned midorder = f->order / 2; - filter_real y = 0; - unsigned i,j,k; - - /* i == [0] */ - /* j == [-2*midorder] */ - i = s->prev_mac; - j = i + 1; - if (j == order) - j = 0; - - /* x */ - for(k=0;kxcoeffs[midorder-k] * (s->xprev[i] + s->xprev[j]); - ++j; - if (j == order) - j = 0; - if (i == 0) - i = order - 1; - else - --i; - } - y += f->xcoeffs[0] * s->xprev[i]; - -#ifdef FILTER_USE_INT - return y >> FILTER_INT_FRACT; -#else - return y; -#endif -} - -filter* filter_lp_fir_alloc(double freq, int order) { - filter* f = filter_alloc(); - unsigned midorder = (order - 1) / 2; - unsigned i; - double gain; - - assert( order <= FILTER_ORDER_MAX ); - assert( order % 2 == 1 ); - assert( 0 < freq && freq <= 0.5 ); - - /* Compute the antitrasform of the perfect low pass filter */ - gain = 2*freq; -#ifdef FILTER_USE_INT - f->xcoeffs[0] = gain * (1 << FILTER_INT_FRACT); -#else - f->xcoeffs[0] = gain; -#endif - for(i=1;i<=midorder;++i) { - /* number of the sample starting from 0 to (order-1) included */ - unsigned n = i + midorder; - - /* sample value */ - double c = sin(2*M_PI*freq*i) / (M_PI*i); - - /* apply only one window or none */ - /* double w = 2 - 2*n/(order-1); */ /* Bartlett (triangular) */ - /* double w = 0.5 * (1 - cos(2*M_PI*n/(order-1))); */ /* Hanning */ - double w = 0.54 - 0.46 * cos(2*M_PI*n/(order-1)); /* Hamming */ - /* double w = 0.42 - 0.5 * cos(2*M_PI*n/(order-1)) + 0.08 * cos(4*M_PI*n/(order-1)); */ /* Blackman */ - - /* apply the window */ - c *= w; - - /* update the gain */ - gain += 2*c; - - /* insert the coeff */ -#ifdef FILTER_USE_INT - f->xcoeffs[i] = c * (1 << FILTER_INT_FRACT); -#else - f->xcoeffs[i] = c; -#endif - } - - /* adjust the gain to be exact 1.0 */ - for(i=0;i<=midorder;++i) { -#ifdef FILTER_USE_INT - f->xcoeffs[i] /= gain; -#else - f->xcoeffs[i] = f->xcoeffs[i] * (double)(1 << FILTER_INT_FRAC) / gain; -#endif - } - - /* decrease the order if the last coeffs are 0 */ - i = midorder; - while (i > 0 && f->xcoeffs[i] == 0.0) - --i; - - f->order = i * 2 + 1; - - return f; -} - - -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. */ -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. */ -void filter2_step(filter2_context *filter2) -{ - 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. */ -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. */ - } - - if (r2 == 0) - { - gain = 1; - r_in = r1; - } - else - { - gain = r2 / (r1 + 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); - gain *= -r3 / r_in * c2 / (c1 + c2); - - filter2_setup(device, FILTER_BANDPASS, fc, d, gain, filter2); -} diff --git a/src/emu/sound/filter.h b/src/emu/sound/filter.h deleted file mode 100644 index ef13c45eb5f..00000000000 --- a/src/emu/sound/filter.h +++ /dev/null @@ -1,133 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Derrick Renaud, Couriersud -#pragma once - -#ifndef __FILTER_H__ -#define __FILTER_H__ - -/* Max filter order */ -#define FILTER_ORDER_MAX 51 - -/* Define to use integer calculation */ -#define FILTER_USE_INT - -#ifdef FILTER_USE_INT -typedef int filter_real; -#define FILTER_INT_FRACT 15 /* fractional bits */ -#else -typedef double filter_real; -#endif - -struct filter -{ - filter_real xcoeffs[(FILTER_ORDER_MAX+1)/2]; - unsigned order; -}; - -struct filter_state -{ - unsigned prev_mac; - filter_real xprev[FILTER_ORDER_MAX]; -}; - -/* Allocate a FIR Low Pass filter */ -filter* filter_lp_fir_alloc(double freq, int order); -void filter_free(filter* f); - -/* Allocate a filter state */ -filter_state* filter_state_alloc(void); - -/* Free the filter state */ -void filter_state_free(filter_state* s); - -/* Clear the filter state */ -void filter_state_reset(filter* f, filter_state* s); - -/* Insert a value in the filter state */ -static inline void filter_insert(filter* f, filter_state* s, filter_real x) { - /* next state */ - ++s->prev_mac; - if (s->prev_mac >= f->order) - s->prev_mac = 0; - - /* set x[0] */ - s->xprev[s->prev_mac] = x; -} - -/* Compute the filter output */ -filter_real filter_compute(filter* f, filter_state* s); - - -/* Filter types */ -#define FILTER_LOWPASS 0 -#define FILTER_HIGHPASS 1 -#define FILTER_BANDPASS 2 - -#define Q_TO_DAMP(q) (1.0/q) - -struct filter2_context -{ - filter2_context() : - x0(0.0), - x1(0.0), - x2(0.0), - y0(0.0), - y1(0.0), - y2(0.0), - a1(0.0), - a2(0.0), - b0(0.0), - b1(0.0), - b2(0.0) - {} - - double x0, x1, x2; /* x[k], x[k-1], x[k-2], current and previous 2 input values */ - double y0, y1, y2; /* y[k], y[k-1], y[k-2], current and previous 2 output values */ - double a1, a2; /* digital filter coefficients, denominator */ - double b0, b1, b2; /* digital filter coefficients, numerator */ -}; - - -/* 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. - */ -void filter2_setup(device_t *device, int type, double fc, double d, double gain, - filter2_context *filter2); - - -/* Reset the input/output voltages to 0. */ -void filter2_reset(filter2_context *filter2); - - -/* Step the filter. - * x0 is the new input, which needs to be set before stepping. - * y0 is the new filter output. - */ -void filter2_step(filter2_context *filter2); - - -/* Setup a filter2 structure based on an op-amp multipole bandpass circuit. - * NOTE: If r2 is not used then set to 0. - * vRef is not needed to setup filter. - * - * .--------+---------. - * | | | - * --- c1 Z | - * --- Z r3 | - * | Z | - * r1 | c2 | |\ | - * In >----ZZZZ----+---------+--||----+ | \ | - * Z '--|- \ | - * Z r2 | >--+------> out - * Z .--|+ / - * | | | / - * gnd vRef >---' |/ - * - */ -void filter_opamp_m_bandpass_setup(device_t *device, double r1, double r2, double r3, double c1, double c2, - filter2_context *filter2); - -#endif /* __FILTER_H__ */ diff --git a/src/mame/audio/polepos.cpp b/src/mame/audio/polepos.cpp index e3e23b2fdef..ba46edb5a9c 100644 --- a/src/mame/audio/polepos.cpp +++ b/src/mame/audio/polepos.cpp @@ -36,7 +36,191 @@ static const double volume_table[8] = static const double r_filt_out[3] = {RES_K(4.7), RES_K(7.5), RES_K(10)}; static const double r_filt_total = 1.0 / (1.0/RES_K(4.7) + 1.0/RES_K(7.5) + 1.0/RES_K(10)); +/* Max filter order */ +#define FILTER_ORDER_MAX 51 +/* Define to use integer calculation */ +#define FILTER_USE_INT + +#ifdef FILTER_USE_INT +typedef int filter_real; +#define FILTER_INT_FRACT 15 /* fractional bits */ +#else +typedef double filter_real; +#endif + +struct filter +{ + filter_real xcoeffs[(FILTER_ORDER_MAX+1)/2]; + unsigned order; +}; + +struct filter_state +{ + unsigned prev_mac; + filter_real xprev[FILTER_ORDER_MAX]; +}; + +/* Insert a value in the filter state */ +static inline void filter_insert(filter* f, filter_state* s, filter_real x) { + /* next state */ + ++s->prev_mac; + if (s->prev_mac >= f->order) + s->prev_mac = 0; + + /* set x[0] */ + s->xprev[s->prev_mac] = x; +} + +/* Filter types */ +#define FILTER_LOWPASS 0 +#define FILTER_HIGHPASS 1 +#define FILTER_BANDPASS 2 + +#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); + + +/* Reset the input/output voltages to 0. */ +static void filter2_reset(filter2_context *filter2); + + +/* 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); + + +/* Setup a filter2 structure based on an op-amp multipole bandpass circuit. + * NOTE: If r2 is not used then set to 0. + * vRef is not needed to setup filter. + * + * .--------+---------. + * | | | + * --- c1 Z | + * --- Z r3 | + * | Z | + * r1 | c2 | |\ | + * In >----ZZZZ----+---------+--||----+ | \ | + * Z '--|- \ | + * Z r2 | >--+------> out + * Z .--|+ / + * | | | / + * 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) +{ + 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. */ + } + + if (r2 == 0) + { + gain = 1; + r_in = r1; + } + else + { + gain = r2 / (r1 + 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); + gain *= -r3 / r_in * c2 / (c1 + c2); + + filter2_setup(device, FILTER_BANDPASS, fc, d, gain, filter2); +} // device type definition diff --git a/src/mame/includes/polepos.h b/src/mame/includes/polepos.h index 16f0963c709..dfbad5505ec 100644 --- a/src/mame/includes/polepos.h +++ b/src/mame/includes/polepos.h @@ -6,11 +6,32 @@ *************************************************************************/ -#include "sound/filter.h" #include "sound/namco.h" #include "sound/tms5220.h" #include "sound/discrete.h" +struct filter2_context +{ + filter2_context() : + x0(0.0), + x1(0.0), + x2(0.0), + y0(0.0), + y1(0.0), + y2(0.0), + a1(0.0), + a2(0.0), + b0(0.0), + b1(0.0), + b2(0.0) + {} + + double x0, x1, x2; /* x[k], x[k-1], x[k-2], current and previous 2 input values */ + double y0, y1, y2; /* y[k], y[k-1], y[k-2], current and previous 2 output values */ + double a1, a2; /* digital filter coefficients, denominator */ + double b0, b1, b2; /* digital filter coefficients, numerator */ +}; + class polepos_state : public driver_device {