From 6ebf956324771f79dc1724c86f34af427ba32767 Mon Sep 17 00:00:00 2001 From: Aaron Giles Date: Mon, 14 Sep 2020 11:08:10 -0700 Subject: sound: Drive updates more sensibly from the sound manager, fixing some asserts. --- src/emu/sound.cpp | 25 +++++++++++++++++-------- src/emu/speaker.cpp | 27 +++++++++------------------ src/emu/speaker.h | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/emu/sound.cpp b/src/emu/sound.cpp index 2dd2643b7b7..80beb7fc5c1 100644 --- a/src/emu/sound.cpp +++ b/src/emu/sound.cpp @@ -1528,10 +1528,24 @@ void sound_manager::update(void *ptr, int param) g_profiler.start(PROFILER_SOUND); + // determine the duration of this update + attotime update_period = machine().time() - m_last_update; + sound_assert(update_period.seconds() == 0); + + // use that to compute the number of samples we need from the speakers + attoseconds_t sample_rate_attos = HZ_TO_ATTOSECONDS(machine().sample_rate()); + m_samples_this_update = update_period.attoseconds() / sample_rate_attos; + + // recompute the end time to an even sample boundary + attotime endtime = m_last_update + attotime(0, m_samples_this_update * sample_rate_attos); + + // clear out the mix bufers + std::fill_n(&m_leftmix[0], m_samples_this_update, 0); + std::fill_n(&m_rightmix[0], m_samples_this_update, 0); + // force all the speaker streams to generate the proper number of samples - m_samples_this_update = 0; for (speaker_device &speaker : speaker_device_iterator(machine().root_device())) - speaker.mix(&m_leftmix[0], &m_rightmix[0], m_samples_this_update, (m_muted & MUTE_REASON_SYSTEM)); + speaker.mix(&m_leftmix[0], &m_rightmix[0], m_last_update, endtime, m_samples_this_update, (m_muted & MUTE_REASON_SYSTEM)); // determine the maximum in this section stream_buffer::sample_t curmax = 0; @@ -1633,13 +1647,8 @@ void sound_manager::update(void *ptr, int param) for (auto &stream : m_orphan_stream_list) stream.first->update(); - // see if we ticked over to the next second - attotime curtime = machine().time(); - if (curtime.seconds() != m_last_update.seconds()) - sound_assert(curtime.seconds() == m_last_update.seconds() + 1); - // remember the update time - m_last_update = curtime; + m_last_update = endtime; m_update_number++; // apply sample rate changes diff --git a/src/emu/speaker.cpp b/src/emu/speaker.cpp index fbbc243e469..3cbb14355a4 100644 --- a/src/emu/speaker.cpp +++ b/src/emu/speaker.cpp @@ -56,34 +56,25 @@ speaker_device::~speaker_device() // mix - mix in samples from the speaker's stream //------------------------------------------------- -void speaker_device::mix(stream_buffer::sample_t *leftmix, stream_buffer::sample_t *rightmix, u32 &samples_this_update, bool suppress) +void speaker_device::mix(stream_buffer::sample_t *leftmix, stream_buffer::sample_t *rightmix, attotime start, attotime end, int expected_samples, bool suppress) { // skip if no stream if (m_mixer_stream == nullptr) return; - // update the stream, getting the start/end pointers around the operation - attotime start = m_mixer_stream->sample_time(); - attotime end = machine().time(); + // skip if invalid range if (start > end) return; - read_stream_view view = m_mixer_stream->update_view(start, end); - - // set or assert that all streams have the same count - if (samples_this_update == 0) - { - samples_this_update = view.samples(); - // reset the mixing streams - std::fill_n(leftmix, samples_this_update, 0); - std::fill_n(rightmix, samples_this_update, 0); - } + // get a view on the desired range + read_stream_view view = m_mixer_stream->update_view(start, end); + sound_assert(view.samples() >= expected_samples); // track maximum sample value for each 0.1s bucket if (machine().options().speaker_report() != 0) { u32 samples_per_bucket = m_mixer_stream->sample_rate() / BUCKETS_PER_SECOND; - for (int sample = 0; sample < samples_this_update; sample++) + for (int sample = 0; sample < expected_samples; sample++) { m_current_max = std::max(m_current_max, fabsf(view.get(sample))); if (++m_samples_this_bucket >= samples_per_bucket) @@ -100,7 +91,7 @@ void speaker_device::mix(stream_buffer::sample_t *leftmix, stream_buffer::sample { // if the speaker is centered, send to both left and right if (m_x == 0) - for (int sample = 0; sample < samples_this_update; sample++) + for (int sample = 0; sample < expected_samples; sample++) { stream_buffer::sample_t cursample = view.get(sample); leftmix[sample] += cursample; @@ -109,12 +100,12 @@ void speaker_device::mix(stream_buffer::sample_t *leftmix, stream_buffer::sample // if the speaker is to the left, send only to the left else if (m_x < 0) - for (int sample = 0; sample < samples_this_update; sample++) + for (int sample = 0; sample < expected_samples; sample++) leftmix[sample] += view.get(sample); // if the speaker is to the right, send only to the right else - for (int sample = 0; sample < samples_this_update; sample++) + for (int sample = 0; sample < expected_samples; sample++) rightmix[sample] += view.get(sample); } } diff --git a/src/emu/speaker.h b/src/emu/speaker.h index 7747622ca34..fd20c4b94b8 100644 --- a/src/emu/speaker.h +++ b/src/emu/speaker.h @@ -69,7 +69,7 @@ public: speaker_device &backrest() { set_position( 0.0, -0.2, 0.1); return *this; } // internally for use by the sound system - void mix(stream_buffer::sample_t *leftmix, stream_buffer::sample_t *rightmix, u32 &samples_this_update, bool suppress); + void mix(stream_buffer::sample_t *leftmix, stream_buffer::sample_t *rightmix, attotime start, attotime end, int expected_samples, bool suppress); protected: // device-level overrides -- cgit v1.2.3