try to fix audio crash on startup

This commit is contained in:
SamGondelman 2018-04-18 13:29:39 -07:00
parent 7c65c9c444
commit 3b4b43cf66
5 changed files with 134 additions and 75 deletions

View file

@ -1102,10 +1102,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
auto audioScriptingInterface = DependencyManager::get<AudioScriptingInterface>();
auto myAvatarPosition = DependencyManager::get<AvatarManager>()->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<AudioClient>()->toggleMute();
auto audioClient = DependencyManager::get<AudioClient>();
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<AudioClient>()->toggleMute();
auto audioClient = DependencyManager::get<AudioClient>();
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 {

View file

@ -50,110 +50,162 @@ float Audio::loudnessToLevel(float loudness) {
Audio::Audio() : _devices(_contextIsHMD) {
auto client = DependencyManager::get<AudioClient>().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<AudioClient>().data();
return client->startRecording(filepath);
return resultWithWriteLock<bool>([&] {
return client->startRecording(filepath);
});
}
bool Audio::getRecording() {
auto client = DependencyManager::get<AudioClient>().data();
return client->getRecording();
return resultWithReadLock<bool>([&] {
return client->getRecording();
});
}
void Audio::stopRecording() {
auto client = DependencyManager::get<AudioClient>().data();
client->stopRecording();
withWriteLock([&] {
client->stopRecording();
});
}
bool Audio::isMuted() const {
return resultWithReadLock<bool>([&] {
return _isMuted;
});
}
void Audio::setMuted(bool isMuted) {
if (_isMuted != isMuted) {
auto client = DependencyManager::get<AudioClient>().data();
QMetaObject::invokeMethod(client, "toggleMute");
bool changed = false;
withWriteLock([&] {
if (_isMuted != isMuted) {
_isMuted = isMuted;
auto client = DependencyManager::get<AudioClient>().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<AudioClient>()->isMuted();
if (_isMuted != isMuted) {
_isMuted = isMuted;
emit mutedChanged(_isMuted);
}
bool Audio::noiseReductionEnabled() const {
return resultWithReadLock<bool>([&] {
return _enableNoiseReduction;
});
}
void Audio::enableNoiseReduction(bool enable) {
if (_enableNoiseReduction != enable) {
auto client = DependencyManager::get<AudioClient>().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<AudioClient>().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<AudioClient>()->isNoiseReductionEnabled();
if (_enableNoiseReduction != noiseReductionEnabled) {
_enableNoiseReduction = noiseReductionEnabled;
emit noiseReductionChanged(_enableNoiseReduction);
}
float Audio::getInputVolume() const {
return resultWithReadLock<bool>([&] {
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<AudioClient>().data();
QMetaObject::invokeMethod(client, "setInputVolume", Q_ARG(float, volume));
bool changed = false;
withWriteLock([&] {
if (_inputVolume != volume) {
_inputVolume = volume;
auto client = DependencyManager::get<AudioClient>().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<bool>([&] {
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<QString>([&] {
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<AudioClient>()->setReverb(enable);
withWriteLock([&] {
DependencyManager::get<AudioClient>()->setReverb(enable);
});
}
void Audio::setReverbOptions(const AudioEffectOptions* options) {
DependencyManager::get<AudioClient>()->setReverbOptions(options);
withWriteLock([&] {
DependencyManager::get<AudioClient>()->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);
});
}

View file

@ -17,10 +17,11 @@
#include "AudioEffectOptions.h"
#include "SettingHandle.h"
#include "AudioFileWav.h"
#include <shared/ReadWriteLockable.h>
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:

View file

@ -757,7 +757,7 @@ void AudioClient::Gate::flush() {
void AudioClient::handleNoisyMutePacket(QSharedPointer<ReceivedMessage> 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());
}
}
}

View file

@ -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);