diff options
author | Aaron Giles <aaron@aarongiles.com> | 2012-02-25 19:21:35 +0000 |
---|---|---|
committer | Aaron Giles <aaron@aarongiles.com> | 2012-02-25 19:21:35 +0000 |
commit | 1ff793a4a83fd9b89f589d22418bcff8d7e215f1 (patch) | |
tree | 10e52fda9dad3ec5b4b4f436715be3a188e1d66f | |
parent | 19d720efc1b0b0eeddd3b50902a3a6df19548d8d (diff) |
Create a new device_mixer_interface, derived from device_sound_interface,
which mixes all its inputs to a single output stream. Redefined the
SPEAKER device to use this and remove the duplicate underlying logic.
The main purpose of this new interface is to allow device-ification of
an entire sound board, which can itself become a mixer of all of its
sound components to a single output stream. This stream can then be
routed by the device's owner to the appropriate speakers. A real-life
example will show up soon.
-rw-r--r-- | src/emu/device.c | 2 | ||||
-rw-r--r-- | src/emu/disound.c | 91 | ||||
-rw-r--r-- | src/emu/disound.h | 25 | ||||
-rw-r--r-- | src/emu/sound/bsmt2000.c | 4 | ||||
-rw-r--r-- | src/emu/speaker.c | 80 | ||||
-rw-r--r-- | src/emu/speaker.h | 22 |
6 files changed, 144 insertions, 80 deletions
diff --git a/src/emu/device.c b/src/emu/device.c index abe467f1122..e799185be2a 100644 --- a/src/emu/device.c +++ b/src/emu/device.c @@ -394,7 +394,7 @@ void device_t::start() state_registrations = machine().save().registration_count() - state_registrations; device_execute_interface *exec; device_sound_interface *sound; - if (state_registrations == 0 && (interface(exec) || interface(sound))) + if (state_registrations == 0 && (interface(exec) || interface(sound)) && type() != SPEAKER) { logerror("Device '%s' did not register any state to save!\n", tag()); if ((machine().system().flags & GAME_SUPPORTS_SAVE) != 0) diff --git a/src/emu/disound.c b/src/emu/disound.c index 2889d58f852..8fdf46cda30 100644 --- a/src/emu/disound.c +++ b/src/emu/disound.c @@ -79,9 +79,7 @@ void device_sound_interface::static_add_route(device_t &device, UINT32 output, c throw emu_fatalerror("MCFG_SOUND_ROUTE called on device '%s' with no sound interface", device.tag()); // append a new route to the list - astring devtag; - device.siblingtag(devtag, target); - sound->m_route_list.append(*global_alloc(sound_route(output, input, gain, devtag.cstr()))); + sound->m_route_list.append(*global_alloc(sound_route(output, input, gain, target))); } @@ -265,7 +263,7 @@ void device_sound_interface::interface_pre_start() for (const sound_route *route = sound->first_route(); route != NULL; route = route->next()) { // see if we are the target of this route; if we are, make sure the source device is started - device_t *target_device = m_device.machine().device(route->m_target); + device_t *target_device = sound->device().siblingdevice(route->m_target); if (target_device == &m_device && !sound->device().started()) throw device_missing_dependencies(); } @@ -279,7 +277,7 @@ void device_sound_interface::interface_pre_start() for (const sound_route *route = sound->first_route(); route != NULL; route = route->next()) { // see if we are the target of this route - device_t *target_device = m_device.machine().device(route->m_target); + device_t *target_device = sound->device().siblingdevice(route->m_target); if (target_device == &m_device && route->m_input == AUTO_ALLOC_INPUT) { const_cast<sound_route *>(route)->m_input = m_auto_allocated_inputs; @@ -305,7 +303,7 @@ void device_sound_interface::interface_post_start() for (const sound_route *route = sound->first_route(); route != NULL; route = route->next()) { // if we are the target of this route, hook it up - device_t *target_device = m_device.machine().device(route->m_target); + device_t *target_device = sound->device().siblingdevice(route->m_target); if (target_device == &m_device) { // iterate over all outputs, matching any that apply @@ -366,3 +364,84 @@ device_sound_interface::sound_route::sound_route(int output, int input, float ga m_target(target) { } + + + +//************************************************************************** +// SIMPLE DERIVED MIXER INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_mixer_interface - constructor +//------------------------------------------------- + +device_mixer_interface::device_mixer_interface(const machine_config &mconfig, device_t &device, int outputs) + : device_sound_interface(mconfig, device), + m_outputs(outputs), + m_mixer_stream(NULL) +{ +} + + +//------------------------------------------------- +// ~device_mixer_interface - destructor +//------------------------------------------------- + +device_mixer_interface::~device_mixer_interface() +{ +} + + +//------------------------------------------------- +// interface_pre_start - perform startup prior +// to the device startup +//------------------------------------------------- + +void device_mixer_interface::interface_pre_start() +{ + // call our parent + device_sound_interface::interface_pre_start(); + + // no inputs? that's weird + if (m_auto_allocated_inputs == 0) + { + logerror("Warning: mixer \"%s\" has no inputs\n", device().tag()); + return; + } + + // allocate the mixer stream + m_mixer_stream = stream_alloc(m_auto_allocated_inputs, m_outputs, device().machine().sample_rate()); +} + + +//------------------------------------------------- +// interface_post_load - after we load a save +// state be sure to update the mixer stream's +// output sample rate +//------------------------------------------------- + +void device_mixer_interface::interface_post_load() +{ + m_mixer_stream->set_sample_rate(device().machine().sample_rate()); + + // call our parent + device_sound_interface::interface_post_load(); +} + + +//------------------------------------------------- +// mixer_update - mix all inputs to one output +//------------------------------------------------- + +void device_mixer_interface::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +{ + // loop over samples + for (int pos = 0; pos < samples; pos++) + { + // add up all the inputs + INT32 sample = inputs[0][pos]; + for (int inp = 1; inp < m_auto_allocated_inputs; inp++) + sample += inputs[inp][pos]; + outputs[0][pos] = sample; + } +} diff --git a/src/emu/disound.h b/src/emu/disound.h index c94187337c4..365b59891da 100644 --- a/src/emu/disound.h +++ b/src/emu/disound.h @@ -152,4 +152,29 @@ protected: // iterator typedef device_interface_iterator<device_sound_interface> sound_interface_iterator; + + +// ======================> device_mixer_interface + +class device_mixer_interface : public device_sound_interface +{ +public: + // construction/destruction + device_mixer_interface(const machine_config &mconfig, device_t &device, int outputs = 1); + virtual ~device_mixer_interface(); + +protected: + // optional operation overrides + virtual void interface_pre_start(); + virtual void interface_post_load(); + + // sound interface overrides + virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + + // internal state + UINT8 m_outputs; // number of outputs + sound_stream * m_mixer_stream; // mixing stream +}; + + #endif /* __DISOUND_H__ */ diff --git a/src/emu/sound/bsmt2000.c b/src/emu/sound/bsmt2000.c index 20d9269cb85..f27d3fd0395 100644 --- a/src/emu/sound/bsmt2000.c +++ b/src/emu/sound/bsmt2000.c @@ -106,10 +106,6 @@ ROM_END // bsmt2000_device - constructor //------------------------------------------------- -//------------------------------------------------- -// bsmt2000_device - constructor -//------------------------------------------------- - bsmt2000_device::bsmt2000_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, BSMT2000, "BSMT2000", "bsmt2000", tag, owner, clock), device_sound_interface(mconfig, *this), diff --git a/src/emu/speaker.c b/src/emu/speaker.c index 0223170125f..9214309d803 100644 --- a/src/emu/speaker.c +++ b/src/emu/speaker.c @@ -45,9 +45,9 @@ -/*************************************************************************** - DEBUGGING -***************************************************************************/ +//************************************************************************** +// DEBUGGING +//************************************************************************** #define VERBOSE (0) @@ -56,23 +56,28 @@ //************************************************************************** -// LIVE SPEAKER DEVICE +// GLOBAL VARIABLES //************************************************************************** // device type definition const device_type SPEAKER = &device_creator<speaker_device>; + + +//************************************************************************** +// LIVE SPEAKER DEVICE +//************************************************************************** + //------------------------------------------------- // speaker_device - constructor //------------------------------------------------- speaker_device::speaker_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, SPEAKER, "Speaker", tag, owner, clock), - device_sound_interface(mconfig, *this), + device_mixer_interface(mconfig, *this), m_x(0.0), m_y(0.0), - m_z(0.0), - m_mixer_stream(NULL) + m_z(0.0) #ifdef MAME_DEBUG , m_max_sample(0), @@ -112,57 +117,6 @@ void speaker_device::static_set_position(device_t &device, double x, double y, d //------------------------------------------------- -// device_start - perform device-specific -// startup -//------------------------------------------------- - -void speaker_device::device_start() -{ - // no inputs? that's weird - if (m_auto_allocated_inputs == 0) - { - logerror("Warning: speaker \"%s\" has no inputs\n", tag()); - return; - } - - // allocate the mixer stream - m_mixer_stream = machine().sound().stream_alloc(*this, m_auto_allocated_inputs, 1, machine().sample_rate()); -} - - -//------------------------------------------------- -// device_post_load - after we load a save state -// be sure to update the mixer stream's output -// sample rate -//------------------------------------------------- - -void speaker_device::device_post_load() -{ - m_mixer_stream->set_sample_rate(machine().sample_rate()); -} - - -//------------------------------------------------- -// mixer_update - mix all inputs to one output -//------------------------------------------------- - -void speaker_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) -{ - VPRINTF(("Mixer_update(%d)\n", samples)); - - // loop over samples - for (int pos = 0; pos < samples; pos++) - { - // add up all the inputs - INT32 sample = inputs[0][pos]; - for (int inp = 1; inp < m_auto_allocated_inputs; inp++) - sample += inputs[inp][pos]; - outputs[0][pos] = sample; - } -} - - -//------------------------------------------------- // mix - mix in samples from the speaker's stream //------------------------------------------------- @@ -223,3 +177,13 @@ void speaker_device::mix(INT32 *leftmix, INT32 *rightmix, int &samples_this_upda rightmix[sample] += stream_buf[sample]; } } + + +//------------------------------------------------- +// device_start - handle device startup +//------------------------------------------------- + +void speaker_device::device_start() +{ + // dummy save to make device.c happy +} diff --git a/src/emu/speaker.h b/src/emu/speaker.h index 3ead6eab11c..cf0b2f04130 100644 --- a/src/emu/speaker.h +++ b/src/emu/speaker.h @@ -48,6 +48,15 @@ //************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definition +extern const device_type SPEAKER; + + + +//************************************************************************** // DEVICE CONFIGURATION MACROS //************************************************************************** @@ -72,7 +81,7 @@ // ======================> speaker_device class speaker_device : public device_t, - public device_sound_interface + public device_mixer_interface { friend resource_pool_object<speaker_device>::~resource_pool_object(); @@ -89,11 +98,7 @@ public: protected: // device-level overrides - virtual void device_start(); - virtual void device_post_load(); - - // sound interface overrides - virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + virtual void device_start() ATTR_COLD; // inline configuration state double m_x; @@ -101,7 +106,6 @@ protected: double m_z; // internal state - sound_stream * m_mixer_stream; // mixing stream #ifdef MAME_DEBUG INT32 m_max_sample; // largest sample value we've seen INT32 m_clipped_samples; // total number of clipped samples @@ -110,10 +114,6 @@ protected: }; -// device type definition -extern const device_type SPEAKER; - - // speaker device iterator typedef device_type_iterator<&device_creator<speaker_device>, speaker_device> speaker_device_iterator; |