From e9b4f6d7fe0da164936156fd45a73dd7cb2826ca Mon Sep 17 00:00:00 2001 From: BearOso Date: Mon, 3 Jul 2023 15:35:11 -0500 Subject: [PATCH] Work on sound driver levels. --- apu/resampler.h | 23 +++++++++++++++++++++++ common/audio/s9x_sound_driver_cubeb.cpp | 7 +++++-- common/audio/s9x_sound_driver_pulse.cpp | 19 +++++++++++++++++-- common/audio/s9x_sound_driver_pulse.hpp | 1 + common/audio/s9x_sound_driver_sdl.cpp | 10 ++++++++-- qt/src/EmuApplication.cpp | 6 ++++++ 6 files changed, 60 insertions(+), 6 deletions(-) diff --git a/apu/resampler.h b/apu/resampler.h index 185ea9d5..d144bb3b 100644 --- a/apu/resampler.h +++ b/apu/resampler.h @@ -91,6 +91,29 @@ class Resampler r_right[0] = r_right[1] = r_right[2] = r_right[3] = 0; } + inline void dump(unsigned int num_samples) + { + if (space_filled() >= num_samples) + start = (start + num_samples) % buffer_size; + } + + inline void add_silence(unsigned int num_samples) + { + if (space_empty() <= num_samples) + { + int new_end = (end + num_samples) % buffer_size; + + if (new_end < end) + { + memset(buffer + end, 0, 2 * (buffer_size - end)); + memset(buffer, 0, 2 * (num_samples - (buffer_size - end))); + } + + memset(buffer + end, 0, 2 * num_samples); + end = new_end; + } + } + inline bool pull(int16_t *dst, int num_samples) { if (space_filled() < num_samples) diff --git a/common/audio/s9x_sound_driver_cubeb.cpp b/common/audio/s9x_sound_driver_cubeb.cpp index bbbe31f0..cf0ef3ac 100644 --- a/common/audio/s9x_sound_driver_cubeb.cpp +++ b/common/audio/s9x_sound_driver_cubeb.cpp @@ -10,11 +10,13 @@ bool S9xCubebSoundDriver::write_samples(int16_t *data, int samples) { bool retval = true; - if (samples > buffer.space_empty()) + auto empty = buffer.space_empty(); + if (samples > empty) { retval = false; - samples = buffer.space_empty(); + buffer.dump(buffer.buffer_size / 2 - empty); } + buffer.push(data, samples); return retval; @@ -83,6 +85,7 @@ long S9xCubebSoundDriver::data_callback(cubeb_stream *stream, void const *input_ auto zeroed_samples = nframes * 2 - avail; memset(output_buffer, 0, zeroed_samples); buffer.read((int16_t *)output_buffer + zeroed_samples, nframes * 2 - zeroed_samples); + buffer.add_silence(buffer.buffer_size / 2); } else { diff --git a/common/audio/s9x_sound_driver_pulse.cpp b/common/audio/s9x_sound_driver_pulse.cpp index 5d26a289..ebe2a167 100644 --- a/common/audio/s9x_sound_driver_pulse.cpp +++ b/common/audio/s9x_sound_driver_pulse.cpp @@ -111,10 +111,10 @@ bool S9xPulseSoundDriver::open_device(int playback_rate, int buffer_size_ms) ss.rate = playback_rate; pa_buffer_attr buffer_attr; - buffer_attr.tlength = pa_usec_to_bytes(buffer_size_ms * 1000, &ss); + buffer_attr.tlength = 2 * pa_usec_to_bytes(buffer_size_ms * 1000, &ss); buffer_attr.maxlength = buffer_attr.tlength * 2; buffer_attr.minreq = pa_usec_to_bytes(3000, &ss); - buffer_attr.prebuf = -1; + buffer_attr.prebuf = buffer_attr.tlength / 2; printf("PulseAudio sound driver initializing...\n"); @@ -189,8 +189,23 @@ bool S9xPulseSoundDriver::write_samples(int16_t *data, int samples) size_t bytes = pa_stream_writable_size(stream); unlock(); + if (draining) + { + if (bytes > buffer_size / 2) + { + return false; + } + else + { + draining = false; + } + } + if (samples * 2 > bytes) + { + draining = true; return false; + } if (samples * 2 < bytes) bytes = samples * 2; diff --git a/common/audio/s9x_sound_driver_pulse.hpp b/common/audio/s9x_sound_driver_pulse.hpp index 12ee60b4..ea1399ff 100644 --- a/common/audio/s9x_sound_driver_pulse.hpp +++ b/common/audio/s9x_sound_driver_pulse.hpp @@ -32,6 +32,7 @@ class S9xPulseSoundDriver : public S9xSoundDriver void wait(); int buffer_size; + bool draining = false; }; #endif /* __S9X_SOUND_DRIVER_PULSE_HPP */ diff --git a/common/audio/s9x_sound_driver_sdl.cpp b/common/audio/s9x_sound_driver_sdl.cpp index 01e93335..ec980b26 100644 --- a/common/audio/s9x_sound_driver_sdl.cpp +++ b/common/audio/s9x_sound_driver_sdl.cpp @@ -10,10 +10,11 @@ bool S9xSDLSoundDriver::write_samples(int16_t *data, int samples) { bool retval = true; - if (samples > buffer.space_empty()) + auto empty = buffer.space_empty(); + if (samples > empty) { retval = false; - samples = buffer.space_empty(); + buffer.dump(buffer.buffer_size / 2 - empty); } buffer.push(data, samples); @@ -24,6 +25,11 @@ void S9xSDLSoundDriver::mix(unsigned char *output, int bytes) { if (buffer.avail() >= bytes >> 1) buffer.read((int16_t *)output, bytes >> 1); + else + { + buffer.read((int16_t *)output, buffer.avail()); + buffer.add_silence(buffer.buffer_size / 2); + } } S9xSDLSoundDriver::S9xSDLSoundDriver() diff --git a/qt/src/EmuApplication.cpp b/qt/src/EmuApplication.cpp index 76662800..4f5748ed 100644 --- a/qt/src/EmuApplication.cpp +++ b/qt/src/EmuApplication.cpp @@ -84,8 +84,14 @@ static void trackBufferLevel(int percent, QWidget *parent) ticks = 0; } + dialog->setFocusPolicy(Qt::FocusPolicy::NoFocus); + if (!dialog->isVisible()) + { + dialog->setDisabled(true); dialog->show(); + dialog->setModal(false); + } } #endif