summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/sound/filter.h
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/sound/filter.h')
-rw-r--r--trunk/src/emu/sound/filter.h120
1 files changed, 120 insertions, 0 deletions
diff --git a/trunk/src/emu/sound/filter.h b/trunk/src/emu/sound/filter.h
new file mode 100644
index 00000000000..802add09701
--- /dev/null
+++ b/trunk/src/emu/sound/filter.h
@@ -0,0 +1,120 @@
+#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
+
+typedef struct _filter filter;
+struct _filter
+{
+ filter_real xcoeffs[(FILTER_ORDER_MAX+1)/2];
+ unsigned order;
+};
+
+typedef struct _filter_state filter_state;
+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 */
+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)
+
+typedef struct _filter2_context filter2_context;
+struct _filter2_context
+{
+ 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__ */