Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/sanear.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntoine Aflalo <antoine@aaflalo.me>2015-09-08 13:36:56 +0300
committerAntoine Aflalo <antoine@aaflalo.me>2015-09-08 14:19:02 +0300
commitae77a37ba10fa2d1caa6b3960aff80891a58125e (patch)
tree8ef89b25072800e0f9035cda157ab00a1af6c583
parent8afb5197935386ebee8b8c7380190041c3caaa82 (diff)
Make Sanear listen to Default Audio Change.
-rw-r--r--dll/src/sanear-dll/OuterFilter.cpp14
-rw-r--r--dll/src/sanear-dll/OuterFilter.h2
-rw-r--r--sanear.vcxproj2
-rw-r--r--sanear.vcxproj.filters6
-rw-r--r--src/Factory.cpp32
-rw-r--r--src/Factory.h3
-rw-r--r--src/MMNotificationClient.cpp99
-rw-r--r--src/MMNotificationClient.h28
8 files changed, 186 insertions, 0 deletions
diff --git a/dll/src/sanear-dll/OuterFilter.cpp b/dll/src/sanear-dll/OuterFilter.cpp
index fdd6b73..9daeb19 100644
--- a/dll/src/sanear-dll/OuterFilter.cpp
+++ b/dll/src/sanear-dll/OuterFilter.cpp
@@ -46,6 +46,13 @@ namespace SaneAudioRenderer
m_settings->GetCrossfeedSettings(&uintValue1, &uintValue2);
m_registryKey.SetUint(CrossfeedCutoffFrequency, uintValue1);
m_registryKey.SetUint(CrossfeedLevel, uintValue2);
+
+ //Unregister Notifications
+ IMMDeviceEnumeratorPtr pDeviceEnumerator;
+ if (SUCCEEDED(pDeviceEnumerator.CreateInstance(__uuidof(MMDeviceEnumerator))))
+ {
+ pDeviceEnumerator->UnregisterEndpointNotificationCallback(m_notification);
+ }
}
STDMETHODIMP OuterFilter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
@@ -70,6 +77,13 @@ namespace SaneAudioRenderer
ReturnIfFailed(Factory::CreateFilterAggregated(GetOwner(), m_guid, m_settings, &m_innerFilter));
ReturnIfFailed(m_registryKey.Open(HKEY_CURRENT_USER, L"Software\\sanear"));
ReturnIfFailed(m_trayWindow.Init(m_settings));
+ ReturnIfFailed(Factory::CreateNotificationClient(m_settings, &m_notification));
+
+ //Register Notifications
+ IMMDeviceEnumeratorPtr pDeviceEnumerator;
+ ReturnIfFailed(pDeviceEnumerator.CreateInstance(__uuidof(MMDeviceEnumerator)));
+
+ pDeviceEnumerator->RegisterEndpointNotificationCallback(m_notification);
m_initialized = true;
diff --git a/dll/src/sanear-dll/OuterFilter.h b/dll/src/sanear-dll/OuterFilter.h
index cf4de20..e5ec79d 100644
--- a/dll/src/sanear-dll/OuterFilter.h
+++ b/dll/src/sanear-dll/OuterFilter.h
@@ -4,6 +4,7 @@
#include "TrayWindow.h"
#include "../../../src/Interfaces.h"
+#include "../../../src/MMNotificationClient.h"
namespace SaneAudioRenderer
{
@@ -31,5 +32,6 @@ namespace SaneAudioRenderer
ISettingsPtr m_settings;
IUnknownPtr m_innerFilter;
TrayWindow m_trayWindow;
+ IMMNotificationClientPtr m_notification;
};
}
diff --git a/sanear.vcxproj b/sanear.vcxproj
index eb6d000..bb7fa47 100644
--- a/sanear.vcxproj
+++ b/sanear.vcxproj
@@ -113,6 +113,7 @@
<ClInclude Include="src\DspRealtimeRate.h" />
<ClInclude Include="src\DspVolume.h" />
<ClInclude Include="src\Interfaces.h" />
+ <ClInclude Include="src\MMNotificationClient.h" />
<ClInclude Include="src\MyBasicAudio.h" />
<ClInclude Include="src\MyPropertyPage.h" />
<ClInclude Include="src\MyTestClock.h" />
@@ -138,6 +139,7 @@
<ClCompile Include="src\DspTempo.cpp" />
<ClCompile Include="src\DspRealtimeRate.cpp" />
<ClCompile Include="src\DspVolume.cpp" />
+ <ClCompile Include="src\MMNotificationClient.cpp" />
<ClCompile Include="src\MyBasicAudio.cpp" />
<ClCompile Include="src\MyFilter.cpp" />
<ClCompile Include="src\MyClock.cpp" />
diff --git a/sanear.vcxproj.filters b/sanear.vcxproj.filters
index aa707a8..4cb7f94 100644
--- a/sanear.vcxproj.filters
+++ b/sanear.vcxproj.filters
@@ -68,6 +68,9 @@
<ClCompile Include="src\DspRealtimeRate.cpp">
<Filter>Processors</Filter>
</ClCompile>
+ <ClCompile Include="src\MMNotificationClient.cpp">
+ <Filter>Renderer</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\DspMatrix.h">
@@ -147,6 +150,9 @@
<ClInclude Include="src\DspRealtimeRate.h">
<Filter>Processors</Filter>
</ClInclude>
+ <ClInclude Include="src\MMNotificationClient.h">
+ <Filter>Renderer</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="DirectShow">
diff --git a/src/Factory.cpp b/src/Factory.cpp
index a93ebf7..12d2db4 100644
--- a/src/Factory.cpp
+++ b/src/Factory.cpp
@@ -3,6 +3,7 @@
#include "MyFilter.h"
#include "Settings.h"
+#include "MMNotificationClient.h"
namespace SaneAudioRenderer
{
@@ -33,6 +34,37 @@ namespace SaneAudioRenderer
return result;
}
+ HRESULT Factory::CreateNotificationClient(ISettings* pSettings, IMMNotificationClient** ppOut)
+ {
+ IUnknownPtr unknown;
+ ReturnIfFailed(CreateNotificationClientAggregated(pSettings, &unknown));
+ return unknown->QueryInterface(IID_PPV_ARGS(ppOut));
+ }
+
+ HRESULT Factory::CreateNotificationClientAggregated(ISettings* pSettings, IUnknown** ppOut)
+ {
+ CheckPointer(ppOut, E_POINTER);
+ CheckPointer(pSettings, E_POINTER);
+
+ *ppOut = nullptr;
+
+ auto pNotifclient = new(std::nothrow) CMMNotificationClient;
+
+ if (!pNotifclient)
+ return E_OUTOFMEMORY;
+
+ pNotifclient->AddRef();
+
+ HRESULT result = pNotifclient->Init(pSettings);
+
+ if (SUCCEEDED(result))
+ result = pNotifclient->QueryInterface(IID_PPV_ARGS(ppOut));
+
+ pNotifclient->Release();
+
+ return result;
+ }
+
HRESULT Factory::CreateFilter(ISettings* pSettings, IBaseFilter** ppOut)
{
IUnknownPtr unknown;
diff --git a/src/Factory.h b/src/Factory.h
index 178620b..d12cc5d 100644
--- a/src/Factory.h
+++ b/src/Factory.h
@@ -16,6 +16,9 @@ namespace SaneAudioRenderer
static HRESULT CreateSettings(ISettings** ppOut);
static HRESULT CreateSettingsAggregated(IUnknown* pOwner, IUnknown** ppOut);
+ static HRESULT CreateNotificationClient(__in ISettings* pSettings, __out IMMNotificationClient** ppOut);
+ static HRESULT CreateNotificationClientAggregated(__in ISettings* pSettings, __out IUnknown** ppOut);
+
static HRESULT CreateFilter(ISettings* pSettings, IBaseFilter** ppOut);
static HRESULT CreateFilterAggregated(IUnknown* pOwner, const GUID& guid,
ISettings* pSettings, IUnknown** ppOut);
diff --git a/src/MMNotificationClient.cpp b/src/MMNotificationClient.cpp
new file mode 100644
index 0000000..d8cb896
--- /dev/null
+++ b/src/MMNotificationClient.cpp
@@ -0,0 +1,99 @@
+#include "pch.h"
+#include "MMNotificationClient.h"
+
+namespace SaneAudioRenderer
+{
+ HRESULT CMMNotificationClient::QueryInterface(const IID& riid, void** ppvInterface)
+ {
+ if (IID_IUnknown == riid)
+ {
+ AddRef();
+ *ppvInterface = static_cast<IUnknown*>(this);
+ }
+ else if (__uuidof(IMMNotificationClient) == riid)
+ {
+ AddRef();
+ *ppvInterface = static_cast<IMMNotificationClient*>(this);
+ }
+ else
+ {
+ *ppvInterface = nullptr;
+ return E_NOINTERFACE;
+ }
+ return S_OK;
+ }
+
+ ULONG CMMNotificationClient::AddRef()
+ {
+ return InterlockedIncrement(&m_cRef);
+ }
+
+ ULONG CMMNotificationClient::Release()
+ {
+ ULONG ulRef = InterlockedDecrement(&m_cRef);
+ if (0 == ulRef)
+ {
+ delete this;
+ }
+ return ulRef;
+ }
+
+ HRESULT CMMNotificationClient::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState)
+ {
+ return S_OK;
+ }
+
+ HRESULT CMMNotificationClient::OnDeviceAdded(LPCWSTR pwstrDeviceId)
+ {
+ return S_OK;
+ }
+
+ HRESULT CMMNotificationClient::OnDeviceRemoved(LPCWSTR pwstrDeviceId)
+ {
+ return S_OK;
+ }
+
+ HRESULT CMMNotificationClient::OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDefaultDeviceId)
+ {
+ //Not interested in Recording devices
+ if (flow == eCapture)
+ return S_FALSE;
+ //Not interested in Communications devices, only Multimedia and Console
+ if (role == ::eCommunications)
+ return S_FALSE;
+
+ LPWSTR pDeviceId = nullptr;
+ BOOL exclusive;
+ UINT32 buffer;
+ m_settings->GetOuputDevice(&pDeviceId, &exclusive, &buffer);
+ std::unique_ptr<WCHAR, CoTaskMemFreeDeleter> holder(pDeviceId);
+
+ if (!pDeviceId || pwstrDefaultDeviceId != pDeviceId)
+ {
+ m_settings->SetOuputDevice(pwstrDefaultDeviceId, exclusive, buffer);
+ return S_OK;
+ }
+ return S_FALSE;
+ }
+
+ HRESULT CMMNotificationClient::OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key)
+ {
+ return S_OK;
+ }
+
+ HRESULT CMMNotificationClient::Init(ISettings* pSettings)
+ {
+ CheckPointer(pSettings, E_POINTER);
+ ReturnIfFailed(pSettings->QueryInterface(IID_PPV_ARGS(&m_settings)));
+ return S_OK;
+ }
+
+ CMMNotificationClient::CMMNotificationClient() : m_cRef(0)
+ {
+ }
+
+
+ CMMNotificationClient::~CMMNotificationClient()
+ {
+ }
+}
diff --git a/src/MMNotificationClient.h b/src/MMNotificationClient.h
new file mode 100644
index 0000000..349657a
--- /dev/null
+++ b/src/MMNotificationClient.h
@@ -0,0 +1,28 @@
+#pragma once
+#include <comdef.h>
+#include "../../../src/Settings.h"
+
+namespace SaneAudioRenderer
+{
+ _COM_SMARTPTR_TYPEDEF(IMMDeviceEnumerator, __uuidof(IMMDeviceEnumerator));
+ _COM_SMARTPTR_TYPEDEF(IMMNotificationClient, __uuidof(IMMNotificationClient));
+
+ class CMMNotificationClient : public IMMNotificationClient
+ {
+ public:
+ HRESULT STDMETHODCALLTYPE QueryInterface(const IID& riid, void** ppvObject) override;
+ ULONG STDMETHODCALLTYPE AddRef() override;
+ ULONG STDMETHODCALLTYPE Release() override;
+ HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState) override;
+ HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR pwstrDeviceId) override;
+ HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR pwstrDeviceId) override;
+ HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDefaultDeviceId) override;
+ HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key) override;
+ HRESULT Init(ISettings* pSettings);
+ CMMNotificationClient();
+ virtual ~CMMNotificationClient();
+ private:
+ LONG m_cRef;
+ ISettingsPtr m_settings;
+ };
+}