From eec8c9a905540eafe318ec9f779efaa9d16ddd1a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alexander=20Steinh=C3=B6fer?= Date: Wed, 6 Apr 2022 16:20:52 +0200 Subject: [PATCH] Fixed crashes when audio endpoint changes. --- WinMute/MuteControl.cpp | 47 +++++++++++++++++++++++------------------ WinMute/MuteControl.h | 25 +++++++++++----------- WinMute/VistaAudio.cpp | 23 +++++++++----------- WinMute/WinAudio.h | 1 - WinMute/WinMute.cpp | 18 ++++++++++------ 5 files changed, 61 insertions(+), 53 deletions(-) diff --git a/WinMute/MuteControl.cpp b/WinMute/MuteControl.cpp index 484a622..af2b915 100644 --- a/WinMute/MuteControl.cpp +++ b/WinMute/MuteControl.cpp @@ -47,8 +47,7 @@ enum MuteType { MuteTypeCount // Meta }; -MuteControl::MuteControl() : - wasAlreadyMuted_(false) +MuteControl::MuteControl() { MuteConfig initMuteConf; initMuteConf.active = false; @@ -77,31 +76,33 @@ void MuteControl::SetMute(bool mute) winAudio_->SetMute(mute); } -void MuteControl::ConfigureWasAlreadyMuted() +void MuteControl::SaveMuteStatus() { - bool muteAlreadyActive = false; + bool alreadySaved = false; for (const auto& conf : muteConfig_) { if (conf.shouldMute && conf.active) { - muteAlreadyActive = true; + WMLog::GetInstance().Write(_T("Muting event already active. Skipping status save")); + alreadySaved = true; break; } } - /*if (!muteAlreadyActive && winAudio_->AllEndpointsMuted()) { - wasAlreadyMuted_ = true; - }*/ + if (!alreadySaved) { + WMLog::GetInstance().Write(_T("Saving mute status")); + winAudio_->SaveMuteStatus(); + } } void MuteControl::RestoreVolume() { WMLog& log = WMLog::GetInstance(); if (!restoreVolume_) { - log.Write(_T("Restore is FALSE")); + log.Write(_T("Volume Restore has been disabled")); return; } bool restore = true; for (const auto& conf : muteConfig_) { if (conf.shouldMute && conf.active) { - log.Write(_T("Entry found with ShouldMute: Yes and Active: Yes")); + log.Write(_T("Skipping restore since other mute event is currently active")); restore = false; break; } @@ -147,7 +148,6 @@ void MuteControl::SetMuteOnRemoteSession(bool enable) muteConfig_[MuteTypeRemoteSession].shouldMute = enable; } - void MuteControl::SetMuteOnDisplayStandby(bool enable) { muteConfig_[MuteTypeDisplayStandby].shouldMute = enable; @@ -196,16 +196,13 @@ bool MuteControl::GetMuteOnShutdown() void MuteControl::NotifyRestoreCondition(int type, bool active) { if (active) { - ConfigureWasAlreadyMuted(); + SaveMuteStatus(); muteConfig_[type].active = active; - WMLog::GetInstance().Write(_T("Condition {}: ACTIVE"), type); if (muteConfig_[type].shouldMute) { - WMLog::GetInstance().Write(_T("Mute: On")); - winAudio_->SaveMuteStatus(); + WMLog::GetInstance().Write(_T("Muting workstation")); winAudio_->SetMute(true); } } else { - WMLog::GetInstance().Write(_T("Condition {}: INACTIVE"), type); muteConfig_[type].active = active; RestoreVolume(); } @@ -213,26 +210,35 @@ void MuteControl::NotifyRestoreCondition(int type, bool active) void MuteControl::NotifyWorkstationLock(bool active) { + WMLog::GetInstance().Write(_T("Mute Event: Workstation Lock {}"), + active ? _T("start") : _T("stop")); NotifyRestoreCondition(MuteTypeWorkstationLock, active); } void MuteControl::NotifyScreensaver(bool active) { + WMLog::GetInstance().Write(_T("Mute Event: Screensaver {}"), + active ? _T("start") : _T("stop")); NotifyRestoreCondition(MuteTypeScreensaverActive, active); } void MuteControl::NotifyRemoteSession(bool active) { + WMLog::GetInstance().Write(_T("Mute Event: Remote Session {}"), + active ? _T("start") : _T("stop")); NotifyRestoreCondition(MuteTypeRemoteSession, active); } void MuteControl::NotifyDisplayStandby(bool active) { + WMLog::GetInstance().Write(_T("Mute Event: Display Standby {}"), + active ? _T("start") : _T("stop")); NotifyRestoreCondition(MuteTypeDisplayStandby, active); } void MuteControl::NotifyLogout() { + WMLog::GetInstance().Write(_T("Mute Event: Logout start")); if (muteConfig_[MuteTypeLogout].shouldMute) { winAudio_->SetMute(true); } @@ -240,7 +246,7 @@ void MuteControl::NotifyLogout() void MuteControl::NotifySuspend(bool /*active*/) { - WMLog::GetInstance().Write(_T("Suspend: START")); + WMLog::GetInstance().Write(_T("Mute Event: Suspend start")); if (muteConfig_[MuteTypeSuspend].shouldMute) { winAudio_->SetMute(true); } @@ -248,6 +254,7 @@ void MuteControl::NotifySuspend(bool /*active*/) void MuteControl::NotifyShutdown() { + WMLog::GetInstance().Write(_T("Mute Event: Shutdown start")); if (muteConfig_[MuteTypeShutdown].shouldMute) { winAudio_->SetMute(true); } @@ -256,12 +263,12 @@ void MuteControl::NotifyShutdown() void MuteControl::NotifyQuietHours(bool active) { if (active) { - ConfigureWasAlreadyMuted(); - WMLog::GetInstance().Write(L"Quiet Hours startet"); + SaveMuteStatus(); + WMLog::GetInstance().Write(L"Mute Event: Quiet Hours startet"); winAudio_->SaveMuteStatus(); winAudio_->SetMute(true); } else { - WMLog::GetInstance().Write(L"Quiet Hours ended"); + WMLog::GetInstance().Write(L"Mute Event: Quiet Hours ended"); RestoreVolume(); } } diff --git a/WinMute/MuteControl.h b/WinMute/MuteControl.h index 6f059fc..4e62a1d 100644 --- a/WinMute/MuteControl.h +++ b/WinMute/MuteControl.h @@ -36,18 +36,6 @@ POSSIBILITY OF SUCH DAMAGE. #include "common.h" class MuteControl { - struct MuteConfig { - bool shouldMute; - bool active; - }; - std::vector muteConfig_; - bool wasAlreadyMuted_; - bool restoreVolume_; - std::unique_ptr winAudio_; - - void NotifyRestoreCondition(int type, bool active); - void ConfigureWasAlreadyMuted(); - void RestoreVolume(); public: MuteControl(); ~MuteControl(); @@ -90,4 +78,17 @@ public: void NotifyShutdown(); void NotifyQuietHours(bool active); +private: + struct MuteConfig { + bool shouldMute; + bool active; + }; + std::vector muteConfig_; + bool restoreVolume_; + std::unique_ptr winAudio_; + + void NotifyRestoreCondition(int type, bool active); + void SaveMuteStatus(); + void RestoreVolume(); + }; diff --git a/WinMute/VistaAudio.cpp b/WinMute/VistaAudio.cpp index f1953ab..8518525 100644 --- a/WinMute/VistaAudio.cpp +++ b/WinMute/VistaAudio.cpp @@ -61,7 +61,6 @@ VistaAudio::VistaAudio() : deviceEnumerator_(nullptr), mmnAudioEvents_(nullptr), reInit_(false), - oldVolume_(0), hParent_(nullptr) { if (FAILED(CoInitialize(nullptr))) { @@ -133,8 +132,7 @@ bool VistaAudio::LoadAllEndpoints() continue; } - IAudioSessionControlPtr sessionCtrl; - hr = sessionManager2->GetAudioSessionControl(nullptr, 0, &sessionCtrl); + hr = sessionManager2->GetAudioSessionControl(nullptr, 0, &ep->sessionCtrl); if (FAILED(hr)) { log.Write(_T("Failed to retrieve audio session manager for {}"), ep->deviceName); @@ -143,11 +141,13 @@ bool VistaAudio::LoadAllEndpoints() ep->wasapiAudioEvents = std::make_unique(this); if (ep->wasapiAudioEvents) { - sessionCtrl->RegisterAudioSessionNotification(ep->wasapiAudioEvents.get()); + ep->sessionCtrl->RegisterAudioSessionNotification( + ep->wasapiAudioEvents.get()); } - hr = device->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, - nullptr, reinterpret_cast(&ep->endpointVolume)); + hr = device->Activate( + __uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, + nullptr, reinterpret_cast(&ep->endpointVolume)); if (FAILED(hr)) { log.Write(_T("Failed to active endpoint volume for device {}"), ep->deviceName); @@ -168,11 +168,10 @@ bool VistaAudio::Init(HWND hParent) hParent_ = hParent; reInit_ = false; - if (FAILED(CoCreateInstance( + if (FAILED(deviceEnumerator_.CreateInstance( __uuidof(MMDeviceEnumerator), nullptr, - CLSCTX_INPROC_SERVER, - IID_PPV_ARGS(&deviceEnumerator_)))) { + CLSCTX_INPROC_SERVER))) { log.Write(_T("Failed to create instance of MMDeviceEnumerator")); return false; } @@ -192,10 +191,8 @@ void VistaAudio::Uninit() if (deviceEnumerator_ && mmnAudioEvents_) { deviceEnumerator_->UnregisterEndpointNotificationCallback(mmnAudioEvents_); } - deviceEnumerator_->Release(); - + deviceEnumerator_.Release(); SafeRelease(&mmnAudioEvents_); - SafeRelease(&deviceEnumerator_); endpoints_.clear(); } @@ -263,7 +260,7 @@ bool VistaAudio::RestoreMuteStatus() WMLog& log = WMLog::GetInstance(); for (auto& e : endpoints_) { - log.Write(_T("Restoring: Mute {} for device \"{}\""), + log.Write(_T("Restoring: Mute {} for \"{}\""), e->wasMuted, e->deviceName); if (e->wasMuted != true) { if (FAILED(e->endpointVolume->SetMute(false, nullptr))) { diff --git a/WinMute/WinAudio.h b/WinMute/WinAudio.h index a8a5726..73147b0 100644 --- a/WinMute/WinAudio.h +++ b/WinMute/WinAudio.h @@ -90,7 +90,6 @@ private: IMMDeviceEnumeratorPtr deviceEnumerator_; bool reInit_; - float oldVolume_; HWND hParent_; // non copy-able diff --git a/WinMute/WinMute.cpp b/WinMute/WinMute.cpp index 1bff773..8a9e31a 100644 --- a/WinMute/WinMute.cpp +++ b/WinMute/WinMute.cpp @@ -145,13 +145,6 @@ bool WinMute::InitWindow() bool WinMute::InitAudio() { -#ifdef _DEBUG - WMLog::GetInstance().SetEnabled(true); -#else - WMLog::GetInstance().SetEnabled(settings_.QueryValue(LOGGING_ENABLED, 0)); -#endif - - if (IsWindowsVistaOrGreater()) { // Nothing to do } else if (IsWindowsXPOrGreater()) { @@ -195,6 +188,8 @@ bool WinMute::InitTrayMenu() bool WinMute::Init() { + WMLog& log = WMLog::GetInstance(); + hAppIcon_ = LoadIcon(hglobInstance, MAKEINTRESOURCE(IDI_APP)); if (!settings_.Init() || @@ -202,6 +197,13 @@ bool WinMute::Init() return false; } +#ifdef _DEBUG + WMLog::GetInstance().SetEnabled(true); +#else + WMLog::GetInstance().SetEnabled(settings_.QueryValue(LOGGING_ENABLED, 0)); +#endif + log.Write(_T("Starting new session...")); + if (!RegisterWindowClass() || !InitWindow() || !InitTrayMenu()) { @@ -241,6 +243,8 @@ bool WinMute::Init() ResetQuietHours(); + log.Write(_T("WinMute initialized")); + return true; } -- 2.43.0