From 956d9332a94b750c912f15584d33412caf89f40d Mon Sep 17 00:00:00 2001 From: Ivan Vangelista Date: Sun, 4 Aug 2013 09:47:44 +0000 Subject: [PATCH] Modernized Mirco3D noise device. [Osso] --- src/mame/audio/micro3d.c | 264 +++++++++++++----------------------- src/mame/includes/micro3d.h | 48 ++++++- 2 files changed, 137 insertions(+), 175 deletions(-) diff --git a/src/mame/audio/micro3d.c b/src/mame/audio/micro3d.c index 2f4c72c2670..258d9bdae49 100644 --- a/src/mame/audio/micro3d.c +++ b/src/mame/audio/micro3d.c @@ -8,63 +8,11 @@ #include "emu.h" #include "includes/micro3d.h" -#include "devlegcy.h" #define MM5837_CLOCK 100000 -/************************************* - * - * Type definitions - * - *************************************/ - -struct biquad -{ - double a0, a1, a2; /* Numerator coefficients */ - double b0, b1, b2; /* Denominator coefficients */ -}; - -struct lp_filter -{ - float *history; - float *coef; - double fs; - biquad ProtoCoef[2]; -}; - -struct filter_state -{ - double capval; - double exponent; -}; - -struct noise_state -{ - union - { - struct - { - UINT8 vcf; - UINT8 vcq; - UINT8 vca; - UINT8 pan; - }; - UINT8 dac[4]; - }; - - float gain; - UINT32 noise_shift; - UINT8 noise_value; - UINT8 noise_subcount; - - filter_state noise_filters[4]; - lp_filter filter; - sound_stream *stream; -}; - - /************************************* * * Pink noise filtering @@ -177,49 +125,106 @@ static void recompute_filter(lp_filter *iir, double k, double q, double fc) iir->coef[0] = k; } -void micro3d_noise_sh_w(running_machine &machine, UINT8 data) +void micro3d_sound_device::noise_sh_w(UINT8 data) { - micro3d_state *state = machine.driver_data(); + micro3d_state *state = machine().driver_data(); if (~data & 8) { - device_t *device = machine.device(data & 4 ? "noise_2" : "noise_1"); - noise_state *nstate = (noise_state *)downcast(device)->token(); - - if (state->m_dac_data != nstate->dac[data & 3]) + if (state->m_dac_data != m_dac[data & 3]) { double q; double fc; - nstate->stream->update(); + m_stream->update(); - nstate->dac[data & 3] = state->m_dac_data; + m_dac[data & 3] = state->m_dac_data; - if (nstate->vca == 255) - nstate->gain = 0; + if (m_vca == 255) + m_gain = 0; else - nstate->gain = exp(-(float)(nstate->vca) / 25.0) * 10.0; + m_gain = exp(-(float)(m_vca) / 25.0) * 10.0; - q = 0.75/255 * (255 - nstate->vcq) + 0.1; - fc = 4500.0/255 * (255 - nstate->vcf) + 100; + q = 0.75/255 * (255 - m_vcq) + 0.1; + fc = 4500.0/255 * (255 - m_vcf) + 100; - recompute_filter(&nstate->filter, nstate->gain, q, fc); + recompute_filter(&m_filter, m_gain, q, fc); } } } -INLINE noise_state *get_safe_token(device_t *device) -{ - assert(device != NULL); - assert(device->type() == MICRO3D); - return (noise_state *)downcast(device)->token(); +/************************************* + * + * Initialisation + * + *************************************/ + + +const device_type MICRO3D = &device_creator; + +micro3d_sound_device::micro3d_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, MICRO3D, "Microprose Custom", tag, owner, clock, "micro3d_sound", __FILE__), + device_sound_interface(mconfig, *this), + m_vcf(0), + m_vcq(0), + m_vca(0), + m_pan(0), + m_gain(0), + m_noise_shift(0), + m_noise_value(0), + m_noise_subcount(0), + m_stream(NULL) +{ } -static STREAM_UPDATE( micro3d_stream_update ) +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void micro3d_sound_device::device_config_complete() { - noise_state *state = (noise_state *)param; - lp_filter *iir = &state->filter; +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void micro3d_sound_device::device_start() +{ + /* Allocate the stream */ + m_stream = machine().sound().stream_alloc(*this, 0, 2, machine().sample_rate(), this); + filter_init(machine(), &m_filter, machine().sample_rate()); + + configure_filter(&m_noise_filters[0], 2.7e3 + 2.7e3, 1.0e-6); + configure_filter(&m_noise_filters[1], 2.7e3 + 1e3, 0.30e-6); + configure_filter(&m_noise_filters[2], 2.7e3 + 270, 0.15e-6); + configure_filter(&m_noise_filters[3], 2.7e3 + 0, 0.082e-6); +// configure_filter(&m_noise_filters[4], 33e3, 0.1e-6); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void micro3d_sound_device::device_reset() +{ + m_noise_shift = 0x15555; + m_dac[0] = 255; + m_dac[1] = 255; + m_dac[2] = 255; + m_dac[3] = 255; +} + +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- + +void micro3d_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +{ + lp_filter *iir = &m_filter; float pan_l, pan_r; stream_sample_t *fl = &outputs[0][0]; @@ -229,11 +234,11 @@ static STREAM_UPDATE( micro3d_stream_update ) memset(outputs[0], 0, samples * sizeof(*outputs[0])); memset(outputs[1], 0, samples * sizeof(*outputs[1])); - if (state->gain == 0) + if (m_gain == 0) return; - pan_l = (float)(255 - state->pan) / 255.0; - pan_r = (float)(state->pan) / 255.0; + pan_l = (float)(255 - m_pan) / 255.0; + pan_r = (float)(m_pan) / 255.0; while (samples--) { @@ -244,21 +249,21 @@ static STREAM_UPDATE( micro3d_stream_update ) int step; /* Update the noise source */ - for (step = 2000000 / (2000000/8); step >= state->noise_subcount; step -= state->noise_subcount) + for (step = 2000000 / (2000000/8); step >= m_noise_subcount; step -= m_noise_subcount) { - state->noise_shift = (state->noise_shift << 1) | (((state->noise_shift >> 13) ^ (state->noise_shift >> 16)) & 1); - state->noise_value = (state->noise_shift >> 16) & 1; - state->noise_subcount = 2000000 / MM5837_CLOCK; + m_noise_shift = (m_noise_shift << 1) | (((m_noise_shift >> 13) ^ (m_noise_shift >> 16)) & 1); + m_noise_value = (m_noise_shift >> 16) & 1; + m_noise_subcount = 2000000 / MM5837_CLOCK; } - state->noise_subcount -= step; - input = (float)state->noise_value - 0.5; + m_noise_subcount -= step; + input = (float)m_noise_value - 0.5; white = input; /* Pink noise filtering */ - state->noise_filters[0].capval = 0.99765 * state->noise_filters[0].capval + input * 0.0990460; - state->noise_filters[1].capval = 0.96300 * state->noise_filters[1].capval + input * 0.2965164; - state->noise_filters[2].capval = 0.57000 * state->noise_filters[2].capval + input * 1.0526913; - input = state->noise_filters[0].capval + state->noise_filters[1].capval + state->noise_filters[2].capval + input * 0.1848; + m_noise_filters[0].capval = 0.99765 * m_noise_filters[0].capval + input * 0.0990460; + m_noise_filters[1].capval = 0.96300 * m_noise_filters[1].capval + input * 0.2965164; + m_noise_filters[2].capval = 0.57000 * m_noise_filters[2].capval + input * 1.0526913; + input = m_noise_filters[0].capval + m_noise_filters[1].capval + m_noise_filters[2].capval + input * 0.1848; input += white; input *= 200.0f; @@ -300,40 +305,6 @@ static STREAM_UPDATE( micro3d_stream_update ) } } - -/************************************* - * - * Initialisation - * - *************************************/ - -static DEVICE_START( micro3d_sound ) -{ - running_machine &machine = device->machine(); - noise_state *state = get_safe_token(device); - - /* Allocate the stream */ - state->stream = device->machine().sound().stream_alloc(*device, 0, 2, machine.sample_rate(), state, micro3d_stream_update); - filter_init(machine, &state->filter, machine.sample_rate()); - - configure_filter(&state->noise_filters[0], 2.7e3 + 2.7e3, 1.0e-6); - configure_filter(&state->noise_filters[1], 2.7e3 + 1e3, 0.30e-6); - configure_filter(&state->noise_filters[2], 2.7e3 + 270, 0.15e-6); - configure_filter(&state->noise_filters[3], 2.7e3 + 0, 0.082e-6); -// configure_filter(&state->noise_filters[4], 33e3, 0.1e-6); -} - -static DEVICE_RESET( micro3d_sound ) -{ - noise_state *state = get_safe_token(device); - state->noise_shift = 0x15555; - state->dac[0] = 255; - state->dac[1] = 255; - state->dac[2] = 255; - state->dac[3] = 255; -} - - /*************************************************************************** 8031 port mappings: @@ -370,7 +341,8 @@ WRITE8_MEMBER(micro3d_state::micro3d_sound_io_w) { case 0x01: { - micro3d_noise_sh_w(machine(), data); + micro3d_sound_device *noise = machine().device(data & 4 ? "noise_2" : "noise_1"); + noise->noise_sh_w(data); break; } case 0x03: @@ -398,51 +370,3 @@ WRITE8_MEMBER(micro3d_state::micro3d_upd7759_w) m_upd7759->start_w(0); m_upd7759->start_w(1); } - - -const device_type MICRO3D = &device_creator; - -micro3d_sound_device::micro3d_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, MICRO3D, "Microprose Custom", tag, owner, clock, "micro3d_sound", __FILE__), - device_sound_interface(mconfig, *this) -{ - m_token = global_alloc_clear(noise_state); -} - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void micro3d_sound_device::device_config_complete() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void micro3d_sound_device::device_start() -{ - DEVICE_START_NAME( micro3d_sound )(this); -} - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void micro3d_sound_device::device_reset() -{ - DEVICE_RESET_NAME( micro3d_sound )(this); -} - -//------------------------------------------------- -// sound_stream_update - handle a stream update -//------------------------------------------------- - -void micro3d_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) -{ - // should never get here - fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); -} diff --git a/src/mame/includes/micro3d.h b/src/mame/includes/micro3d.h index 9bdeb47135b..03080ab9cea 100644 --- a/src/mame/includes/micro3d.h +++ b/src/mame/includes/micro3d.h @@ -12,6 +12,7 @@ #define VGB_MONITOR_DISPLAY 0 #define DRMATH_MONITOR_DISPLAY 0 + class micro3d_state : public driver_device { public: @@ -155,17 +156,35 @@ void micro3d_duart_tx(device_t *device, int channel, UINT8 data); /*----------- defined in audio/micro3d.c -----------*/ -void micro3d_noise_sh_w(running_machine &machine, UINT8 data); +struct biquad +{ + double a0, a1, a2; /* Numerator coefficients */ + double b0, b1, b2; /* Denominator coefficients */ +}; + +struct lp_filter +{ + float *history; + float *coef; + double fs; + biquad ProtoCoef[2]; +}; + +struct filter_state +{ + double capval; + double exponent; +}; class micro3d_sound_device : public device_t, public device_sound_interface { public: micro3d_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - ~micro3d_sound_device() { global_free(m_token); } + ~micro3d_sound_device() {} - // access to legacy token - void *token() const { assert(m_token != NULL); return m_token; } + void noise_sh_w(UINT8 data); + protected: // device-level overrides virtual void device_config_complete(); @@ -176,7 +195,26 @@ protected: virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); private: // internal state - void *m_token; + union + { + struct + { + UINT8 m_vcf; + UINT8 m_vcq; + UINT8 m_vca; + UINT8 m_pan; + }; + UINT8 m_dac[4]; + }; + + float m_gain; + UINT32 m_noise_shift; + UINT8 m_noise_value; + UINT8 m_noise_subcount; + + filter_state m_noise_filters[4]; + lp_filter m_filter; + sound_stream *m_stream; }; extern const device_type MICRO3D;