diff --git a/src/platform/qt/AudioDevice.cpp b/src/platform/qt/AudioDevice.cpp index 74f863444..d19fc20d3 100644 --- a/src/platform/qt/AudioDevice.cpp +++ b/src/platform/qt/AudioDevice.cpp @@ -62,3 +62,13 @@ qint64 AudioDevice::writeData(const char*, qint64) { LOG(QT, WARN) << tr("Writing data to read-only audio device"); return 0; } + +bool AudioDevice::atEnd() const { + if (!m_context->core) { + return true; + } + mCoreSyncLockAudio(&m_context->impl->sync); + bool available = blip_samples_avail(m_context->core->getAudioChannel(m_context->core, 0)) == 0; + mCoreSyncUnlockAudio(&m_context->impl->sync); + return available; +} diff --git a/src/platform/qt/AudioDevice.h b/src/platform/qt/AudioDevice.h index 0794b3743..86c5b17a6 100644 --- a/src/platform/qt/AudioDevice.h +++ b/src/platform/qt/AudioDevice.h @@ -20,6 +20,7 @@ public: void setInput(mCoreThread* input); void setFormat(const QAudioFormat& format); + bool atEnd() const override; protected: virtual qint64 readData(char* data, qint64 maxSize) override; diff --git a/src/platform/qt/AudioProcessorQt.cpp b/src/platform/qt/AudioProcessorQt.cpp index 4b53c7bb7..3e4c5474e 100644 --- a/src/platform/qt/AudioProcessorQt.cpp +++ b/src/platform/qt/AudioProcessorQt.cpp @@ -21,6 +21,10 @@ using namespace QGBA; AudioProcessorQt::AudioProcessorQt(QObject* parent) : AudioProcessor(parent) { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + m_recheckTimer.setInterval(1); + connect(&m_recheckTimer, &QTimer::timeout, this, &AudioProcessorQt::recheckUnderflow); +#endif } void AudioProcessorQt::setInput(std::shared_ptr controller) { @@ -34,6 +38,9 @@ void AudioProcessorQt::setInput(std::shared_ptr controller) { } void AudioProcessorQt::stop() { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + m_recheckTimer.stop(); +#endif if (m_audioOutput) { m_audioOutput->stop(); m_audioOutput.reset(); @@ -72,6 +79,12 @@ bool AudioProcessorQt::start() { QAudioDevice device(QMediaDevices::defaultAudioOutput()); m_audioOutput = std::make_unique(device, format); LOG(QT, INFO) << "Audio outputting to " << device.description(); + connect(m_audioOutput.get(), &QAudioSink::stateChanged, this, [this](QAudio::State state) { + if (state != QAudio::IdleState) { + return; + } + m_recheckTimer.start(); + }); #endif } @@ -86,6 +99,9 @@ bool AudioProcessorQt::start() { } void AudioProcessorQt::pause() { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + m_recheckTimer.stop(); +#endif if (m_audioOutput) { m_audioOutput->suspend(); } @@ -115,3 +131,16 @@ unsigned AudioProcessorQt::sampleRate() const { } return m_audioOutput->format().sampleRate(); } + +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +void AudioProcessorQt::recheckUnderflow() { + if (!m_device) { + m_recheckTimer.stop(); + return; + } + if (!m_device->atEnd()) { + start(); + m_recheckTimer.stop(); + } +} +#endif diff --git a/src/platform/qt/AudioProcessorQt.h b/src/platform/qt/AudioProcessorQt.h index 1648b967f..bdfa17a77 100644 --- a/src/platform/qt/AudioProcessorQt.h +++ b/src/platform/qt/AudioProcessorQt.h @@ -11,6 +11,7 @@ #include #else #include +#include #endif class QAudioOutput; @@ -38,10 +39,15 @@ public slots: virtual void requestSampleRate(unsigned) override; -private: #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +private slots: + void recheckUnderflow(); + +private: + QTimer m_recheckTimer; std::unique_ptr m_audioOutput; #else +private: std::unique_ptr m_audioOutput; #endif std::unique_ptr m_device;