3 * Copyright (C) 2014 Team XBMC
6 * This Program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This Program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with XBMC; see the file COPYING. If not, see
18 * <http://www.gnu.org/licenses/>.
22 #include <Audioclient.h>
23 #include <mmdeviceapi.h>
24 #include "system.h" // for SAFE_RELEASE
25 #include "utils/log.h"
26 #include "cores/AudioEngine/AEFactory.h"
28 class CMMNotificationClient : public IMMNotificationClient
31 IMMDeviceEnumerator *_pEnumerator;
35 CMMNotificationClient() : _cRef(1), _pEnumerator(NULL)
39 ~CMMNotificationClient()
41 SAFE_RELEASE(_pEnumerator);
44 // IUnknown methods -- AddRef, Release, and QueryInterface
46 ULONG STDMETHODCALLTYPE AddRef()
48 return InterlockedIncrement(&_cRef);
51 ULONG STDMETHODCALLTYPE Release()
53 ULONG ulRef = InterlockedDecrement(&_cRef);
61 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID **ppvInterface)
63 if (IID_IUnknown == riid)
66 *ppvInterface = (IUnknown*)this;
68 else if (__uuidof(IMMNotificationClient) == riid)
71 *ppvInterface = (IMMNotificationClient*)this;
81 // Callback methods for device-event notifications.
83 HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId)
85 // if the default device changes this function is called four times.
86 // therefore we call CAEFactory::DeviceChange() only for one role.
87 char *pszFlow = "?????";
88 char *pszRole = "?????";
103 pszRole = "eConsole";
106 pszRole = "eMultimedia";
108 case eCommunications:
109 pszRole = "eCommunications";
110 CAEFactory::DeviceChange();
114 CLog::Log(LOGDEBUG, "%s: New default device: flow = %s, role = %s", __FUNCTION__, pszFlow, pszRole);
118 HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR pwstrDeviceId)
120 CLog::Log(LOGDEBUG, "%s: Added device: %s", __FUNCTION__, pwstrDeviceId);
121 CAEFactory::DeviceChange();
125 HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR pwstrDeviceId)
127 CLog::Log(LOGDEBUG, "%s: Removed device: %s", __FUNCTION__, pwstrDeviceId);
128 CAEFactory::DeviceChange();
132 HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState)
134 char *pszState = "?????";
138 case DEVICE_STATE_ACTIVE:
141 case DEVICE_STATE_DISABLED:
142 pszState = "DISABLED";
144 case DEVICE_STATE_NOTPRESENT:
145 pszState = "NOTPRESENT";
147 case DEVICE_STATE_UNPLUGGED:
148 pszState = "UNPLUGGED";
151 CLog::Log(LOGDEBUG, "%s: New device state is DEVICE_STATE_%s", __FUNCTION__, pszState);
152 CAEFactory::DeviceChange();
156 HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key)
158 CLog::Log(LOGDEBUG, "%s: Changed device property of %s is {%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x}#%d",
159 __FUNCTION__, pwstrDeviceId, key.fmtid.Data1, key.fmtid.Data2, key.fmtid.Data3,
160 key.fmtid.Data4[0], key.fmtid.Data4[1],
161 key.fmtid.Data4[2], key.fmtid.Data4[3],
162 key.fmtid.Data4[4], key.fmtid.Data4[5],
163 key.fmtid.Data4[6], key.fmtid.Data4[7],