From 71fe25f95be7030fbeb26dad6067a06b2fe38f59 Mon Sep 17 00:00:00 2001 From: hap Date: Mon, 6 Jan 2025 18:30:26 +0100 Subject: [PATCH] zsg2: update stream before reading, tms57002: fix input sample overflow --- src/devices/cpu/tms57002/tms57002.cpp | 2 +- src/devices/sound/zsg2.cpp | 178 +++++++++++++------------- src/devices/sound/zsg2.h | 5 +- 3 files changed, 93 insertions(+), 92 deletions(-) diff --git a/src/devices/cpu/tms57002/tms57002.cpp b/src/devices/cpu/tms57002/tms57002.cpp index 4adeed1cf85..593a74e3263 100644 --- a/src/devices/cpu/tms57002/tms57002.cpp +++ b/src/devices/cpu/tms57002/tms57002.cpp @@ -925,7 +925,7 @@ void tms57002_device::sound_stream_update(sound_stream &stream, std::vector>16; + sample += ((uint16_t)(elem.step_ptr << 2 & 0xffff) * (int16_t)(elem.samples[sample_pos+1] - sample)) >> 16; // another filter... - elem.output_filter_state += (sample - (elem.output_filter_state>>16)) * elem.output_cutoff; + elem.output_filter_state += (sample - (elem.output_filter_state >> 16)) * elem.output_cutoff; sample = elem.output_filter_state >> 16; // To prevent DC bias, we need to slowly discharge the filter when the output filter cutoff is 0 - if(!elem.output_cutoff) + if (!elem.output_cutoff) elem.output_filter_state >>= 1; - sample = (sample * elem.vol)>>16; + sample = (sample * elem.vol) >> 16; - for(int output=0; output<4; output++) + for (int output = 0; output < 4; output++) { int output_gain = elem.output_gain[output] & 0x1f; // left / right int32_t output_sample = sample; @@ -340,19 +342,19 @@ void zsg2_device::sound_stream_update(sound_stream &stream, std::vector> 16; + mix[output] += (output_sample * m_gain_tab[output_gain & 0x1f]) >> 16; } // Apply ramping every other update // It's possible key on is handled on the other sample - if(m_sample_count & 1) + if (m_sample_count & 1) { elem.vol = ramp(elem.vol, elem.vol_target, elem.vol_delta); elem.output_cutoff = ramp(elem.output_cutoff, elem.output_cutoff_target, elem.output_cutoff_delta); } } - for(int output=0; output<4; output++) + for (int output = 0; output < 4; output++) outputs[output].put_int_clamp(i, mix[output], 32768); } m_sample_count++; @@ -491,17 +493,17 @@ uint16_t zsg2_device::chan_r(int ch, int reg) // calculate this value, for now I'm generating an opproximate inverse. int16_t zsg2_device::get_ramp(uint8_t val) { - int16_t frac = val<<12; // sign extend - frac = ((frac>>12) ^ 8) << (val >> 4); + int16_t frac = val << 12; // sign extend + frac = ((frac >> 12) ^ 8) << (val >> 4); return (frac >> 4); } inline uint16_t zsg2_device::ramp(uint16_t current, uint16_t target, int16_t delta) { int32_t rampval = current + delta; - if(delta < 0 && rampval < target) + if (delta < 0 && rampval < target) rampval = target; - else if(delta >= 0 && rampval > target) + else if (delta >= 0 && rampval > target) rampval = target; return rampval; @@ -572,7 +574,7 @@ void zsg2_device::control_w(int reg, uint16_t data) break; default: - if(reg < 0x20) + if (reg < 0x20) m_reg[reg] = data; logerror("ZSG2 control %02X = %04X\n", reg, data & 0xffff); break; @@ -596,7 +598,7 @@ uint16_t zsg2_device::control_r(int reg) return read_memory(m_read_address) >> 16; default: - if(reg < 0x20) + if (reg < 0x20) return m_reg[reg]; break; } @@ -639,6 +641,8 @@ uint16_t zsg2_device::read(offs_t offset, uint16_t mem_mask) return 0; } + m_stream->update(); + if (offset < 0x300) { int chan = offset >> 4; diff --git a/src/devices/sound/zsg2.h b/src/devices/sound/zsg2.h index 6d4d1b7c081..91a06e27a2e 100644 --- a/src/devices/sound/zsg2.h +++ b/src/devices/sound/zsg2.h @@ -58,12 +58,9 @@ private: int16_t output_cutoff_delta; int32_t emphasis_filter_state; - int32_t output_filter_state; - // Attenuation for output channels - uint8_t output_gain[4]; - + uint8_t output_gain[4]; // Attenuation for output channels int16_t samples[5]; // +1 history };