summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
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
commit1ff793a4a83fd9b89f589d22418bcff8d7e215f1 (patch)
tree10e52fda9dad3ec5b4b4f436715be3a188e1d66f
parent19d720efc1b0b0eeddd3b50902a3a6df19548d8d (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.c2
-rw-r--r--src/emu/disound.c91
-rw-r--r--src/emu/disound.h25
-rw-r--r--src/emu/sound/bsmt2000.c4
-rw-r--r--src/emu/speaker.c80
-rw-r--r--src/emu/speaker.h22
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;