From 4b2778f02dbc932c90a673fcf95f98c2df923b54 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Sat, 20 Aug 2016 12:22:47 -0700 Subject: [PATCH] Re-implement the continuous detection of device changes for all platforms, using a background thread. This prevents the glitches caused by calling checkDevices() on the audio processing thread. --- libraries/audio-client/src/AudioClient.cpp | 41 +++++++++++++++++----- libraries/audio-client/src/AudioClient.h | 3 +- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index cf43730258..8f8d17d4ad 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -67,6 +67,33 @@ Setting::Handle windowSecondsForDesiredReduction("windowSecondsForDesiredRe DEFAULT_WINDOW_SECONDS_FOR_DESIRED_REDUCTION); Setting::Handle repetitionWithFade("repetitionWithFade", DEFAULT_REPETITION_WITH_FADE); +// background thread that continuously polls for device changes +class CheckDevicesThread : public QThread { +public: + const unsigned long DEVICE_CHECK_INTERVAL_MSECS = 2 * 1000; + + CheckDevicesThread(AudioClient* audioClient) + : _audioClient(audioClient) { + + connect(qApp, &QCoreApplication::aboutToQuit, [this] { + _quit = true; + }); + } + + void run() override { + while (!_quit) { + + //qDebug() << "Checking for audio device changes..."; + _audioClient->checkDevices(); + + QThread::msleep(DEVICE_CHECK_INTERVAL_MSECS); + } + } + + AudioClient* _audioClient { nullptr }; + bool _quit { false }; +}; + AudioClient::AudioClient() : AbstractAudioInterface(), _audioInput(NULL), @@ -121,14 +148,14 @@ AudioClient::AudioClient() : connect(&_receivedAudioStream, &InboundAudioStream::mismatchedAudioCodec, this, &AudioClient::handleMismatchAudioFormat); - _inputDevices = getDeviceNames(QAudio::AudioInput); _outputDevices = getDeviceNames(QAudio::AudioOutput); - const qint64 DEVICE_CHECK_INTERVAL_MSECS = 2 * 1000; - QTimer* updateTimer = new QTimer(this); - connect(updateTimer, &QTimer::timeout, this, &AudioClient::checkDevices); - updateTimer->start(DEVICE_CHECK_INTERVAL_MSECS); + // start a thread to detect any device changes + QThread* checkDevicesThread = new CheckDevicesThread(this); + checkDevicesThread->setObjectName("CheckDevices Thread"); + checkDevicesThread->setPriority(QThread::LowPriority); + checkDevicesThread->start(); configureReverb(); @@ -1349,9 +1376,6 @@ qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) { } void AudioClient::checkDevices() { -# if defined(Q_OS_LINUX) || defined (Q_OS_WIN) - // on Windows and Linux, this causes dropouts in the audio stream -# else QVector inputDevices = getDeviceNames(QAudio::AudioInput); QVector outputDevices = getDeviceNames(QAudio::AudioOutput); @@ -1361,7 +1385,6 @@ void AudioClient::checkDevices() { emit deviceChanged(); } -# endif } void AudioClient::loadSettings() { diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 9db2cc0489..1ee4b92a0c 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -139,6 +139,8 @@ public: QVector& getActiveLocalAudioInjectors() { return _activeLocalAudioInjectors; } + void checkDevices(); + static const float CALLBACK_ACCELERATOR_RATIO; #ifdef Q_OS_WIN @@ -312,7 +314,6 @@ private: QVector _inputDevices; QVector _outputDevices; - void checkDevices(); bool _hasReceivedFirstPacket = false;