From 8da0ab734e18e9d1bc4989b3cfc0353bc14f23a8 Mon Sep 17 00:00:00 2001 From: matzman666 Date: Wed, 15 Feb 2017 22:22:32 +0100 Subject: [PATCH] Fixed and improved audio device selection. --- bin/win64/res/qml/AudioPage.qml | 52 +++++++++++++++++++ src/tabcontrollers/AudioTabController.cpp | 24 ++++++--- src/tabcontrollers/AudioTabController.h | 9 ++-- .../audiomanager/AudioManagerWindows.cpp | 23 +++++++- .../audiomanager/AudioManagerWindows.h | 2 + 5 files changed, 96 insertions(+), 14 deletions(-) diff --git a/bin/win64/res/qml/AudioPage.qml b/bin/win64/res/qml/AudioPage.qml index 635da21..b12fccc 100644 --- a/bin/win64/res/qml/AudioPage.qml +++ b/bin/win64/res/qml/AudioPage.qml @@ -495,6 +495,58 @@ MyStackViewPage { onPttProfilesUpdated: { reloadPttProfiles() } + onPlaybackDeviceListChanged: { + var devs1 = [] + var devs2 = [""] + var playbackDeviceCount = AudioTabController.getPlaybackDeviceCount() + for (var i = 0; i < playbackDeviceCount; i++) { + var name = AudioTabController.getPlaybackDeviceName(i) + devs1.push(name) + devs2.push(name) + } + audioPlaybackNameCombo.model = devs1 + audioPlaybackNameCombo.currentIndex = AudioTabController.playbackDeviceIndex + audioMirrorNameCombo.model = devs2 + if (AudioTabController.mirrorDeviceIndex < 0) { + audioMirrorNameCombo.currentIndex = 0 + audioMirrorVolumeMinusButton.enabled = false + audioMirrorVolumeSlider.enabled = false + audioMirrorVolumePlusButton.enabled = false + audioMirrorMuteToggle.enabled = false + } else { + audioMirrorVolumeMinusButton.enabled = true + audioMirrorVolumeSlider.enabled = true + audioMirrorVolumePlusButton.enabled = true + audioMirrorMuteToggle.enabled = true + audioMirrorVolumeSlider.value = AudioTabController.mirrorVolume + audioMirrorMuteToggle.checked = AudioTabController.mirrorMuted + audioMirrorNameCombo.currentIndex = AudioTabController.mirrorDeviceIndex + 1 + } + } + onRecordingDeviceListChanged: { + var devs3 = [] + var micDeviceCount = AudioTabController.getRecordingDeviceCount() + for (var i = 0; i < micDeviceCount; i++) { + var name = AudioTabController.getRecordingDeviceName(i) + devs3.push(name) + } + audioMicNameCombo.model = devs3 + if (AudioTabController.micDeviceIndex < 0) { + audioMicNameCombo.currentIndex = 0 + audioMicVolumeMinusButton.enabled = false + audioMicVolumeSlider.enabled = false + audioMicVolumePlusButton.enabled = false + audioMicMuteToggle.enabled = false + } else { + audioMicVolumeMinusButton.enabled = true + audioMicVolumeSlider.enabled = true + audioMicVolumePlusButton.enabled = true + audioMicMuteToggle.enabled = true + audioMicVolumeSlider.value = AudioTabController.micVolume + audioMicMuteToggle.checked = AudioTabController.micMuted + audioMicNameCombo.currentIndex = AudioTabController.micDeviceIndex + } + } } } diff --git a/src/tabcontrollers/AudioTabController.cpp b/src/tabcontrollers/AudioTabController.cpp index e393970..18c8c93 100644 --- a/src/tabcontrollers/AudioTabController.cpp +++ b/src/tabcontrollers/AudioTabController.cpp @@ -192,12 +192,24 @@ namespace advsettings { } void AudioTabController::onNewMirrorDevice() { + auto devid = audioManager->getMirrorDevId(); + if (devid.empty()) { + m_mirrorDeviceIndex = -1; + emit mirrorDeviceIndexChanged(m_mirrorDeviceIndex); + } else { + findMirrorDeviceIndex(devid); + } } - void AudioTabController::onDeviceAdded() { - } - - void AudioTabController::onDeviceRemoved() { + void AudioTabController::onDeviceStateChanged() { + // I'm too lazy to find out which device has changed, so let's invalidate all device lists + m_playbackDevices = audioManager->getPlaybackDevices(); + m_recordingDevices = audioManager->getRecordingDevices(); + findPlaybackDeviceIndex(audioManager->getPlaybackDevId(), false); + findMirrorDeviceIndex(audioManager->getMirrorDevId(), false); + findMicDeviceIndex(audioManager->getMicDevId(), false); + emit playbackDeviceListChanged(); + emit recordingDeviceListChanged(); } int AudioTabController::getPlaybackDeviceCount() { @@ -275,7 +287,7 @@ namespace advsettings { audioManager->setMirrorDevice(m_playbackDevices[index].first, notify); } } else if (notify) { - emit mirrorDeviceIndexChanged(index); + emit mirrorDeviceIndexChanged(m_mirrorDeviceIndex); } } } @@ -292,7 +304,7 @@ namespace advsettings { audioManager->setMicDevice(m_recordingDevices[index].first, notify); } } else if (notify) { - emit micDeviceIndexChanged(index); + emit micDeviceIndexChanged(m_recordingDeviceIndex); } } } diff --git a/src/tabcontrollers/AudioTabController.h b/src/tabcontrollers/AudioTabController.h index 91ef998..73d26b8 100644 --- a/src/tabcontrollers/AudioTabController.h +++ b/src/tabcontrollers/AudioTabController.h @@ -36,14 +36,10 @@ namespace advsettings { int m_playbackDeviceIndex = -1; int m_mirrorDeviceIndex = -1; - //bool m_mirrorPresent = false; - //QString m_mirrorDevName = ""; float m_mirrorVolume = 1.0; bool m_mirrorMuted = false; int m_recordingDeviceIndex = -1; - //bool m_micPresent = false; - //QString m_micDevName = ""; float m_micVolume = 1.0; bool m_micMuted = false; @@ -91,8 +87,7 @@ namespace advsettings { void onNewRecordingDevice(); void onNewPlaybackDevice(); void onNewMirrorDevice(); - void onDeviceAdded(); - void onDeviceRemoved(); + void onDeviceStateChanged(); public slots: void setMirrorVolume(float value, bool notify = true); @@ -116,6 +111,8 @@ namespace advsettings { void micVolumeChanged(float value); void micMutedChanged(bool value); + void playbackDeviceListChanged(); + void recordingDeviceListChanged(); }; } // namespace advsettings diff --git a/src/tabcontrollers/audiomanager/AudioManagerWindows.cpp b/src/tabcontrollers/audiomanager/AudioManagerWindows.cpp index 4e62fb8..98c65aa 100644 --- a/src/tabcontrollers/audiomanager/AudioManagerWindows.cpp +++ b/src/tabcontrollers/audiomanager/AudioManagerWindows.cpp @@ -11,6 +11,7 @@ namespace advsettings { AudioManagerWindows::~AudioManagerWindows() { + std::lock_guard lock(_mutex); audioDeviceEnumerator->UnregisterEndpointNotificationCallback((IMMNotificationClient*)this); if (mirrorAudioEndpointVolume) { mirrorAudioEndpointVolume->Release(); @@ -31,6 +32,7 @@ AudioManagerWindows::~AudioManagerWindows() { } void AudioManagerWindows::init(AudioTabController* controller) { + std::lock_guard lock(_mutex); audioDeviceEnumerator = getAudioDeviceEnumerator(); if (!audioDeviceEnumerator) { throw std::exception("Could not create audio device enumerator"); @@ -54,6 +56,7 @@ void AudioManagerWindows::init(AudioTabController* controller) { } void AudioManagerWindows::setPlaybackDevice(const std::string & id, bool notify) { + std::lock_guard lock(_mutex); if (!id.empty()) { auto dev = getDevice(audioDeviceEnumerator, id); if (!dev) { @@ -74,6 +77,7 @@ void AudioManagerWindows::setPlaybackDevice(const std::string & id, bool notify) } std::string AudioManagerWindows::getPlaybackDevName() { + std::lock_guard lock(_mutex); if (playbackAudioDevice) { return getDeviceName(playbackAudioDevice); } @@ -81,6 +85,7 @@ std::string AudioManagerWindows::getPlaybackDevName() { } std::string AudioManagerWindows::getPlaybackDevId() { + std::lock_guard lock(_mutex); if (playbackAudioDevice) { return getDeviceId(playbackAudioDevice); } @@ -89,8 +94,12 @@ std::string AudioManagerWindows::getPlaybackDevId() { void AudioManagerWindows::setMirrorDevice(const std::string& id, bool notify) { + std::lock_guard lock(_mutex); if (id.empty()) { deleteMirrorDevice(); + if (notify) { + controller->onNewMirrorDevice(); + } } else { auto dev = getDevice(audioDeviceEnumerator, id); if (dev) { @@ -121,6 +130,7 @@ bool AudioManagerWindows::isMirrorValid() { } std::string AudioManagerWindows::getMirrorDevName() { + std::lock_guard lock(_mutex); if (mirrorAudioDevice) { return getDeviceName(mirrorAudioDevice); } @@ -128,6 +138,7 @@ std::string AudioManagerWindows::getMirrorDevName() { } std::string AudioManagerWindows::getMirrorDevId() { + std::lock_guard lock(_mutex); if (mirrorAudioDevice) { return getDeviceId(mirrorAudioDevice); } @@ -176,6 +187,7 @@ bool AudioManagerWindows::isMicValid() { } void AudioManagerWindows::setMicDevice(const std::string & id, bool notify) { + std::lock_guard lock(_mutex); if (!id.empty()) { auto dev = getDevice(audioDeviceEnumerator, id); if (!dev) { @@ -196,6 +208,7 @@ void AudioManagerWindows::setMicDevice(const std::string & id, bool notify) { } std::string AudioManagerWindows::getMicDevName() { + std::lock_guard lock(_mutex); if (micAudioDevice) { return getDeviceName(micAudioDevice); } @@ -203,6 +216,7 @@ std::string AudioManagerWindows::getMicDevName() { } std::string AudioManagerWindows::getMicDevId() { + std::lock_guard lock(_mutex); if (micAudioDevice) { return getDeviceId(micAudioDevice); } @@ -380,20 +394,25 @@ ULONG AudioManagerWindows::Release(void) { } HRESULT AudioManagerWindows::OnDeviceStateChanged(LPCWSTR, DWORD) { + std::lock_guard lock(_mutex); + controller->onDeviceStateChanged(); return S_OK; } HRESULT AudioManagerWindows::OnDeviceAdded(LPCWSTR) { - controller->onDeviceAdded(); + std::lock_guard lock(_mutex); + controller->onDeviceStateChanged(); return S_OK; } HRESULT AudioManagerWindows::OnDeviceRemoved(LPCWSTR) { - controller->onDeviceRemoved(); + std::lock_guard lock(_mutex); + controller->onDeviceStateChanged(); return S_OK; } HRESULT AudioManagerWindows::OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDefaultDeviceId) { + std::lock_guard lock(_mutex); if (flow == eCapture && role == eMultimedia) { if (audioDeviceEnumerator) { auto device = getDevice(audioDeviceEnumerator, pwstrDefaultDeviceId); diff --git a/src/tabcontrollers/audiomanager/AudioManagerWindows.h b/src/tabcontrollers/audiomanager/AudioManagerWindows.h index b380fd5..f0dba1a 100644 --- a/src/tabcontrollers/audiomanager/AudioManagerWindows.h +++ b/src/tabcontrollers/audiomanager/AudioManagerWindows.h @@ -6,6 +6,7 @@ #include #include #include "IPolicyConfig.h" +#include // application namespace @@ -14,6 +15,7 @@ namespace advsettings { class AudioManagerWindows : public AudioManager, IMMNotificationClient { friend class AudioNotificationClient; private: + std::recursive_mutex _mutex; AudioTabController* controller = nullptr; IMMDeviceEnumerator* audioDeviceEnumerator = nullptr; IMMDevice* playbackAudioDevice = nullptr;