VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/DrvHostAudioDSoundMMNotifClient.cpp@ 88799

Last change on this file since 88799 was 88361, checked in by vboxsync, 4 years ago

DrvHostAudioDSound: Converted to use PDMIAUDIONOTIFYFROMHOST. bugref:9890

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.0 KB
Line 
1/* $Id: DrvHostAudioDSoundMMNotifClient.cpp 88361 2021-04-05 00:23:47Z vboxsync $ */
2/** @file
3 * Host audio driver - DSound - Implementation of the IMMNotificationClient interface to detect audio endpoint changes.
4 */
5
6/*
7 * Copyright (C) 2017-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include "DrvHostAudioDSoundMMNotifClient.h"
19
20#include <iprt/win/windows.h>
21#include <mmdeviceapi.h>
22#include <iprt/win/endpointvolume.h>
23#include <iprt/errcore.h>
24
25#ifdef LOG_GROUP /** @todo r=bird: wtf? Put it before all other includes like you're supposed to. */
26# undef LOG_GROUP
27#endif
28#define LOG_GROUP LOG_GROUP_DRV_HOST_AUDIO
29#include <VBox/log.h>
30
31
32DrvHostAudioDSoundMMNotifClient::DrvHostAudioDSoundMMNotifClient(PPDMIAUDIONOTIFYFROMHOST pInterface)
33 : m_fRegisteredClient(false)
34 , m_cRef(1)
35 , m_pIAudioNotifyFromHost(pInterface)
36{
37}
38
39DrvHostAudioDSoundMMNotifClient::~DrvHostAudioDSoundMMNotifClient(void)
40{
41}
42
43/**
44 * Registers the mulitmedia notification client implementation.
45 */
46HRESULT DrvHostAudioDSoundMMNotifClient::Register(void)
47{
48 HRESULT hr = m_pEnum->RegisterEndpointNotificationCallback(this);
49 if (SUCCEEDED(hr))
50 {
51 m_fRegisteredClient = true;
52
53 hr = AttachToDefaultEndpoint();
54 }
55
56 return hr;
57}
58
59/**
60 * Unregisters the mulitmedia notification client implementation.
61 */
62void DrvHostAudioDSoundMMNotifClient::Unregister(void)
63{
64 DetachFromEndpoint();
65
66 if (m_fRegisteredClient)
67 {
68 m_pEnum->UnregisterEndpointNotificationCallback(this);
69
70 m_fRegisteredClient = false;
71 }
72}
73
74/**
75 * Initializes the mulitmedia notification client implementation.
76 *
77 * @return HRESULT
78 */
79HRESULT DrvHostAudioDSoundMMNotifClient::Initialize(void)
80{
81 HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), 0, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),
82 (void **)&m_pEnum);
83
84 LogFunc(("Returning %Rhrc\n", hr));
85 return hr;
86}
87
88/**
89 * Stub being called when attaching to the default audio endpoint.
90 * Does nothing at the moment.
91 */
92HRESULT DrvHostAudioDSoundMMNotifClient::AttachToDefaultEndpoint(void)
93{
94 return S_OK;
95}
96
97/**
98 * Stub being called when detaching from the default audio endpoint.
99 * Does nothing at the moment.
100 */
101void DrvHostAudioDSoundMMNotifClient::DetachFromEndpoint(void)
102{
103
104}
105
106/**
107 * Helper function for invoking the audio connector callback (if any).
108 */
109void DrvHostAudioDSoundMMNotifClient::doCallback(void)
110{
111 if (m_pIAudioNotifyFromHost)
112 m_pIAudioNotifyFromHost->pfnNotifyDevicesChanged(m_pIAudioNotifyFromHost);
113}
114
115/**
116 * Handler implementation which is called when an audio device state
117 * has been changed.
118 *
119 * @return HRESULT
120 * @param pwstrDeviceId Device ID the state is announced for.
121 * @param dwNewState New state the device is now in.
122 */
123STDMETHODIMP DrvHostAudioDSoundMMNotifClient::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState)
124{
125 char *pszState = "unknown";
126
127 switch (dwNewState)
128 {
129 case DEVICE_STATE_ACTIVE:
130 pszState = "active";
131 break;
132 case DEVICE_STATE_DISABLED:
133 pszState = "disabled";
134 break;
135 case DEVICE_STATE_NOTPRESENT:
136 pszState = "not present";
137 break;
138 case DEVICE_STATE_UNPLUGGED:
139 pszState = "unplugged";
140 break;
141 default:
142 break;
143 }
144
145 LogRel(("Audio: Device '%ls' has changed state to '%s'\n", pwstrDeviceId, pszState));
146
147 doCallback();
148
149 return S_OK;
150}
151
152/**
153 * Handler implementation which is called when a new audio device has been added.
154 *
155 * @return HRESULT
156 * @param pwstrDeviceId Device ID which has been added.
157 */
158STDMETHODIMP DrvHostAudioDSoundMMNotifClient::OnDeviceAdded(LPCWSTR pwstrDeviceId)
159{
160 LogRel(("Audio: Device '%ls' has been added\n", pwstrDeviceId));
161
162 return S_OK;
163}
164
165/**
166 * Handler implementation which is called when an audio device has been removed.
167 *
168 * @return HRESULT
169 * @param pwstrDeviceId Device ID which has been removed.
170 */
171STDMETHODIMP DrvHostAudioDSoundMMNotifClient::OnDeviceRemoved(LPCWSTR pwstrDeviceId)
172{
173 LogRel(("Audio: Device '%ls' has been removed\n", pwstrDeviceId));
174
175 return S_OK;
176}
177
178/**
179 * Handler implementation which is called when the device audio device has been
180 * changed.
181 *
182 * @return HRESULT
183 * @param eFlow Flow direction of the new default device.
184 * @param eRole Role of the new default device.
185 * @param pwstrDefaultDeviceId ID of the new default device.
186 */
187STDMETHODIMP DrvHostAudioDSoundMMNotifClient::OnDefaultDeviceChanged(EDataFlow eFlow, ERole eRole, LPCWSTR pwstrDefaultDeviceId)
188{
189 RT_NOREF(eRole);
190
191 char *pszRole = "unknown";
192
193 if (eFlow == eRender)
194 pszRole = "output";
195 else if (eFlow == eCapture)
196 pszRole = "input";
197
198 LogRel(("Audio: Default %s device has been changed to '%ls'\n", pszRole, pwstrDefaultDeviceId));
199
200 doCallback();
201
202 return S_OK;
203}
204
205STDMETHODIMP DrvHostAudioDSoundMMNotifClient::QueryInterface(REFIID interfaceID, void **ppvInterface)
206{
207 const IID MY_IID_IMMNotificationClient = __uuidof(IMMNotificationClient);
208
209 if ( IsEqualIID(interfaceID, IID_IUnknown)
210 || IsEqualIID(interfaceID, MY_IID_IMMNotificationClient))
211 {
212 *ppvInterface = static_cast<IMMNotificationClient*>(this);
213 AddRef();
214 return S_OK;
215 }
216
217 *ppvInterface = NULL;
218 return E_NOINTERFACE;
219}
220
221STDMETHODIMP_(ULONG) DrvHostAudioDSoundMMNotifClient::AddRef(void)
222{
223 return InterlockedIncrement(&m_cRef);
224}
225
226STDMETHODIMP_(ULONG) DrvHostAudioDSoundMMNotifClient::Release(void)
227{
228 long lRef = InterlockedDecrement(&m_cRef);
229 if (lRef == 0)
230 delete this;
231
232 return lRef;
233}
234
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette