mirror of
https://github.com/holub/mame
synced 2025-05-19 20:29:09 +03:00
Whoops, missed some files.
This commit is contained in:
parent
b36244a734
commit
ce62988c27
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1142,6 +1142,8 @@ src/emu/sound/ymz280b.c svneol=native#text/plain
|
|||||||
src/emu/sound/ymz280b.h svneol=native#text/plain
|
src/emu/sound/ymz280b.h svneol=native#text/plain
|
||||||
src/emu/sound/zsg2.c svneol=native#text/plain
|
src/emu/sound/zsg2.c svneol=native#text/plain
|
||||||
src/emu/sound/zsg2.h svneol=native#text/plain
|
src/emu/sound/zsg2.h svneol=native#text/plain
|
||||||
|
src/emu/speaker.c svneol=native#text/plain
|
||||||
|
src/emu/speaker.h svneol=native#text/plain
|
||||||
src/emu/state.c svneol=native#text/plain
|
src/emu/state.c svneol=native#text/plain
|
||||||
src/emu/state.h svneol=native#text/plain
|
src/emu/state.h svneol=native#text/plain
|
||||||
src/emu/tilemap.c svneol=native#text/plain
|
src/emu/tilemap.c svneol=native#text/plain
|
||||||
|
269
src/emu/speaker.c
Normal file
269
src/emu/speaker.c
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
speaker.c
|
||||||
|
|
||||||
|
Speaker output sound device.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
Copyright Aaron Giles
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name 'MAME' nor the names of its contributors may be
|
||||||
|
used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
#include "emuopts.h"
|
||||||
|
#include "osdepend.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "profiler.h"
|
||||||
|
#include "sound/wavwrite.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
DEBUGGING
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#define VERBOSE (0)
|
||||||
|
|
||||||
|
#define VPRINTF(x) do { if (VERBOSE) mame_printf_debug x; } while (0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
DEVICE DEFINITIONS
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
const device_type SPEAKER = speaker_device_config::static_alloc_device_config;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// SPEAKER DEVICE CONFIGURATION
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// speaker_device_config - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
speaker_device_config::speaker_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
|
||||||
|
: device_config(mconfig, static_alloc_device_config, "Speaker", tag, owner, clock),
|
||||||
|
device_config_sound_interface(mconfig, *this),
|
||||||
|
m_x(0.0),
|
||||||
|
m_y(0.0),
|
||||||
|
m_z(0.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// static_alloc_device_config - allocate a new
|
||||||
|
// configuration object
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
device_config *speaker_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
|
||||||
|
{
|
||||||
|
return global_alloc(speaker_device_config(mconfig, tag, owner, clock));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// alloc_device - allocate a new device object
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
device_t *speaker_device_config::alloc_device(running_machine &machine) const
|
||||||
|
{
|
||||||
|
return auto_alloc(&machine, speaker_device(machine, *this));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// static_set_position - configuration helper to
|
||||||
|
// set the speaker position
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void speaker_device_config::static_set_position(device_config *device, double x, double y, double z)
|
||||||
|
{
|
||||||
|
speaker_device_config *speaker = downcast<speaker_device_config *>(device);
|
||||||
|
speaker->m_x = x;
|
||||||
|
speaker->m_y = y;
|
||||||
|
speaker->m_z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// LIVE SPEAKER DEVICE
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// speaker_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
speaker_device::speaker_device(running_machine &_machine, const speaker_device_config &config)
|
||||||
|
: device_t(_machine, config),
|
||||||
|
device_sound_interface(_machine, config, *this),
|
||||||
|
m_config(config),
|
||||||
|
m_mixer_stream(NULL)
|
||||||
|
#ifdef MAME_DEBUG
|
||||||
|
,
|
||||||
|
m_max_sample(0),
|
||||||
|
m_clipped_samples(0),
|
||||||
|
m_total_samples(0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// ~speaker_device - destructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
speaker_device::~speaker_device()
|
||||||
|
{
|
||||||
|
#ifdef MAME_DEBUG
|
||||||
|
// log the maximum sample values for all speakers
|
||||||
|
if (m_max_sample > 0)
|
||||||
|
mame_printf_debug("Speaker \"%s\" - max = %d (gain *= %f) - %d%% samples clipped\n", tag(), m_max_sample, 32767.0 / (m_max_sample ? m_max_sample : 1), (int)((double)m_clipped_samples * 100.0 / m_total_samples));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// 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 = m_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(m_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
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void speaker_device::mix(INT32 *leftmix, INT32 *rightmix, int &samples_this_update, bool suppress)
|
||||||
|
{
|
||||||
|
// skip if no stream
|
||||||
|
if (m_mixer_stream == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// update the stream, getting the start/end pointers around the operation
|
||||||
|
int numsamples;
|
||||||
|
const stream_sample_t *stream_buf = m_mixer_stream->output_since_last_update(0, numsamples);
|
||||||
|
|
||||||
|
// set or assert that all streams have the same count
|
||||||
|
if (samples_this_update == 0)
|
||||||
|
{
|
||||||
|
samples_this_update = numsamples;
|
||||||
|
|
||||||
|
// reset the mixing streams
|
||||||
|
memset(leftmix, 0, samples_this_update * sizeof(*leftmix));
|
||||||
|
memset(rightmix, 0, samples_this_update * sizeof(*rightmix));
|
||||||
|
}
|
||||||
|
assert(samples_this_update == numsamples);
|
||||||
|
|
||||||
|
#ifdef MAME_DEBUG
|
||||||
|
// debug version: keep track of the maximum sample
|
||||||
|
for (int sample = 0; sample < samples_this_update; sample++)
|
||||||
|
{
|
||||||
|
if (stream_buf[sample] > m_max_sample)
|
||||||
|
m_max_sample = stream_buf[sample];
|
||||||
|
else if (-stream_buf[sample] > m_max_sample)
|
||||||
|
m_max_sample = -stream_buf[sample];
|
||||||
|
if (stream_buf[sample] > 32767 || stream_buf[sample] < -32768)
|
||||||
|
m_clipped_samples++;
|
||||||
|
m_total_samples++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// mix if sound is enabled
|
||||||
|
if (!suppress)
|
||||||
|
{
|
||||||
|
// if the speaker is centered, send to both left and right
|
||||||
|
if (m_config.m_x == 0)
|
||||||
|
for (int sample = 0; sample < samples_this_update; sample++)
|
||||||
|
{
|
||||||
|
leftmix[sample] += stream_buf[sample];
|
||||||
|
rightmix[sample] += stream_buf[sample];
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the speaker is to the left, send only to the left
|
||||||
|
else if (m_config.m_x < 0)
|
||||||
|
for (int sample = 0; sample < samples_this_update; sample++)
|
||||||
|
leftmix[sample] += stream_buf[sample];
|
||||||
|
|
||||||
|
// if the speaker is to the right, send only to the right
|
||||||
|
else
|
||||||
|
for (int sample = 0; sample < samples_this_update; sample++)
|
||||||
|
rightmix[sample] += stream_buf[sample];
|
||||||
|
}
|
||||||
|
}
|
187
src/emu/speaker.h
Normal file
187
src/emu/speaker.h
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
speaker.h
|
||||||
|
|
||||||
|
Speaker output sound device.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
Copyright Aaron Giles
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name 'MAME' nor the names of its contributors may be
|
||||||
|
used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef __EMU_H__
|
||||||
|
#error Dont include this file directly; include emu.h instead.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __SPEAKER_H__
|
||||||
|
#define __SPEAKER_H__
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// DEVICE CONFIGURATION MACROS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
// add/remove speakers
|
||||||
|
#define MCFG_SPEAKER_ADD(_tag, _x, _y, _z) \
|
||||||
|
MCFG_DEVICE_ADD(_tag, SPEAKER, 0) \
|
||||||
|
speaker_device_config::static_set_position(device, _x, _y, _z); \
|
||||||
|
|
||||||
|
#define MCFG_SPEAKER_STANDARD_MONO(_tag) \
|
||||||
|
MCFG_SPEAKER_ADD(_tag, 0.0, 0.0, 1.0)
|
||||||
|
|
||||||
|
#define MCFG_SPEAKER_STANDARD_STEREO(_tagl, _tagr) \
|
||||||
|
MCFG_SPEAKER_ADD(_tagl, -0.2, 0.0, 1.0) \
|
||||||
|
MCFG_SPEAKER_ADD(_tagr, 0.2, 0.0, 1.0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// TYPE DEFINITIONS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
// ======================> speaker_device_config
|
||||||
|
|
||||||
|
class speaker_device_config : public device_config,
|
||||||
|
public device_config_sound_interface
|
||||||
|
{
|
||||||
|
friend class speaker_device;
|
||||||
|
|
||||||
|
// construction/destruction
|
||||||
|
speaker_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// allocators
|
||||||
|
static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
|
||||||
|
virtual device_t *alloc_device(running_machine &machine) const;
|
||||||
|
|
||||||
|
// inline configuration helpers
|
||||||
|
static void static_set_position(device_config *device, double x, double y, double z);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// inline configuration state
|
||||||
|
double m_x;
|
||||||
|
double m_y;
|
||||||
|
double m_z;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> speaker_device
|
||||||
|
|
||||||
|
class speaker_device : public device_t,
|
||||||
|
public device_sound_interface
|
||||||
|
{
|
||||||
|
friend class speaker_device_config;
|
||||||
|
friend resource_pool_object<speaker_device>::~resource_pool_object();
|
||||||
|
|
||||||
|
// construction/destruction
|
||||||
|
speaker_device(running_machine &_machine, const speaker_device_config &config);
|
||||||
|
virtual ~speaker_device();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// internally for use by the sound system
|
||||||
|
void mix(INT32 *leftmix, INT32 *rightmix, int &samples_this_update, bool suppress);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// internal state
|
||||||
|
const speaker_device_config &m_config;
|
||||||
|
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
|
||||||
|
INT32 m_total_samples; // total number of samples
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
extern const device_type SPEAKER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// INLINE HELPERS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// speaker_first - return the first speaker
|
||||||
|
// device config in a machine_config
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
inline const speaker_device_config *speaker_first(const machine_config &config)
|
||||||
|
{
|
||||||
|
return downcast<speaker_device_config *>(config.m_devicelist.first(SPEAKER));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// speaker_next - return the next speaker
|
||||||
|
// device config in a machine_config
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
inline const speaker_device_config *speaker_next(const speaker_device_config *previous)
|
||||||
|
{
|
||||||
|
return downcast<speaker_device_config *>(previous->typenext());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// speaker_first - return the first speaker
|
||||||
|
// device in a machine
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
inline speaker_device *speaker_first(running_machine &machine)
|
||||||
|
{
|
||||||
|
return downcast<speaker_device *>(machine.m_devicelist.first(SPEAKER));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// speaker_next - return the next speaker
|
||||||
|
// device in a machine
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
inline speaker_device *speaker_next(speaker_device *previous)
|
||||||
|
{
|
||||||
|
return downcast<speaker_device *>(previous->typenext());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __SOUND_H__ */
|
Loading…
Reference in New Issue
Block a user