diff options
Diffstat (limited to 'src/devices/sound/namco.cpp')
-rw-r--r-- | src/devices/sound/namco.cpp | 504 |
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); } |