From fe1e26a9fb437de24661a5cb16f82ec94cdb14fc Mon Sep 17 00:00:00 2001 From: couriersud Date: Wed, 15 Jun 2022 12:39:00 +0200 Subject: 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() --- src/emu/sound.cpp | 21 +++++++++++++++++---- src/emu/sound.h | 5 +++++ 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 //************************************************************************** // 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 m_input; // list of streams we directly depend upon std::vector m_input_view; // array of output views for passing to the callback -- cgit v1.2.3