summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
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
commit6fcc1587fcb60a8cb6d93b811778be0bc0c380de (patch)
treef8bf8819bf792b63fd9b61d9b07a6d3ed261c942
parentbd606bd055e05062a5b707c810465f65e989870d (diff)
parenta5579831cae73eb13c01b10d74666ee41a217887 (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.cpp80
-rw-r--r--src/devices/sound/okiadpcm.h12
-rw-r--r--src/devices/sound/qs1000.cpp14
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;