summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/namco.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/namco.cpp')
-rw-r--r--src/devices/sound/namco.cpp504
1 files changed, 253 insertions, 251 deletions
diff --git a/src/devices/sound/namco.cpp b/src/devices/sound/namco.cpp
index a8a0d3b9259..688f1ce98ec 100644
--- a/src/devices/sound/namco.cpp
+++ b/src/devices/sound/namco.cpp
@@ -5,11 +5,10 @@
NAMCO sound driver.
This driver handles the four known types of NAMCO wavetable sounds:
-
- - 3-voice mono (PROM-based design: Pac-Man, Pengo, Dig Dug, etc)
- - 8-voice quadrophonic (Pole Position 1, Pole Position 2)
- - 8-voice mono (custom 15XX: Mappy, Dig Dug 2, etc)
- - 8-voice stereo (System 1)
+ - 3-voice mono (PROM-based design: Pac-Man, Pengo, Dig Dug, etc)
+ - 8-voice quadrophonic (Pole Position 1, Pole Position 2)
+ - 8-voice mono (custom 15XX: Mappy, Dig Dug 2, etc)
+ - 8-voice stereo (System 1)
The 15XX custom does not have a DAC of its own; instead, it streams
the 4-bit PROM data directly into the 99XX custom DAC. Most pre-99XX
@@ -23,24 +22,26 @@
CUS30 also uses the 99XX DAC, or two 99XX in the optional 16-channel
stereo configuration, but it uses no PROM and delivers its own samples.
+ The CUS30 has been decapped and verified to be a ULA.
+
***************************************************************************/
#include "emu.h"
#include "namco.h"
-/* quality parameter: internal sample rate is 192 KHz, output is 48 KHz */
+// quality parameter: internal sample rate is 192 KHz, output is 48 KHz
#define INTERNAL_RATE 192000
-/* 16 bits: sample bits of the stream buffer */
-/* 4 bits: volume */
-/* 4 bits: prom sample bits */
+// 16 bits: sample bits of the stream buffer
+// 4 bits: volume
+// 4 bits: prom sample bits
#define MIXLEVEL (1 << (16 - 4 - 4))
-/* stream output level */
+// stream output level
#define OUTPUT_LEVEL(n) ((n) * MIXLEVEL / m_voices)
-/* a position of waveform sample */
+// a position of waveform sample
#define WAVEFORM_POSITION(n) (((n) >> m_f_fracbits) & 0x1f)
DEFINE_DEVICE_TYPE(NAMCO, namco_device, "namco", "Namco")
@@ -52,7 +53,6 @@ namco_audio_device::namco_audio_device(const machine_config &mconfig, device_typ
, device_sound_interface(mconfig, *this)
, m_wave_ptr(*this, DEVICE_SELF)
, m_last_channel(nullptr)
- , m_soundregs(nullptr)
, m_wavedata(nullptr)
, m_wave_size(0)
, m_sound_enable(false)
@@ -67,11 +67,13 @@ namco_audio_device::namco_audio_device(const machine_config &mconfig, device_typ
namco_device::namco_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: namco_audio_device(mconfig, NAMCO, tag, owner, clock)
+ , m_soundregs(nullptr)
{
}
namco_15xx_device::namco_15xx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- :namco_audio_device(mconfig, NAMCO_15XX, tag, owner, clock)
+ : namco_audio_device(mconfig, NAMCO_15XX, tag, owner, clock)
+ , m_soundregs(nullptr)
{
}
@@ -87,40 +89,32 @@ namco_cus30_device::namco_cus30_device(const machine_config &mconfig, const char
void namco_audio_device::device_start()
{
- sound_channel *voice;
-
- /* extract globals from the interface */
+ // extract globals from the interface
m_last_channel = m_channel_list + m_voices;
- m_soundregs = auto_alloc_array_clear(machine(), uint8_t, 0x400);
-
- /* build the waveform table */
+ // build the waveform table
build_decoded_waveform(m_wave_ptr);
- /* get stream channels */
+ // get stream channels
if (m_stereo)
- m_stream = machine().sound().stream_alloc(*this, 0, 2, 192000);
+ m_stream = stream_alloc(0, 2, 192000);
else
- m_stream = machine().sound().stream_alloc(*this, 0, 1, 192000);
+ m_stream = stream_alloc(0, 1, 192000);
- /* start with sound enabled, many games don't have a sound enable register */
+ // start with sound enabled, many games don't have a sound enable register
m_sound_enable = true;
- /* register with the save state system */
- save_pointer(NAME(m_soundregs), 0x400);
-
+ // register with the save state system
if (m_wave_ptr == nullptr)
save_pointer(NAME(m_wavedata), 0x400);
- save_item(NAME(m_voices));
save_item(NAME(m_sound_enable));
- save_pointer(NAME(m_waveform[0]), MAX_VOLUME * 32 * 8 * (1+m_wave_size));
+ for (int v = 0; v < MAX_VOLUME; v++)
+ save_pointer(NAME(m_waveform[v]), 32 * 8 * (1+m_wave_size), v);
- /* reset all the voices */
- for (voice = m_channel_list; voice < m_last_channel; voice++)
+ // reset all the voices
+ for (sound_channel *voice = m_channel_list; voice < m_last_channel; voice++)
{
- int voicenum = voice - m_channel_list;
-
voice->frequency = 0;
voice->volume[0] = voice->volume[1] = 0;
voice->waveform_select = 0;
@@ -130,18 +124,36 @@ void namco_audio_device::device_start()
voice->noise_seed = 1;
voice->noise_counter = 0;
voice->noise_hold = 0;
-
- /* register with the save state system */
- save_item(NAME(voice->frequency), voicenum);
- save_item(NAME(voice->counter), voicenum);
- save_item(NAME(voice->volume), voicenum);
- save_item(NAME(voice->noise_sw), voicenum);
- save_item(NAME(voice->noise_state), voicenum);
- save_item(NAME(voice->noise_seed), voicenum);
- save_item(NAME(voice->noise_hold), voicenum);
- save_item(NAME(voice->noise_counter), voicenum);
- save_item(NAME(voice->waveform_select), voicenum);
}
+
+ // register with the save state system
+ save_pointer(STRUCT_MEMBER(m_channel_list, frequency), m_voices);
+ save_pointer(STRUCT_MEMBER(m_channel_list, counter), m_voices);
+ save_pointer(STRUCT_MEMBER(m_channel_list, volume), m_voices);
+ save_pointer(STRUCT_MEMBER(m_channel_list, noise_sw), m_voices);
+ save_pointer(STRUCT_MEMBER(m_channel_list, noise_state), m_voices);
+ save_pointer(STRUCT_MEMBER(m_channel_list, noise_seed), m_voices);
+ save_pointer(STRUCT_MEMBER(m_channel_list, noise_hold), m_voices);
+ save_pointer(STRUCT_MEMBER(m_channel_list, noise_counter), m_voices);
+ save_pointer(STRUCT_MEMBER(m_channel_list, waveform_select), m_voices);
+}
+
+
+void namco_device::device_start()
+{
+ namco_audio_device::device_start();
+
+ m_soundregs = make_unique_clear<uint8_t[]>(0x400);
+ save_pointer(NAME(m_soundregs), 0x400);
+}
+
+
+void namco_15xx_device::device_start()
+{
+ namco_audio_device::device_start();
+
+ m_soundregs = make_unique_clear<uint8_t[]>(0x400);
+ save_pointer(NAME(m_soundregs), 0x400);
}
@@ -149,14 +161,14 @@ void namco_audio_device::device_clock_changed()
{
int clock_multiple;
- /* adjust internal clock */
+ // adjust internal clock
m_namco_clock = clock();
for (clock_multiple = 0; m_namco_clock < INTERNAL_RATE; clock_multiple++)
m_namco_clock *= 2;
m_f_fracbits = clock_multiple + 15;
- /* adjust output clock */
+ // adjust output clock
m_sample_rate = m_namco_clock;
logerror("Namco: freq fractional bits = %d: internal freq = %d, output freq = %d\n", m_f_fracbits, m_namco_clock, m_sample_rate);
@@ -165,18 +177,15 @@ void namco_audio_device::device_clock_changed()
}
-/* update the decoded waveform data */
+// update the decoded waveform data
void namco_audio_device::update_namco_waveform(int offset, uint8_t data)
{
if (m_wave_size == 1)
{
- int16_t wdata;
- int v;
-
- /* use full byte, first 4 high bits, then low 4 bits */
- for (v = 0; v < MAX_VOLUME; v++)
+ // use full byte, first 4 high bits, then low 4 bits
+ for (int v = 0; v < MAX_VOLUME; v++)
{
- wdata = ((data >> 4) & 0x0f) - 8;
+ int16_t wdata = ((data >> 4) & 0x0f) - 8;
m_waveform[v][offset * 2] = OUTPUT_LEVEL(wdata * v);
wdata = (data & 0x0f) - 8;
m_waveform[v][offset * 2 + 1] = OUTPUT_LEVEL(wdata * v);
@@ -184,60 +193,51 @@ void namco_audio_device::update_namco_waveform(int offset, uint8_t data)
}
else
{
- int v;
-
- /* use only low 4 bits */
- for (v = 0; v < MAX_VOLUME; v++)
+ // use only low 4 bits
+ for (int v = 0; v < MAX_VOLUME; v++)
m_waveform[v][offset] = OUTPUT_LEVEL(((data & 0x0f) - 8) * v);
}
}
-/* build the decoded waveform table */
+// build the decoded waveform table
void namco_audio_device::build_decoded_waveform(uint8_t *rgnbase)
{
- int16_t *p;
- int size;
- int offset;
- int v;
-
- m_wavedata = (rgnbase != nullptr) ? rgnbase : auto_alloc_array_clear(machine(), uint8_t, 0x400);
+ if (rgnbase != nullptr)
+ m_wavedata = rgnbase;
+ else
+ {
+ m_waveram_alloc = make_unique_clear<uint8_t[]>(0x400);
+ m_wavedata = m_waveram_alloc.get();
+ }
- /* 20pacgal has waves in RAM but old sound system */
+ // 20pacgal has waves in RAM but old sound system
+ int size;
if (rgnbase == nullptr && m_voices != 3)
{
m_wave_size = 1;
- size = 32 * 16; /* 32 samples, 16 waveforms */
+ size = 32 * 16; // 32 samples, 16 waveforms
}
else
{
m_wave_size = 0;
- size = 32 * 8; /* 32 samples, 8 waveforms */
+ size = 32 * 8; // 32 samples, 8 waveforms
}
- p = auto_alloc_array(machine(), int16_t, size * MAX_VOLUME);
-
- for (v = 0; v < MAX_VOLUME; v++)
- {
- m_waveform[v] = p;
- p += size;
- }
+ for (int v = 0; v < MAX_VOLUME; v++)
+ m_waveform[v] = std::make_unique<int16_t[]>(size);
- /* We need waveform data. It fails if region is not specified. */
- if (m_wavedata)
- {
- for (offset = 0; offset < 256; offset++)
- update_namco_waveform(offset, m_wavedata[offset]);
- }
+ for (int offset = 0; offset < 256; offset++)
+ update_namco_waveform(offset, m_wavedata[offset]);
}
-/* generate sound by oversampling */
-uint32_t namco_audio_device::namco_update_one(stream_sample_t *buffer, int length, const int16_t *wave, uint32_t counter, uint32_t freq)
+// generate sound by oversampling
+uint32_t namco_audio_device::namco_update_one(sound_stream &stream, int output, const int16_t *wave, uint32_t counter, uint32_t freq)
{
- while (length-- > 0)
+ for (int sampindex = 0; sampindex < stream.samples(); sampindex++)
{
- *buffer++ += wave[WAVEFORM_POSITION(counter)];
+ stream.add_int(output, sampindex, wave[WAVEFORM_POSITION(counter)], 32768);
counter += freq;
}
@@ -245,7 +245,7 @@ uint32_t namco_audio_device::namco_update_one(stream_sample_t *buffer, int lengt
}
-WRITE_LINE_MEMBER(namco_audio_device::sound_enable_w)
+void namco_audio_device::sound_enable_w(int state)
{
m_sound_enable = state;
}
@@ -269,7 +269,7 @@ WRITE_LINE_MEMBER(namco_audio_device::sound_enable_w)
0x1f: ch 2 volume
*/
-WRITE8_MEMBER( namco_device::pacman_sound_w )
+void namco_device::pacman_sound_w(offs_t offset, uint8_t data)
{
sound_channel *voice;
int ch;
@@ -278,10 +278,10 @@ WRITE8_MEMBER( namco_device::pacman_sound_w )
if (m_soundregs[offset] == data)
return;
- /* update the streams */
+ // update the streams
m_stream->update();
- /* set the register */
+ // set the register
m_soundregs[offset] = data;
if (offset < 0x10)
@@ -294,7 +294,7 @@ WRITE8_MEMBER( namco_device::pacman_sound_w )
if (ch >= m_voices)
return;
- /* recompute the voice parameters */
+ // recompute the voice parameters
voice = m_channel_list + ch;
switch (offset - ch * 5)
{
@@ -307,13 +307,13 @@ WRITE8_MEMBER( namco_device::pacman_sound_w )
case 0x12:
case 0x13:
case 0x14:
- /* the frequency has 20 bits */
- /* the first voice has extra frequency bits */
+ // the frequency has 20 bits
+ // the first voice has extra frequency bits
voice->frequency = (ch == 0) ? m_soundregs[0x10] : 0;
voice->frequency += (m_soundregs[ch * 5 + 0x11] << 4);
voice->frequency += (m_soundregs[ch * 5 + 0x12] << 8);
voice->frequency += (m_soundregs[ch * 5 + 0x13] << 12);
- voice->frequency += (m_soundregs[ch * 5 + 0x14] << 16); /* always 0 */
+ voice->frequency += (m_soundregs[ch * 5 + 0x14] << 16); // always 0
break;
case 0x15:
@@ -322,20 +322,22 @@ WRITE8_MEMBER( namco_device::pacman_sound_w )
}
}
-WRITE8_MEMBER( namco_cus30_device::pacman_sound_w )
+void namco_cus30_device::pacman_sound_w(offs_t offset, uint8_t data)
{
sound_channel *voice;
int ch;
+ uint8_t *soundregs = &m_wavedata[0x100];
+
data &= 0x0f;
- if (m_soundregs[offset] == data)
+ if (soundregs[offset] == data)
return;
- /* update the streams */
+ // update the streams
m_stream->update();
- /* set the register */
- m_soundregs[offset] = data;
+ // set the register
+ soundregs[offset] = data;
if (offset < 0x10)
ch = (offset - 5) / 5;
@@ -347,7 +349,7 @@ WRITE8_MEMBER( namco_cus30_device::pacman_sound_w )
if (ch >= m_voices)
return;
- /* recompute the voice parameters */
+ // recompute the voice parameters
voice = m_channel_list + ch;
switch (offset - ch * 5)
{
@@ -360,13 +362,13 @@ WRITE8_MEMBER( namco_cus30_device::pacman_sound_w )
case 0x12:
case 0x13:
case 0x14:
- /* the frequency has 20 bits */
- /* the first voice has extra frequency bits */
- voice->frequency = (ch == 0) ? m_soundregs[0x10] : 0;
- voice->frequency += (m_soundregs[ch * 5 + 0x11] << 4);
- voice->frequency += (m_soundregs[ch * 5 + 0x12] << 8);
- voice->frequency += (m_soundregs[ch * 5 + 0x13] << 12);
- voice->frequency += (m_soundregs[ch * 5 + 0x14] << 16); /* always 0 */
+ // the frequency has 20 bits
+ // the first voice has extra frequency bits
+ voice->frequency = (ch == 0) ? soundregs[0x10] : 0;
+ voice->frequency += (soundregs[ch * 5 + 0x11] << 4);
+ voice->frequency += (soundregs[ch * 5 + 0x12] << 8);
+ voice->frequency += (soundregs[ch * 5 + 0x13] << 12);
+ voice->frequency += (soundregs[ch * 5 + 0x14] << 16); // always 0
break;
case 0x15:
@@ -411,12 +413,12 @@ it select the 54XX/52XX outputs on those channels
0x3f ch 7
*/
-READ8_MEMBER( namco_device::polepos_sound_r )
+uint8_t namco_device::polepos_sound_r(offs_t offset)
{
return m_soundregs[offset];
}
-WRITE8_MEMBER( namco_device::polepos_sound_w )
+void namco_device::polepos_sound_w(offs_t offset, uint8_t data)
{
sound_channel *voice;
int ch;
@@ -424,28 +426,28 @@ WRITE8_MEMBER( namco_device::polepos_sound_w )
if (m_soundregs[offset] == data)
return;
- /* update the streams */
+ // update the streams
m_stream->update();
- /* set the register */
+ // set the register
m_soundregs[offset] = data;
ch = (offset & 0x1f) / 4;
- /* recompute the voice parameters */
+ // recompute the voice parameters
voice = m_channel_list + ch;
switch (offset & 0x23)
{
case 0x00:
case 0x01:
- /* the frequency has 16 bits */
+ // the frequency has 16 bits
voice->frequency = m_soundregs[ch * 4 + 0x00];
voice->frequency += m_soundregs[ch * 4 + 0x01] << 8;
break;
case 0x23:
voice->waveform_select = data & 7;
- /* fall through */
+ [[fallthrough]];
case 0x02:
case 0x03:
voice->volume[0] = voice->volume[1] = 0;
@@ -459,7 +461,7 @@ WRITE8_MEMBER( namco_device::polepos_sound_w )
voice->volume[0] /= 2;
voice->volume[1] /= 2;
- /* if 54XX or 52XX selected, silence this voice */
+ // if 54XX or 52XX selected, silence this voice
if (m_soundregs[ch * 4 + 0x23] & 8)
voice->volume[0] = voice->volume[1] = 0;
break;
@@ -485,9 +487,14 @@ WRITE8_MEMBER( namco_device::polepos_sound_w )
0x3b ch 7 volume
0x3c-0x3d ch 7 frequency
0x3e ch 7 waveform select & frequency
+
+Grobda also stuffs values into register offset 0x02 with a frequency of zero
+to make 15XX channels act like a 4-bit DAC instead of waveform voices. This
+has been emulated by allowing writes to set the upper counter bits directly.
+Possibly offsets 0x00 and 0x01 can be used to set the fractional bits.
*/
-WRITE8_MEMBER(namco_15xx_device::namco_15xx_w)
+void namco_15xx_device::namco_15xx_w(offs_t offset, uint8_t data)
{
sound_channel *voice;
int ch;
@@ -495,32 +502,38 @@ WRITE8_MEMBER(namco_15xx_device::namco_15xx_w)
if (m_soundregs[offset] == data)
return;
- /* update the streams */
+ // update the streams
m_stream->update();
- /* set the register */
+ // set the register
m_soundregs[offset] = data;
ch = offset / 8;
if (ch >= m_voices)
return;
- /* recompute the voice parameters */
+ // recompute the voice parameters
voice = m_channel_list + ch;
- switch (offset - ch * 8)
+ switch (offset & 7)
{
+ case 0x02:
+ voice->counter &= util::make_bitmask<uint32_t>(m_f_fracbits);
+ voice->counter |= uint32_t(data & 0x1f) << m_f_fracbits;
+ break;
+
case 0x03:
voice->volume[0] = data & 0x0f;
break;
case 0x06:
voice->waveform_select = (data >> 4) & 7;
+ [[fallthrough]];
case 0x04:
case 0x05:
- /* the frequency has 20 bits */
+ // the frequency has 20 bits
voice->frequency = m_soundregs[ch * 8 + 0x04];
voice->frequency += m_soundregs[ch * 8 + 0x05] << 8;
- voice->frequency += (m_soundregs[ch * 8 + 0x06] & 15) << 16; /* high bits are from here */
+ voice->frequency += (m_soundregs[ch * 8 + 0x06] & 15) << 16; // high bits are from here
break;
}
}
@@ -552,38 +565,35 @@ WRITE8_MEMBER(namco_15xx_device::namco_15xx_w)
0x3c ch 0 noise sw
*/
- WRITE8_MEMBER(namco_cus30_device::namcos1_sound_w)
+void namco_cus30_device::namcos1_sound_w(offs_t offset, uint8_t data)
{
sound_channel *voice;
- int ch;
- int nssw;
-
- /* verify the offset */
+ // verify the offset
if (offset > 63)
{
logerror("NAMCOS1 sound: Attempting to write past the 64 registers segment\n");
return;
}
- m_soundregs = m_wavedata + 0x100;
+ uint8_t *soundregs = &m_wavedata[0x100];
- if (m_soundregs[offset] == data)
+ if (soundregs[offset] == data)
return;
- /* update the streams */
+ // update the streams
m_stream->update();
- /* set the register */
- m_soundregs[offset] = data;
+ // set the register
+ soundregs[offset] = data;
- ch = offset / 8;
+ int ch = offset / 8;
if (ch >= m_voices)
return;
- /* recompute the voice parameters */
+ // recompute the voice parameters
voice = m_channel_list + ch;
- switch (offset - ch * 8)
+ switch (offset & 7)
{
case 0x00:
voice->volume[0] = data & 0x0f;
@@ -591,18 +601,19 @@ WRITE8_MEMBER(namco_15xx_device::namco_15xx_w)
case 0x01:
voice->waveform_select = (data >> 4) & 15;
+ [[fallthrough]];
case 0x02:
case 0x03:
- /* the frequency has 20 bits */
- voice->frequency = (m_soundregs[ch * 8 + 0x01] & 15) << 16; /* high bits are from here */
- voice->frequency += m_soundregs[ch * 8 + 0x02] << 8;
- voice->frequency += m_soundregs[ch * 8 + 0x03];
+ // the frequency has 20 bits
+ voice->frequency = (soundregs[ch * 8 + 0x01] & 15) << 16; // high bits are from here
+ voice->frequency += soundregs[ch * 8 + 0x02] << 8;
+ voice->frequency += soundregs[ch * 8 + 0x03];
break;
case 0x04:
voice->volume[1] = data & 0x0f;
- nssw = ((data & 0x80) >> 7);
+ int nssw = ((data & 0x80) >> 7);
if (++voice == m_last_channel)
voice = m_channel_list;
voice->noise_sw = nssw;
@@ -610,41 +621,54 @@ WRITE8_MEMBER(namco_15xx_device::namco_15xx_w)
}
}
-WRITE8_MEMBER( namco_cus30_device::namcos1_cus30_w )
+void namco_cus30_device::namcos1_cus30_w(offs_t offset, uint8_t data)
{
if (offset < 0x100)
{
if (m_wavedata[offset] != data)
{
- /* update the streams */
+ // update the streams
m_stream->update();
m_wavedata[offset] = data;
- /* update the decoded waveform table */
+ // update the decoded waveform table
update_namco_waveform(offset, data);
}
}
else if (offset < 0x140)
- namcos1_sound_w(space, offset - 0x100,data);
+ namcos1_sound_w(offset - 0x100, data);
else
m_wavedata[offset] = data;
}
-READ8_MEMBER( namco_cus30_device::namcos1_cus30_r )
+uint8_t namco_cus30_device::namcos1_cus30_r(offs_t offset)
{
+ if (offset >= 0x100 && offset < 0x140)
+ {
+ int ch = (offset - 0x100) / 8;
+ int reg = offset & 7;
+
+ // reading from register 5 returns the counter (used by baraduke)
+ if (ch < m_voices && reg == 5)
+ {
+ m_stream->update();
+ return WAVEFORM_POSITION(m_channel_list[ch].counter);
+ }
+ }
+
return m_wavedata[offset];
}
-READ8_MEMBER( namco_15xx_device::sharedram_r )
+uint8_t namco_15xx_device::sharedram_r(offs_t offset)
{
return m_soundregs[offset];
}
-WRITE8_MEMBER( namco_15xx_device::sharedram_w )
+void namco_15xx_device::sharedram_w(offs_t offset, uint8_t data)
{
if (offset < 0x40)
- namco_15xx_w(space, offset, data);
+ namco_15xx_w(offset, data);
else
{
m_soundregs[offset] = data;
@@ -655,25 +679,17 @@ WRITE8_MEMBER( namco_15xx_device::sharedram_w )
// sound_stream_update - handle a stream update
//-------------------------------------------------
-void namco_audio_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
+void namco_audio_device::sound_stream_update(sound_stream &stream)
{
if (m_stereo)
{
- sound_channel *voice;
-
- /* zap the contents of the buffers */
- memset(outputs[0], 0, samples * sizeof(*outputs[0]));
- memset(outputs[1], 0, samples * sizeof(*outputs[1]));
-
- /* if no sound, we're done */
+ // if no sound, we're done
if (!m_sound_enable)
return;
- /* loop over each voice and add its contribution */
- for (voice = m_channel_list; voice < m_last_channel; voice++)
+ // loop over each voice and add its contribution
+ for (sound_channel *voice = m_channel_list; voice < m_last_channel; voice++)
{
- stream_sample_t *lmix = outputs[0];
- stream_sample_t *rmix = outputs[1];
int lv = voice->volume[0];
int rv = voice->volume[1];
@@ -681,8 +697,8 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, stream_sample
{
int f = voice->frequency & 0xff;
- /* only update if we have non-zero volume and frequency */
- if ((lv || rv) && f)
+ // only update if we have non-zero volume
+ if (lv || rv)
{
int hold_time = 1 << (m_f_fracbits - 16);
int hold = voice->noise_hold;
@@ -690,22 +706,19 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, stream_sample
uint32_t c = voice->noise_counter;
int16_t l_noise_data = OUTPUT_LEVEL(0x07 * (lv >> 1));
int16_t r_noise_data = OUTPUT_LEVEL(0x07 * (rv >> 1));
- int i;
- /* add our contribution */
- for (i = 0; i < samples; i++)
+ // add our contribution
+ for (int i = 0; i < stream.samples(); i++)
{
- int cnt;
-
if (voice->noise_state)
{
- *lmix++ += l_noise_data;
- *rmix++ += r_noise_data;
+ stream.add_int(0, i, l_noise_data, 32768);
+ stream.add_int(1, i, r_noise_data, 32768);
}
else
{
- *lmix++ -= l_noise_data;
- *rmix++ -= r_noise_data;
+ stream.add_int(0, i, -l_noise_data, 32768);
+ stream.add_int(1, i, -r_noise_data, 32768);
}
if (hold)
@@ -717,7 +730,7 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, stream_sample
hold = hold_time;
c += delta;
- cnt = (c >> 12);
+ int cnt = (c >> 12);
c &= (1 << 12) - 1;
for( ;cnt > 0; cnt--)
{
@@ -727,40 +740,36 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, stream_sample
}
}
- /* update the counter and hold time for this voice */
+ // update the counter and hold time for this voice
voice->noise_counter = c;
voice->noise_hold = hold;
}
}
else
{
- /* only update if we have non-zero frequency */
- if (voice->frequency)
- {
- /* save the counter for this voice */
- uint32_t c = voice->counter;
-
- /* only update if we have non-zero left volume */
- if (lv)
- {
- const int16_t *lw = &m_waveform[lv][voice->waveform_select * 32];
+ // save the counter for this voice
+ uint32_t c = voice->counter;
- /* generate sound into the buffer */
- c = namco_update_one(lmix, samples, lw, voice->counter, voice->frequency);
- }
+ // only update if we have non-zero left volume
+ if (lv)
+ {
+ const int16_t *lw = &m_waveform[lv][voice->waveform_select * 32];
- /* only update if we have non-zero right volume */
- if (rv)
- {
- const int16_t *rw = &m_waveform[rv][voice->waveform_select * 32];
+ // generate sound into the buffer
+ c = namco_update_one(stream, 0, lw, voice->counter, voice->frequency);
+ }
- /* generate sound into the buffer */
- c = namco_update_one(rmix, samples, rw, voice->counter, voice->frequency);
- }
+ // only update if we have non-zero right volume
+ if (rv)
+ {
+ const int16_t *rw = &m_waveform[rv][voice->waveform_select * 32];
- /* update the counter for this voice */
- voice->counter = c;
+ // generate sound into the buffer
+ c = namco_update_one(stream, 1, rw, voice->counter, voice->frequency);
}
+
+ // update the counter for this voice
+ voice->counter = c;
}
}
}
@@ -768,92 +777,85 @@ void namco_audio_device::sound_stream_update(sound_stream &stream, stream_sample
{
sound_channel *voice;
- stream_sample_t *buffer = outputs[0];
- /* zap the contents of the buffer */
- memset(buffer, 0, samples * sizeof(*buffer));
-
- /* if no sound, we're done */
+ // if no sound, we're done
if (!m_sound_enable)
return;
- /* loop over each voice and add its contribution */
+ // loop over each voice and add its contribution
for (voice = m_channel_list; voice < m_last_channel; voice++)
{
- stream_sample_t *mix = buffer;
int v = voice->volume[0];
- if (voice->noise_sw)
- {
+ if (voice->noise_sw)
+ {
int f = voice->frequency & 0xff;
- /* only update if we have non-zero volume and frequency */
- if (v && f)
+
+ // only update if we have non-zero volume
+ if (v)
{
- int hold_time = 1 << (m_f_fracbits - 16);
- int hold = voice->noise_hold;
- uint32_t delta = f << 4;
- uint32_t c = voice->noise_counter;
- int16_t noise_data = OUTPUT_LEVEL(0x07 * (v >> 1));
- int i;
-
- /* add our contribution */
- for (i = 0; i < samples; i++)
+ int hold_time = 1 << (m_f_fracbits - 16);
+ int hold = voice->noise_hold;
+ uint32_t delta = f << 4;
+ uint32_t c = voice->noise_counter;
+ int16_t noise_data = OUTPUT_LEVEL(0x07 * (v >> 1));
+
+ // add our contribution
+ for (int i = 0; i < stream.samples(); i++)
+ {
+ if (voice->noise_state)
+ stream.add_int(0, i, noise_data, 32768);
+ else
+ stream.add_int(1, i, -noise_data, 32768);
+
+ if (hold)
{
- int cnt;
-
- if (voice->noise_state)
- *mix++ += noise_data;
- else
- *mix++ -= noise_data;
-
- if (hold)
- {
- hold--;
- continue;
- }
-
- hold = hold_time;
-
- c += delta;
- cnt = (c >> 12);
- c &= (1 << 12) - 1;
- for( ;cnt > 0; cnt--)
- {
- if ((voice->noise_seed + 1) & 2) voice->noise_state ^= 1;
- if (voice->noise_seed & 1) voice->noise_seed ^= 0x28000;
- voice->noise_seed >>= 1;
- }
+ hold--;
+ continue;
}
- /* update the counter and hold time for this voice */
- voice->noise_counter = c;
- voice->noise_hold = hold;
+ hold = hold_time;
+
+ c += delta;
+ int cnt = (c >> 12);
+ c &= (1 << 12) - 1;
+ for( ;cnt > 0; cnt--)
+ {
+ if ((voice->noise_seed + 1) & 2) voice->noise_state ^= 1;
+ if (voice->noise_seed & 1) voice->noise_seed ^= 0x28000;
+ voice->noise_seed >>= 1;
+ }
}
+
+ // update the counter and hold time for this voice
+ voice->noise_counter = c;
+ voice->noise_hold = hold;
}
- else
- {
- /* only update if we have non-zero volume and frequency */
- if (v && voice->frequency)
+ }
+ else
+ {
+ // only update if we have non-zero volume
+ if (v)
{
const int16_t *w = &m_waveform[v][voice->waveform_select * 32];
- /* generate sound into buffer and update the counter for this voice */
- voice->counter = namco_update_one(mix, samples, w, voice->counter, voice->frequency);
+ // generate sound into buffer and update the counter for this voice
+ voice->counter = namco_update_one(stream, 0, w, voice->counter, voice->frequency);
}
}
}
}
}
-void namco_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
+void namco_device::sound_stream_update(sound_stream &stream)
{
- namco_audio_device::sound_stream_update(stream, inputs, outputs, samples);
+ namco_audio_device::sound_stream_update(stream);
}
-void namco_15xx_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
+void namco_15xx_device::sound_stream_update(sound_stream &stream)
{
- namco_audio_device::sound_stream_update(stream, inputs, outputs, samples);
+ namco_audio_device::sound_stream_update(stream);
}
-void namco_cus30_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
+void namco_cus30_device::sound_stream_update(sound_stream &stream)
{
- namco_audio_device::sound_stream_update(stream, inputs, outputs, samples);
+ namco_audio_device::sound_stream_update(stream);
}