From 29ff47c6fbd613bf196851eda4963194bff910e5 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 18 Jun 2018 16:23:54 -0700 Subject: [PATCH 1/3] Ensure audio devices are made on the right thread --- libraries/audio-client/src/AudioClient.cpp | 6 +++++- libraries/script-engine/src/AudioScriptingInterface.cpp | 9 ++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index a5f79290cd..39578622c9 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -1463,6 +1463,8 @@ void AudioClient::outputFormatChanged() { } bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInfo, bool isShutdownRequest) { + Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread"); + qCDebug(audioclient) << __FUNCTION__ << "inputDeviceInfo: [" << inputDeviceInfo.deviceName() << "]"; bool supportedFormat = false; @@ -1663,6 +1665,8 @@ void AudioClient::outputNotify() { } bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceInfo, bool isShutdownRequest) { + Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread"); + qCDebug(audioclient) << "AudioClient::switchOutputToAudioDevice() outputDeviceInfo: [" << outputDeviceInfo.deviceName() << "]"; bool supportedFormat = false; @@ -2021,7 +2025,7 @@ void AudioClient::setAvatarBoundingBoxParameters(glm::vec3 corner, glm::vec3 sca void AudioClient::startThread() { - moveToNewNamedThread(this, "Audio Thread", [this] { start(); }); + moveToNewNamedThread(this, "Audio Thread", [this] { start(); }, QThread::TimeCriticalPriority); } void AudioClient::setInputVolume(float volume, bool emitSignal) { diff --git a/libraries/script-engine/src/AudioScriptingInterface.cpp b/libraries/script-engine/src/AudioScriptingInterface.cpp index f248c20d41..c06bb2d952 100644 --- a/libraries/script-engine/src/AudioScriptingInterface.cpp +++ b/libraries/script-engine/src/AudioScriptingInterface.cpp @@ -63,8 +63,15 @@ ScriptAudioInjector* AudioScriptingInterface::playSound(SharedSoundPointer sound bool AudioScriptingInterface::setStereoInput(bool stereo) { bool stereoInputChanged = false; if (_localAudioInterface) { - stereoInputChanged = _localAudioInterface->setIsStereoInput(stereo); + if (QThread::currentThread() != _localAudioInterface->thread()) { + // TODO: This can block the main thread which is not ideal, make this function and the UI calling it async + BLOCKING_INVOKE_METHOD(_localAudioInterface, "setIsStereoInput", Q_RETURN_ARG(bool, stereoInputChanged), + Q_ARG(bool, stereo)); + } else { + stereoInputChanged = _localAudioInterface->setIsStereoInput(stereo); + } } + return stereoInputChanged; } From 4a4c0d132ecd489fc541ea575b12e7459112584b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 18 Jun 2018 17:25:38 -0700 Subject: [PATCH 2/3] Make stereo interface async --- interface/resources/qml/hifi/audio/Audio.qml | 8 ++---- libraries/audio-client/src/AudioClient.cpp | 2 ++ libraries/audio/src/AbstractAudioInterface.h | 3 ++ .../src/AudioScriptingInterface.cpp | 28 +++++++++++-------- .../src/AudioScriptingInterface.h | 14 ++++++++-- 5 files changed, 36 insertions(+), 19 deletions(-) diff --git a/interface/resources/qml/hifi/audio/Audio.qml b/interface/resources/qml/hifi/audio/Audio.qml index ba50b7f238..cc1ba49984 100644 --- a/interface/resources/qml/hifi/audio/Audio.qml +++ b/interface/resources/qml/hifi/audio/Audio.qml @@ -129,12 +129,10 @@ Rectangle { id: stereoMic spacing: muteMic.spacing; text: qsTr("Enable stereo input"); - checked: AudioScriptingInterface.isStereoInput(); + checked: AudioScriptingInterface.isStereoInput; onClicked: { - var success = AudioScriptingInterface.setStereoInput(checked); - if (!success) { - checked = !checked; - } + AudioScriptingInterface.isStereoInput = checked; + checked = Qt.binding(function() { return AudioScriptingInterface.isStereoInput; }); // restore binding } } } diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 39578622c9..a6f0416a30 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -1426,6 +1426,8 @@ bool AudioClient::setIsStereoInput(bool isStereoInput) { // restart the input device switchInputToAudioDevice(_inputDeviceInfo); + + emit isStereoInputChanged(_isStereoInput); } return stereoInputChanged; diff --git a/libraries/audio/src/AbstractAudioInterface.h b/libraries/audio/src/AbstractAudioInterface.h index 30cbceeb0e..bbfd79d0aa 100644 --- a/libraries/audio/src/AbstractAudioInterface.h +++ b/libraries/audio/src/AbstractAudioInterface.h @@ -44,6 +44,9 @@ public slots: virtual bool setIsStereoInput(bool stereo) = 0; virtual bool isStereoInput() = 0; + +signals: + void isStereoInputChanged(bool isStereo); }; Q_DECLARE_METATYPE(AbstractAudioInterface*) diff --git a/libraries/script-engine/src/AudioScriptingInterface.cpp b/libraries/script-engine/src/AudioScriptingInterface.cpp index c06bb2d952..72918e33f6 100644 --- a/libraries/script-engine/src/AudioScriptingInterface.cpp +++ b/libraries/script-engine/src/AudioScriptingInterface.cpp @@ -23,6 +23,21 @@ void registerAudioMetaTypes(QScriptEngine* engine) { qScriptRegisterMetaType(engine, soundSharedPointerToScriptValue, soundSharedPointerFromScriptValue); } + +void AudioScriptingInterface::setLocalAudioInterface(AbstractAudioInterface* audioInterface) { + if (_localAudioInterface) { + disconnect(_localAudioInterface, &AbstractAudioInterface::isStereoInputChanged, + this, &AudioScriptingInterface::isStereoInputChanged); + } + + _localAudioInterface = audioInterface; + + if (_localAudioInterface) { + connect(_localAudioInterface, &AbstractAudioInterface::isStereoInputChanged, + this, &AudioScriptingInterface::isStereoInputChanged); + } +} + ScriptAudioInjector* AudioScriptingInterface::playSystemSound(SharedSoundPointer sound, const QVector3D& position) { AudioInjectorOptions options; options.position = glm::vec3(position.x(), position.y(), position.z()); @@ -60,19 +75,10 @@ ScriptAudioInjector* AudioScriptingInterface::playSound(SharedSoundPointer sound } } -bool AudioScriptingInterface::setStereoInput(bool stereo) { - bool stereoInputChanged = false; +void AudioScriptingInterface::setStereoInput(bool stereo) { if (_localAudioInterface) { - if (QThread::currentThread() != _localAudioInterface->thread()) { - // TODO: This can block the main thread which is not ideal, make this function and the UI calling it async - BLOCKING_INVOKE_METHOD(_localAudioInterface, "setIsStereoInput", Q_RETURN_ARG(bool, stereoInputChanged), - Q_ARG(bool, stereo)); - } else { - stereoInputChanged = _localAudioInterface->setIsStereoInput(stereo); - } + QMetaObject::invokeMethod(_localAudioInterface, "setIsStereoInput", Q_ARG(bool, stereo)); } - - return stereoInputChanged; } bool AudioScriptingInterface::isStereoInput() { diff --git a/libraries/script-engine/src/AudioScriptingInterface.h b/libraries/script-engine/src/AudioScriptingInterface.h index 36fe29243d..20ca977da1 100644 --- a/libraries/script-engine/src/AudioScriptingInterface.h +++ b/libraries/script-engine/src/AudioScriptingInterface.h @@ -23,9 +23,11 @@ class AudioScriptingInterface : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY + Q_PROPERTY(bool isStereoInput READ isStereoInput WRITE setStereoInput NOTIFY isStereoInputChanged) + public: virtual ~AudioScriptingInterface() {} - void setLocalAudioInterface(AbstractAudioInterface* audioInterface) { _localAudioInterface = audioInterface; } + void setLocalAudioInterface(AbstractAudioInterface* audioInterface); protected: AudioScriptingInterface() {} @@ -52,9 +54,8 @@ protected: /**jsdoc * @function Audio.setStereoInput * @param {boolean} stereo - * @returns {boolean} */ - Q_INVOKABLE bool setStereoInput(bool stereo); + Q_INVOKABLE void setStereoInput(bool stereo); /**jsdoc * @function Audio.isStereoInput @@ -114,6 +115,13 @@ signals: */ void inputReceived(const QByteArray& inputSamples); + /**jsdoc + * @function Audio.isStereoInputChanged + * @param {boolean} isStereo + * @returns {Signal} + */ + void isStereoInputChanged(bool isStereo); + private: AbstractAudioInterface* _localAudioInterface { nullptr }; }; From 2bf7db6952555dc0f513c5205600badc995ea6a9 Mon Sep 17 00:00:00 2001 From: Clement Date: Tue, 19 Jun 2018 16:36:37 -0700 Subject: [PATCH 3/3] setStereoInput always returns true to not break old scripts --- libraries/script-engine/src/AudioScriptingInterface.cpp | 3 ++- libraries/script-engine/src/AudioScriptingInterface.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/script-engine/src/AudioScriptingInterface.cpp b/libraries/script-engine/src/AudioScriptingInterface.cpp index 72918e33f6..be419e8005 100644 --- a/libraries/script-engine/src/AudioScriptingInterface.cpp +++ b/libraries/script-engine/src/AudioScriptingInterface.cpp @@ -75,10 +75,11 @@ ScriptAudioInjector* AudioScriptingInterface::playSound(SharedSoundPointer sound } } -void AudioScriptingInterface::setStereoInput(bool stereo) { +bool AudioScriptingInterface::setStereoInput(bool stereo) { if (_localAudioInterface) { QMetaObject::invokeMethod(_localAudioInterface, "setIsStereoInput", Q_ARG(bool, stereo)); } + return true; } bool AudioScriptingInterface::isStereoInput() { diff --git a/libraries/script-engine/src/AudioScriptingInterface.h b/libraries/script-engine/src/AudioScriptingInterface.h index 20ca977da1..843fa3e8f0 100644 --- a/libraries/script-engine/src/AudioScriptingInterface.h +++ b/libraries/script-engine/src/AudioScriptingInterface.h @@ -54,8 +54,9 @@ protected: /**jsdoc * @function Audio.setStereoInput * @param {boolean} stereo + * @returns {boolean} */ - Q_INVOKABLE void setStereoInput(bool stereo); + Q_INVOKABLE bool setStereoInput(bool stereo); /**jsdoc * @function Audio.isStereoInput