diff --git a/app/audio/audiomanager.cpp b/app/audio/audiomanager.cpp index 77bedcb6d..721d99f3b 100644 --- a/app/audio/audiomanager.cpp +++ b/app/audio/audiomanager.cpp @@ -20,6 +20,8 @@ #include "audiomanager.h" +#include + #include "config/config.h" AudioManager* AudioManager::instance_ = nullptr; @@ -53,7 +55,18 @@ void AudioManager::RefreshDevices() refreshing_devices_ = true; - refresh_thread_.start(QThread::LowPriority); + // Refreshing devices can take some time, so we do it in a separate thread + QThread* thread = new QThread(); + connect(thread, &QThread::finished, thread, &QThread::deleteLater); + thread->start(QThread::LowPriority); + + AudioRefreshDevicesObject* refresher = new AudioRefreshDevicesObject(); + connect(refresher, &AudioRefreshDevicesObject::ListsReady, this, &AudioManager::RefreshThreadDone); + refresher->moveToThread(thread); + + QMetaObject::invokeMethod(refresher, + "Refresh", + Qt::QueuedConnection); } bool AudioManager::IsRefreshing() @@ -169,8 +182,6 @@ AudioManager::AudioManager() : input_file_(nullptr), refreshing_devices_(false) { - connect(&refresh_thread_, &AudioRefreshDevicesThread::ListsReady, this, &AudioManager::RefreshThreadDone); - RefreshDevices(); connect(&output_manager_, &AudioHybridDevice::HasSamples, this, &AudioManager::OutputManagerHasSamples); @@ -182,8 +193,10 @@ AudioManager::AudioManager() : void AudioManager::RefreshThreadDone() { - output_devices_ = refresh_thread_.output_devices(); - input_devices_ = refresh_thread_.input_devices(); + AudioRefreshDevicesObject* refresher = static_cast(sender()); + + output_devices_ = refresher->output_devices(); + input_devices_ = refresher->input_devices(); refreshing_devices_ = false; @@ -219,6 +232,9 @@ void AudioManager::RefreshThreadDone() } } + // Clean up refresher object + refresher->deleteLater(); + emit DeviceListReady(); } @@ -241,24 +257,27 @@ void AudioManager::OutputNotified() } } -AudioRefreshDevicesThread::AudioRefreshDevicesThread() +AudioRefreshDevicesObject::AudioRefreshDevicesObject() { } -void AudioRefreshDevicesThread::run() -{ - output_devices_ = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); - input_devices_ = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); - - emit ListsReady(); -} - -const QList& AudioRefreshDevicesThread::input_devices() +const QList& AudioRefreshDevicesObject::input_devices() { return input_devices_; } -const QList& AudioRefreshDevicesThread::output_devices() +const QList& AudioRefreshDevicesObject::output_devices() { return output_devices_; } + +void AudioRefreshDevicesObject::Refresh() +{ + output_devices_ = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); + input_devices_ = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); + + // Move back to main thread + moveToThread(QApplication::instance()->thread()); + + emit ListsReady(); +} diff --git a/app/audio/audiomanager.h b/app/audio/audiomanager.h index 9a6c2f765..1eb8fa3c4 100644 --- a/app/audio/audiomanager.h +++ b/app/audio/audiomanager.h @@ -34,16 +34,17 @@ * * Refreshing devices causes a noticeable pause in execution. Doing it another thread is intended to avoid this. */ -class AudioRefreshDevicesThread : public QThread { +class AudioRefreshDevicesObject : public QObject { Q_OBJECT public: - AudioRefreshDevicesThread(); - - virtual void run() override; + AudioRefreshDevicesObject(); const QList& input_devices(); const QList& output_devices(); +public slots: + void Refresh(); + signals: void ListsReady(); @@ -120,8 +121,6 @@ private: bool refreshing_devices_; - AudioRefreshDevicesThread refresh_thread_; - private slots: void RefreshThreadDone();