diff options
Diffstat (limited to 'src/devices/sound/swp30.cpp')
-rw-r--r-- | src/devices/sound/swp30.cpp | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/src/devices/sound/swp30.cpp b/src/devices/sound/swp30.cpp index db37c8bff68..d135a77f16c 100644 --- a/src/devices/sound/swp30.cpp +++ b/src/devices/sound/swp30.cpp @@ -437,6 +437,8 @@ const std::array<u32, 4> swp30_device::lfo_shape_centered_tri = { 0x00000000, 0x const std::array<u32, 4> swp30_device::lfo_shape_offset_saw = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; // __////__ const std::array<u32, 4> swp30_device::lfo_shape_offset_tri = { 0x00000000, 0x00000000, 0x000fffff, 0x000fffff }; // __/\/\__ +const std::array<u8, 4> swp30_device::dpcm_offset = { 7, 6, 4, 0 }; + swp30_device::swp30_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : cpu_device(mconfig, SWP30, tag, owner, clock), device_sound_interface(mconfig, *this), @@ -478,7 +480,7 @@ void swp30_device::device_start() // Delta-packed samples decompression. for(int i=0; i<128; i++) { - s16 base = ((i & 0x1f) << (5+(i >> 5))) + (((1 << (i >> 5))-1) << 10); + s16 base = ((i & 0x1f) << (3+(i >> 5))) + (((1 << (i >> 5))-1) << 8); m_dpcm[i | 0x80] = - base; m_dpcm[i] = + base; } @@ -511,6 +513,7 @@ void swp30_device::device_start() save_item(NAME(m_dpcm_current)); save_item(NAME(m_dpcm_next)); save_item(NAME(m_dpcm_address)); + save_item(NAME(m_dpcm_sum)); save_item(NAME(m_sample_history)); @@ -568,6 +571,7 @@ void swp30_device::device_reset() std::fill(m_dpcm_current.begin(), m_dpcm_current.end(), false); std::fill(m_dpcm_next.begin(), m_dpcm_next.end(), false); std::fill(m_dpcm_address.begin(), m_dpcm_address.end(), false); + std::fill(m_dpcm_sum.begin(), m_dpcm_sum.end(), 0); std::fill(m_meg_program.begin(), m_meg_program.end(), 0); std::fill(m_meg_const.begin(), m_meg_const.end(), 0); @@ -731,11 +735,12 @@ void swp30_device::keyon_w(u16) if(m_sample_end[chan] & 0x80000000) dt = -dt; m_dpcm_address[chan] = ((m_sample_address[chan] & 0xffffff) << 2) - dt; + m_dpcm_sum[chan] = 0; m_lfo_phase[chan] = 0; if(1) - logerror("[%08d] keyon %02x %08x %08x %08x vol %04x env %04x %04x %04x\n", scount, chan, m_sample_start[chan], m_sample_end[chan], m_sample_address[chan], m_release_glo[chan], m_attack[chan], m_decay1[chan], m_decay2[chan]); + logerror("[%08d] keyon %02x %08x %08x %08x vol %04x env %04x %04x %04x pitch %04x pmod %04x\n", scount, chan, m_sample_start[chan], m_sample_end[chan], m_sample_address[chan], m_release_glo[chan], m_attack[chan], m_decay1[chan], m_decay2[chan], m_pitch[chan], m_lfo_step_pmod[chan]); } } m_keyon_mask = 0; @@ -1228,11 +1233,6 @@ uint32_t swp30_device::execute_max_cycles() const noexcept return 1; } -uint32_t swp30_device::execute_input_lines() const noexcept -{ - return 0; -} - void swp30_device::meg_prg_map(address_map &map) { @@ -1285,10 +1285,10 @@ void swp30_device::state_string_export(const device_state_entry &entry, std::str { } -void swp30_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) +void swp30_device::sound_stream_update(sound_stream &stream) { - outputs[0].put_int_clamp(0, m_meg_output[0], 32768); - outputs[1].put_int_clamp(0, m_meg_output[1], 32768); + stream.put_int_clamp(0, 0, m_meg_output[0], 32768); + stream.put_int_clamp(1, 0, m_meg_output[1], 32768); } void swp30_device::change_mode_attack_decay1(int chan) @@ -1317,6 +1317,7 @@ void swp30_device::execute_run() { while(m_icount >= 0) { if(m_meg_pc == 0) { + scount++; if(0) { static std::array<mixer_slot, 0x80> mixer; if(memcmp(mixer.data(), m_mixer.data(), sizeof(mixer))) { @@ -1475,12 +1476,15 @@ void swp30_device::execute_run() } case 3: { // 8-bits delta-pcm + u8 offset = dpcm_offset[(m_sample_address[chan] >> 25) & 3]; + u8 scale = (m_sample_address[chan] >> 27) & 7; offs_t adr = m_dpcm_address[chan]; if(m_sample_end[chan] & 0x80000000) { u32 target_address = (base_address << 2) + spos - 1; while(adr >= target_address) { m_dpcm_current[chan] = m_dpcm_next[chan]; - s32 sample = m_dpcm_next[chan] + m_dpcm[(m_rom_cache.read_dword(adr >> 2) >> (8*(adr & 3))) & 0xff]; + m_dpcm_sum[chan] += m_dpcm[(m_rom_cache.read_dword(adr >> 2) >> (8*(adr & 3))) & 0xff] - offset; + s32 sample = (m_dpcm_sum[chan] << scale) >> 3; adr --; if(sample < -0x8000) sample = -0x8000; @@ -1492,7 +1496,9 @@ void swp30_device::execute_run() u32 target_address = (base_address << 2) + spos + 1; while(adr <= target_address) { m_dpcm_current[chan] = m_dpcm_next[chan]; - s32 sample = m_dpcm_next[chan] + m_dpcm[(m_rom_cache.read_dword(adr >> 2) >> (8*(adr & 3))) & 0xff]; + m_dpcm_sum[chan] += m_dpcm[(m_rom_cache.read_dword(adr >> 2) >> (8*(adr & 3))) & 0xff] - offset; + s32 sample = (m_dpcm_sum[chan] << scale) >> 3; + // logerror("## + sample %08x %02x %d\n", adr, (m_rom_cache.read_dword(adr >> 2) >> (8*(adr & 3))) & 0xff, sample); adr ++; if(sample < -0x8000) sample = -0x8000; @@ -1543,12 +1549,13 @@ void swp30_device::execute_run() else { s32 prev = m_sample_pos[chan]; do - m_sample_pos[chan] = m_sample_pos[chan] - ((m_sample_end[chan] & 0xffffff) << 8) + ((m_sample_address[chan] >> 22) & 0xfc); + m_sample_pos[chan] -= (m_sample_end[chan] & 0xffffff) << 8; while((m_sample_pos[chan] >> 8) >= (m_sample_end[chan] & 0xffffff)); if(m_sample_end[chan] & 0x80000000) m_dpcm_address[chan] -= (m_sample_pos[chan] >> 8) - (prev >> 8); else m_dpcm_address[chan] += (m_sample_pos[chan] >> 8) - (prev >> 8); + m_dpcm_sum[chan] = 0; } } |