mirror of
https://github.com/holub/mame
synced 2025-06-05 20:33:45 +03:00
* 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()
This commit is contained in:
parent
ac042242b7
commit
fe1e26a9fb
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user