diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index aec31f2de4..cfd1d4412c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1102,10 +1102,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo auto audioScriptingInterface = DependencyManager::get(); auto myAvatarPosition = DependencyManager::get()->getMyAvatar()->getWorldPosition(); float distance = glm::distance(myAvatarPosition, position); - bool shouldMute = !audioClient->isMuted() && (distance < radius); - if (shouldMute) { - audioClient->toggleMute(); + if (distance < radius) { + audioClient->setMuted(true); audioScriptingInterface->environmentMuted(); } }); @@ -1508,7 +1507,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo if (state) { if (action == controller::toInt(controller::Action::TOGGLE_MUTE)) { - DependencyManager::get()->toggleMute(); + auto audioClient = DependencyManager::get(); + audioClient->setMuted(!audioClient->isMuted()); } else if (action == controller::toInt(controller::Action::CYCLE_CAMERA)) { cycleCamera(); } else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) { @@ -3461,7 +3461,8 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_M: if (isMeta) { - DependencyManager::get()->toggleMute(); + auto audioClient = DependencyManager::get(); + audioClient->setMuted(!audioClient->isMuted()); } break; @@ -5119,7 +5120,7 @@ void Application::update(float deltaTime) { if (menu->isOptionChecked(MenuOption::AutoMuteAudio) && !audioClient->isMuted()) { if (_lastFaceTrackerUpdate > 0 && ((usecTimestampNow() - _lastFaceTrackerUpdate) > MUTE_MICROPHONE_AFTER_USECS)) { - audioClient->toggleMute(); + audioClient->setMuted(true); _lastFaceTrackerUpdate = 0; } } else { diff --git a/interface/src/scripting/Audio.cpp b/interface/src/scripting/Audio.cpp index be9b4280f7..387900b2ae 100644 --- a/interface/src/scripting/Audio.cpp +++ b/interface/src/scripting/Audio.cpp @@ -50,110 +50,162 @@ float Audio::loudnessToLevel(float loudness) { Audio::Audio() : _devices(_contextIsHMD) { auto client = DependencyManager::get().data(); - connect(client, &AudioClient::muteToggled, this, &Audio::onMutedChanged); - connect(client, &AudioClient::noiseReductionChanged, this, &Audio::onNoiseReductionChanged); + connect(client, &AudioClient::muteToggled, this, &Audio::setMuted); + connect(client, &AudioClient::noiseReductionChanged, this, &Audio::enableNoiseReduction); connect(client, &AudioClient::inputLoudnessChanged, this, &Audio::onInputLoudnessChanged); - connect(client, &AudioClient::inputVolumeChanged, this, &Audio::onInputVolumeChanged); + connect(client, &AudioClient::inputVolumeChanged, this, &Audio::setInputVolume); connect(this, &Audio::contextChanged, &_devices, &AudioDevices::onContextChanged); enableNoiseReduction(enableNoiseReductionSetting.get()); } bool Audio::startRecording(const QString& filepath) { auto client = DependencyManager::get().data(); - return client->startRecording(filepath); + return resultWithWriteLock([&] { + return client->startRecording(filepath); + }); } bool Audio::getRecording() { auto client = DependencyManager::get().data(); - return client->getRecording(); + return resultWithReadLock([&] { + return client->getRecording(); + }); } void Audio::stopRecording() { auto client = DependencyManager::get().data(); - client->stopRecording(); + withWriteLock([&] { + client->stopRecording(); + }); +} + +bool Audio::isMuted() const { + return resultWithReadLock([&] { + return _isMuted; + }); } void Audio::setMuted(bool isMuted) { - if (_isMuted != isMuted) { - auto client = DependencyManager::get().data(); - QMetaObject::invokeMethod(client, "toggleMute"); + bool changed = false; + withWriteLock([&] { + if (_isMuted != isMuted) { + _isMuted = isMuted; + auto client = DependencyManager::get().data(); + QMetaObject::invokeMethod(client, "setMuted", Q_ARG(bool, isMuted), Q_ARG(bool, false)); + changed = true; + } + }); + if (changed) { + emit mutedChanged(isMuted); } } -void Audio::onMutedChanged() { - bool isMuted = DependencyManager::get()->isMuted(); - if (_isMuted != isMuted) { - _isMuted = isMuted; - emit mutedChanged(_isMuted); - } +bool Audio::noiseReductionEnabled() const { + return resultWithReadLock([&] { + return _enableNoiseReduction; + }); } void Audio::enableNoiseReduction(bool enable) { - if (_enableNoiseReduction != enable) { - auto client = DependencyManager::get().data(); - QMetaObject::invokeMethod(client, "setNoiseReduction", Q_ARG(bool, enable)); - enableNoiseReductionSetting.set(enable); + bool changed = false; + withWriteLock([&] { + if (_enableNoiseReduction != enable) { + _enableNoiseReduction = enable; + auto client = DependencyManager::get().data(); + QMetaObject::invokeMethod(client, "setNoiseReduction", Q_ARG(bool, enable), Q_ARG(bool, false)); + enableNoiseReductionSetting.set(enable); + changed = true; + } + }); + if (changed) { + emit noiseReductionChanged(enable); } } -void Audio::onNoiseReductionChanged() { - bool noiseReductionEnabled = DependencyManager::get()->isNoiseReductionEnabled(); - if (_enableNoiseReduction != noiseReductionEnabled) { - _enableNoiseReduction = noiseReductionEnabled; - emit noiseReductionChanged(_enableNoiseReduction); - } +float Audio::getInputVolume() const { + return resultWithReadLock([&] { + return _inputVolume; + }); } void Audio::setInputVolume(float volume) { // getInputVolume will not reflect changes synchronously, so clamp beforehand volume = glm::clamp(volume, 0.0f, 1.0f); - if (_inputVolume != volume) { - auto client = DependencyManager::get().data(); - QMetaObject::invokeMethod(client, "setInputVolume", Q_ARG(float, volume)); + bool changed = false; + withWriteLock([&] { + if (_inputVolume != volume) { + _inputVolume = volume; + auto client = DependencyManager::get().data(); + QMetaObject::invokeMethod(client, "setInputVolume", Q_ARG(float, volume), Q_ARG(bool, false)); + changed = true; + } + }); + if (changed) { + emit inputVolumeChanged(volume); } } -void Audio::onInputVolumeChanged(float volume) { - if (_inputVolume != volume) { - _inputVolume = volume; - emit inputVolumeChanged(_inputVolume); - } +float Audio::getInputLevel() const { + return resultWithReadLock([&] { + return _inputLevel; + }); } void Audio::onInputLoudnessChanged(float loudness) { float level = loudnessToLevel(loudness); - - if (_inputLevel != level) { - _inputLevel = level; - emit inputLevelChanged(_inputLevel); + bool changed = false; + withWriteLock([&] { + if (_inputLevel != level) { + _inputLevel = level; + changed = true; + } + }); + if (changed) { + emit inputLevelChanged(level); } } QString Audio::getContext() const { - return _contextIsHMD ? Audio::HMD : Audio::DESKTOP; + return resultWithReadLock([&] { + return _contextIsHMD ? Audio::HMD : Audio::DESKTOP; + }); } void Audio::onContextChanged() { + bool changed = false; bool isHMD = qApp->isHMDMode(); - if (_contextIsHMD != isHMD) { - _contextIsHMD = isHMD; - emit contextChanged(getContext()); + withWriteLock([&] { + if (_contextIsHMD != isHMD) { + _contextIsHMD = isHMD; + changed = true; + } + }); + if (changed) { + emit contextChanged(isHMD ? Audio::HMD : Audio::DESKTOP); } } void Audio::setReverb(bool enable) { - DependencyManager::get()->setReverb(enable); + withWriteLock([&] { + DependencyManager::get()->setReverb(enable); + }); } void Audio::setReverbOptions(const AudioEffectOptions* options) { - DependencyManager::get()->setReverbOptions(options); + withWriteLock([&] { + DependencyManager::get()->setReverbOptions(options); + }); } void Audio::setInputDevice(const QAudioDeviceInfo& device, bool isHMD) { - _devices.chooseInputDevice(device, isHMD); + withWriteLock([&] { + _devices.chooseInputDevice(device, isHMD); + }); } void Audio::setOutputDevice(const QAudioDeviceInfo& device, bool isHMD) { - _devices.chooseOutputDevice(device, isHMD); + withWriteLock([&] { + _devices.chooseOutputDevice(device, isHMD); + }); } diff --git a/interface/src/scripting/Audio.h b/interface/src/scripting/Audio.h index 0f0043510c..b4e63b80c5 100644 --- a/interface/src/scripting/Audio.h +++ b/interface/src/scripting/Audio.h @@ -17,10 +17,11 @@ #include "AudioEffectOptions.h" #include "SettingHandle.h" #include "AudioFileWav.h" +#include namespace scripting { -class Audio : public AudioScriptingInterface { +class Audio : public AudioScriptingInterface, protected ReadWriteLockable { Q_OBJECT SINGLETON_DEPENDENCY @@ -40,16 +41,13 @@ public: virtual ~Audio() {} - bool isMuted() const { return _isMuted; } - bool noiseReductionEnabled() const { return _enableNoiseReduction; } - float getInputVolume() const { return _inputVolume; } - float getInputLevel() const { return _inputLevel; } + bool isMuted() const; + bool noiseReductionEnabled() const; + float getInputVolume() const; + float getInputLevel() const; QString getContext() const; - void setMuted(bool muted); - void enableNoiseReduction(bool enable); void showMicMeter(bool show); - void setInputVolume(float volume); Q_INVOKABLE void setInputDevice(const QAudioDeviceInfo& device, bool isHMD); Q_INVOKABLE void setOutputDevice(const QAudioDeviceInfo& device, bool isHMD); @@ -72,9 +70,9 @@ public slots: void onContextChanged(); private slots: - void onMutedChanged(); - void onNoiseReductionChanged(); - void onInputVolumeChanged(float volume); + void setMuted(bool muted); + void enableNoiseReduction(bool enable); + void setInputVolume(float volume); void onInputLoudnessChanged(float loudness); protected: diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index e2dae92a94..f643719a2e 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -757,7 +757,7 @@ void AudioClient::Gate::flush() { void AudioClient::handleNoisyMutePacket(QSharedPointer message) { if (!_muted) { - toggleMute(); + setMuted(true); // have the audio scripting interface emit a signal to say we were muted by the mixer emit mutedByMixer(); @@ -1384,15 +1384,21 @@ void AudioClient::sendMuteEnvironmentPacket() { } } -void AudioClient::toggleMute() { - _muted = !_muted; - emit muteToggled(); +void AudioClient::setMuted(bool muted, bool emitSignal) { + if (_muted != muted) { + _muted = muted; + if (emitSignal) { + emit muteToggled(_muted); + } + } } -void AudioClient::setNoiseReduction(bool enable) { +void AudioClient::setNoiseReduction(bool enable, bool emitSignal) { if (_isNoiseGateEnabled != enable) { _isNoiseGateEnabled = enable; - emit noiseReductionChanged(); + if (emitSignal) { + emit noiseReductionChanged(_isNoiseGateEnabled); + } } } @@ -2018,9 +2024,11 @@ void AudioClient::startThread() { moveToNewNamedThread(this, "Audio Thread", [this] { start(); }); } -void AudioClient::setInputVolume(float volume) { +void AudioClient::setInputVolume(float volume, bool emitSignal) { if (_audioInput && volume != (float)_audioInput->volume()) { _audioInput->setVolume(volume); - emit inputVolumeChanged(_audioInput->volume()); + if (emitSignal) { + emit inputVolumeChanged(_audioInput->volume()); + } } } diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 3bfbdb49ce..9ee7bcfeba 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -189,13 +189,13 @@ public slots: void reset(); void audioMixerKilled(); - void toggleMute(); + void setMuted(bool muted, bool emitSignal = true); bool isMuted() { return _muted; } virtual bool setIsStereoInput(bool stereo) override; virtual bool isStereoInput() override { return _isStereoInput; } - void setNoiseReduction(bool isNoiseGateEnabled); + void setNoiseReduction(bool isNoiseGateEnabled, bool emitSignal = true); bool isNoiseReductionEnabled() const { return _isNoiseGateEnabled; } bool getLocalEcho() { return _shouldEchoLocally; } @@ -218,7 +218,7 @@ public slots: bool switchAudioDevice(QAudio::Mode mode, const QString& deviceName); float getInputVolume() const { return (_audioInput) ? (float)_audioInput->volume() : 0.0f; } - void setInputVolume(float volume); + void setInputVolume(float volume, bool emitSignal = true); void setReverb(bool reverb); void setReverbOptions(const AudioEffectOptions* options); @@ -229,8 +229,8 @@ public slots: signals: void inputVolumeChanged(float volume); - void muteToggled(); - void noiseReductionChanged(); + void muteToggled(bool muted); + void noiseReductionChanged(bool noiseReductionEnabled); void mutedByMixer(); void inputReceived(const QByteArray& inputSamples); void inputLoudnessChanged(float loudness);