summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author couriersud <couriersud@users.noreply.github.com>2022-06-15 12:39:00 +0200
committer GitHub <noreply@github.com>2022-06-15 12:39:00 +0200
commitfe1e26a9fb437de24661a5cb16f82ec94cdb14fc (patch)
treeefbb9c3724d046585af9b28a09d4eaab92a490dc
parentac042242b7d04fe690a79b55a3b49af711885bb8 (diff)
sound.cpp: Fix missed samples due to state save (#9917) (#9918)
* sound.cpp: Fix missed samples due to state save (#9917) The PR address #9917. A save state may occur between time slices. Sound devices through sound.cpp are updated during a timer call every 20ms. When the state is saved, these devices are not updated to the current machine time. Consequently after a state load the devices have have a "time lag" since in postload buffer end time is forced to machine time. This change will save the last buffer end time so that all outstanding samples are processed. This is a core change. I tested it on some drivers. This needs a very thorough review and I post the PR primarily to document a possible solution. * sound.cpp: use "stream.sound_stream" as module name for save_item * sound.cpp: use presave handler to store end_time()
-rw-r--r--src/emu/sound.cpp21
-rw-r--r--src/emu/sound.h5
2 files changed, 22 insertions, 4 deletions
diff --git a/src/emu/sound.cpp b/src/emu/sound.cpp
index 88cdade710d..c1932099be6 100644
--- a/src/emu/sound.cpp
+++ b/src/emu/sound.cpp
@@ -15,7 +15,7 @@
#include "config.h"
#include "wavwrite.h"
-
+#include <vector>
//**************************************************************************
// DEBUGGING
@@ -560,6 +560,7 @@ sound_stream::sound_stream(device_t &device, u32 inputs, u32 outputs, u32 output
m_synchronous((flags & STREAM_SYNCHRONOUS) != 0),
m_resampling_disabled((flags & STREAM_DISABLE_INPUT_RESAMPLING) != 0),
m_sync_timer(nullptr),
+ m_last_update_end_time(attotime::zero),
m_input(inputs),
m_input_view(inputs),
m_empty_buffer(100),
@@ -578,8 +579,10 @@ sound_stream::sound_stream(device_t &device, u32 inputs, u32 outputs, u32 output
// create a unique tag for saving
std::string state_tag = string_format("%d", m_device.machine().sound().unique_id());
auto &save = m_device.machine().save();
- save.save_item(&m_device, "stream.sample_rate", state_tag.c_str(), 0, NAME(m_sample_rate));
+ save.save_item(&m_device, "stream.sound_stream", state_tag.c_str(), 0, NAME(m_sample_rate));
+ save.save_item(&m_device, "stream.sound_stream", state_tag.c_str(), 0, NAME(m_last_update_end_time));
save.register_postload(save_prepost_delegate(FUNC(sound_stream::postload), this));
+ save.register_presave(save_prepost_delegate(FUNC(sound_stream::presave), this));
// initialize all inputs
for (unsigned int inputnum = 0; inputnum < m_input.size(); inputnum++)
@@ -857,14 +860,24 @@ void sound_stream::sample_rate_changed()
void sound_stream::postload()
{
- // set the end time of all of our streams to now
+ // set the end time of all of our streams to the value saved in m_last_update_end_time
for (auto &output : m_output)
- output.set_end_time(m_device.machine().time());
+ output.set_end_time(m_last_update_end_time);
// recompute the sample rate information
sample_rate_changed();
}
+//-------------------------------------------------
+// presave - save/restore callback
+//-------------------------------------------------
+
+void sound_stream::presave()
+{
+ // save the stream end time
+ m_last_update_end_time = m_output[0].end_time();
+}
+
//-------------------------------------------------
// reprime_sync_timer - set up the next sync
diff --git a/src/emu/sound.h b/src/emu/sound.h
index 658c956e5d4..15f6a5743a2 100644
--- a/src/emu/sound.h
+++ b/src/emu/sound.h
@@ -670,6 +670,9 @@ private:
// handle updates after a save state load
void postload();
+ // handle updates before a save state load
+ void presave();
+
// re-print the synchronization timer
void reprime_sync_timer();
@@ -693,6 +696,8 @@ private:
bool m_resampling_disabled; // is resampling of input streams disabled?
emu_timer *m_sync_timer; // update timer for synchronous streams
+ attotime m_last_update_end_time; // last end_time() in update
+
// input information
std::vector<sound_stream_input> m_input; // list of streams we directly depend upon
std::vector<read_stream_view> m_input_view; // array of output views for passing to the callback