diff options
author | R. Belmont <rb6502@users.noreply.github.com> | 2020-06-11 15:37:02 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-11 15:37:02 -0400 |
commit | 6fcc1587fcb60a8cb6d93b811778be0bc0c380de (patch) | |
tree | f8bf8819bf792b63fd9b61d9b07a6d3ed261c942 | |
parent | bd606bd055e05062a5b707c810465f65e989870d (diff) | |
parent | a5579831cae73eb13c01b10d74666ee41a217887 (diff) |
Merge pull request #6819 from cam900/oki_loop
okiadpcm.cpp: Add looped sample support, Allow reading current output without decoding
-rw-r--r-- | src/devices/sound/okiadpcm.cpp | 80 | ||||
-rw-r--r-- | src/devices/sound/okiadpcm.h | 12 | ||||
-rw-r--r-- | src/devices/sound/qs1000.cpp | 14 |
3 files changed, 96 insertions, 10 deletions
diff --git a/src/devices/sound/okiadpcm.cpp b/src/devices/sound/okiadpcm.cpp index 160ddc3519b..4b565042288 100644 --- a/src/devices/sound/okiadpcm.cpp +++ b/src/devices/sound/okiadpcm.cpp @@ -2,7 +2,7 @@ // copyright-holders:Andrew Gardner,Aaron Giles /*************************************************************************** - okiadpcm.h + okiadpcm.cpp OKI ADPCM emulation. @@ -39,14 +39,15 @@ int oki_adpcm_state::s_diff_lookup[49*16]; void oki_adpcm_state::reset() { // reset the signal/step - m_signal = -2; - m_step = 0; + m_signal = m_loop_signal = 0; + m_step = m_loop_step = 0; + m_saved = false; } //------------------------------------------------- -// device_clock_changed - called if the clock -// changes +// clock - decode single nibble and update +// ADPCM output //------------------------------------------------- int16_t oki_adpcm_state::clock(uint8_t nibble) @@ -73,6 +74,36 @@ int16_t oki_adpcm_state::clock(uint8_t nibble) //------------------------------------------------- +// save - save current ADPCM state to buffer +//------------------------------------------------- + +void oki_adpcm_state::save() +{ + if (!m_saved) + { + m_loop_signal = m_signal; + m_loop_step = m_step; + m_saved = true; + } +} + + +//------------------------------------------------- +// restore - restore previous ADPCM state +// from buffer +//------------------------------------------------- + +void oki_adpcm_state::restore() +{ + if (m_saved) + { + m_signal = m_loop_signal; + m_step = m_loop_step; + } +} + + +//------------------------------------------------- // compute_tables - precompute tables for faster // sound generation //------------------------------------------------- @@ -128,14 +159,15 @@ int oki_adpcm2_state::s_diff_lookup[49*16]; void oki_adpcm2_state::reset() { // reset the signal/step - m_signal = -2; - m_step = 0; + m_signal = m_loop_signal = -2; + m_step = m_loop_step = 0; + m_saved = false; } //------------------------------------------------- -// device_clock_changed - called if the clock -// changes +// clock - decode single nibble and update +// ADPCM output //------------------------------------------------- int16_t oki_adpcm2_state::clock(uint8_t nibble) @@ -162,6 +194,36 @@ int16_t oki_adpcm2_state::clock(uint8_t nibble) //------------------------------------------------- +// save - save current ADPCM state to buffer +//------------------------------------------------- + +void oki_adpcm2_state::save() +{ + if (!m_saved) + { + m_loop_signal = m_signal; + m_loop_step = m_step; + m_saved = true; + } +} + + +//------------------------------------------------- +// restore - restore previous ADPCM state +// from buffer +//------------------------------------------------- + +void oki_adpcm2_state::restore() +{ + if (m_saved) + { + m_signal = m_loop_signal; + m_step = m_loop_step; + } +} + + +//------------------------------------------------- // compute_tables - precompute tables for faster // sound generation //------------------------------------------------- diff --git a/src/devices/sound/okiadpcm.h b/src/devices/sound/okiadpcm.h index 62ff8d9a5fc..b89e3ab8db7 100644 --- a/src/devices/sound/okiadpcm.h +++ b/src/devices/sound/okiadpcm.h @@ -24,9 +24,15 @@ public: void reset(); int16_t clock(uint8_t nibble); + int16_t output() { return m_signal; } + void save(); + void restore(); int32_t m_signal; int32_t m_step; + int32_t m_loop_signal; + int32_t m_loop_step; + bool m_saved; private: static const int8_t s_index_shift[8]; @@ -48,9 +54,15 @@ public: void reset(); int16_t clock(uint8_t nibble); + int16_t output() { return m_signal; } + void save(); + void restore(); int32_t m_signal; int32_t m_step; + int32_t m_loop_signal; + int32_t m_loop_step; + bool m_saved; private: static const int8_t s_index_shift[8]; diff --git a/src/devices/sound/qs1000.cpp b/src/devices/sound/qs1000.cpp index 4f6f86fa6d1..0fd23945a2e 100644 --- a/src/devices/sound/qs1000.cpp +++ b/src/devices/sound/qs1000.cpp @@ -259,6 +259,9 @@ void qs1000_device::device_start() save_item(NAME(m_channels[i].m_regs), i); save_item(NAME(m_channels[i].m_adpcm.m_signal), i); save_item(NAME(m_channels[i].m_adpcm.m_step), i); + save_item(NAME(m_channels[i].m_adpcm.m_loop_signal), i); + save_item(NAME(m_channels[i].m_adpcm.m_loop_step), i); + save_item(NAME(m_channels[i].m_adpcm.m_saved), i); } } @@ -504,8 +507,17 @@ void qs1000_device::sound_stream_update(sound_stream &stream, stream_sample_t ** { chan.m_adpcm_addr++; - if (chan.m_start + chan.m_adpcm_addr >= chan.m_loop_end) + if (chan.m_start + chan.m_adpcm_addr >= chan.m_loop_end) + { chan.m_adpcm_addr = chan.m_loop_start - chan.m_start; +#if 0 // Looping disabled until envelopes work + chan.m_adpcm.restore(); + } + if (chan.m_start + chan.m_adpcm_addr == chan.m_loop_start) + { + chan.m_adpcm.save(); +#endif + } uint8_t data = read_byte(chan.m_start + (chan.m_adpcm_addr >> 1)); uint8_t nibble = (chan.m_adpcm_addr & 1 ? data : data >> 4) & 0xf; |