2 * Copyright 2010 Maarten Lankhorst for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/debug.h"
30 #include "mmdeviceapi.h"
33 #include "audioclient.h"
34 #include "endpointvolume.h"
35 #include "audiopolicy.h"
36 #include "spatialaudioclient.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi
);
42 typedef struct AEVImpl
{
43 IAudioEndpointVolumeEx IAudioEndpointVolumeEx_iface
;
49 static inline AEVImpl
*impl_from_IAudioEndpointVolumeEx(IAudioEndpointVolumeEx
*iface
)
51 return CONTAINING_RECORD(iface
, AEVImpl
, IAudioEndpointVolumeEx_iface
);
54 static void AudioEndpointVolume_Destroy(AEVImpl
*This
)
56 HeapFree(GetProcessHeap(), 0, This
);
59 static HRESULT WINAPI
AEV_QueryInterface(IAudioEndpointVolumeEx
*iface
, REFIID riid
, void **ppv
)
61 AEVImpl
*This
= impl_from_IAudioEndpointVolumeEx(iface
);
62 TRACE("(%p)->(%s,%p)\n", This
, debugstr_guid(riid
), ppv
);
66 if (IsEqualIID(riid
, &IID_IUnknown
) ||
67 IsEqualIID(riid
, &IID_IAudioEndpointVolume
) ||
68 IsEqualIID(riid
, &IID_IAudioEndpointVolumeEx
)) {
69 *ppv
= &This
->IAudioEndpointVolumeEx_iface
;
73 IUnknown_AddRef((IUnknown
*)*ppv
);
77 static ULONG WINAPI
AEV_AddRef(IAudioEndpointVolumeEx
*iface
)
79 AEVImpl
*This
= impl_from_IAudioEndpointVolumeEx(iface
);
80 ULONG ref
= InterlockedIncrement(&This
->ref
);
81 TRACE("(%p) new ref %u\n", This
, ref
);
85 static ULONG WINAPI
AEV_Release(IAudioEndpointVolumeEx
*iface
)
87 AEVImpl
*This
= impl_from_IAudioEndpointVolumeEx(iface
);
88 ULONG ref
= InterlockedDecrement(&This
->ref
);
89 TRACE("(%p) new ref %u\n", This
, ref
);
91 AudioEndpointVolume_Destroy(This
);
95 static HRESULT WINAPI
AEV_RegisterControlChangeNotify(IAudioEndpointVolumeEx
*iface
, IAudioEndpointVolumeCallback
*notify
)
97 TRACE("(%p)->(%p)\n", iface
, notify
);
104 static HRESULT WINAPI
AEV_UnregisterControlChangeNotify(IAudioEndpointVolumeEx
*iface
, IAudioEndpointVolumeCallback
*notify
)
106 TRACE("(%p)->(%p)\n", iface
, notify
);
113 static HRESULT WINAPI
AEV_GetChannelCount(IAudioEndpointVolumeEx
*iface
, UINT
*count
)
115 TRACE("(%p)->(%p)\n", iface
, count
);
122 static HRESULT WINAPI
AEV_SetMasterVolumeLevel(IAudioEndpointVolumeEx
*iface
, float leveldb
, const GUID
*ctx
)
124 AEVImpl
*This
= impl_from_IAudioEndpointVolumeEx(iface
);
126 TRACE("(%p)->(%f,%s)\n", iface
, leveldb
, debugstr_guid(ctx
));
128 if(leveldb
< -100.f
|| leveldb
> 0.f
)
131 This
->master_vol
= leveldb
;
136 static HRESULT WINAPI
AEV_SetMasterVolumeLevelScalar(IAudioEndpointVolumeEx
*iface
, float level
, const GUID
*ctx
)
138 TRACE("(%p)->(%f,%s)\n", iface
, level
, debugstr_guid(ctx
));
143 static HRESULT WINAPI
AEV_GetMasterVolumeLevel(IAudioEndpointVolumeEx
*iface
, float *leveldb
)
145 AEVImpl
*This
= impl_from_IAudioEndpointVolumeEx(iface
);
147 TRACE("(%p)->(%p)\n", iface
, leveldb
);
152 *leveldb
= This
->master_vol
;
157 static HRESULT WINAPI
AEV_GetMasterVolumeLevelScalar(IAudioEndpointVolumeEx
*iface
, float *level
)
159 TRACE("(%p)->(%p)\n", iface
, level
);
167 static HRESULT WINAPI
AEV_SetChannelVolumeLevel(IAudioEndpointVolumeEx
*iface
, UINT chan
, float leveldb
, const GUID
*ctx
)
169 TRACE("(%p)->(%f,%s)\n", iface
, leveldb
, debugstr_guid(ctx
));
174 static HRESULT WINAPI
AEV_SetChannelVolumeLevelScalar(IAudioEndpointVolumeEx
*iface
, UINT chan
, float level
, const GUID
*ctx
)
176 TRACE("(%p)->(%u,%f,%s)\n", iface
, chan
, level
, debugstr_guid(ctx
));
181 static HRESULT WINAPI
AEV_GetChannelVolumeLevel(IAudioEndpointVolumeEx
*iface
, UINT chan
, float *leveldb
)
183 TRACE("(%p)->(%u,%p)\n", iface
, chan
, leveldb
);
190 static HRESULT WINAPI
AEV_GetChannelVolumeLevelScalar(IAudioEndpointVolumeEx
*iface
, UINT chan
, float *level
)
192 TRACE("(%p)->(%u,%p)\n", iface
, chan
, level
);
199 static HRESULT WINAPI
AEV_SetMute(IAudioEndpointVolumeEx
*iface
, BOOL mute
, const GUID
*ctx
)
201 AEVImpl
*This
= impl_from_IAudioEndpointVolumeEx(iface
);
204 TRACE("(%p)->(%u,%s)\n", iface
, mute
, debugstr_guid(ctx
));
206 ret
= This
->mute
== mute
? S_FALSE
: S_OK
;
213 static HRESULT WINAPI
AEV_GetMute(IAudioEndpointVolumeEx
*iface
, BOOL
*mute
)
215 AEVImpl
*This
= impl_from_IAudioEndpointVolumeEx(iface
);
217 TRACE("(%p)->(%p)\n", iface
, mute
);
227 static HRESULT WINAPI
AEV_GetVolumeStepInfo(IAudioEndpointVolumeEx
*iface
, UINT
*stepsize
, UINT
*stepcount
)
229 TRACE("(%p)->(%p,%p)\n", iface
, stepsize
, stepcount
);
230 if (!stepsize
&& !stepcount
)
236 static HRESULT WINAPI
AEV_VolumeStepUp(IAudioEndpointVolumeEx
*iface
, const GUID
*ctx
)
238 TRACE("(%p)->(%s)\n", iface
, debugstr_guid(ctx
));
243 static HRESULT WINAPI
AEV_VolumeStepDown(IAudioEndpointVolumeEx
*iface
, const GUID
*ctx
)
245 TRACE("(%p)->(%s)\n", iface
, debugstr_guid(ctx
));
250 static HRESULT WINAPI
AEV_QueryHardwareSupport(IAudioEndpointVolumeEx
*iface
, DWORD
*mask
)
252 TRACE("(%p)->(%p)\n", iface
, mask
);
259 static HRESULT WINAPI
AEV_GetVolumeRange(IAudioEndpointVolumeEx
*iface
, float *mindb
, float *maxdb
, float *inc
)
261 TRACE("(%p)->(%p,%p,%p)\n", iface
, mindb
, maxdb
, inc
);
263 if (!mindb
|| !maxdb
|| !inc
)
273 static HRESULT WINAPI
AEV_GetVolumeRangeChannel(IAudioEndpointVolumeEx
*iface
, UINT chan
, float *mindb
, float *maxdb
, float *inc
)
275 TRACE("(%p)->(%p,%p,%p)\n", iface
, mindb
, maxdb
, inc
);
276 if (!mindb
|| !maxdb
|| !inc
)
282 static const IAudioEndpointVolumeExVtbl AEVImpl_Vtbl
= {
286 AEV_RegisterControlChangeNotify
,
287 AEV_UnregisterControlChangeNotify
,
289 AEV_SetMasterVolumeLevel
,
290 AEV_SetMasterVolumeLevelScalar
,
291 AEV_GetMasterVolumeLevel
,
292 AEV_GetMasterVolumeLevelScalar
,
293 AEV_SetChannelVolumeLevel
,
294 AEV_SetChannelVolumeLevelScalar
,
295 AEV_GetChannelVolumeLevel
,
296 AEV_GetChannelVolumeLevelScalar
,
299 AEV_GetVolumeStepInfo
,
302 AEV_QueryHardwareSupport
,
304 AEV_GetVolumeRangeChannel
307 HRESULT
AudioEndpointVolume_Create(MMDevice
*parent
, IAudioEndpointVolumeEx
**ppv
)
312 This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*This
));
314 return E_OUTOFMEMORY
;
315 This
->IAudioEndpointVolumeEx_iface
.lpVtbl
= &AEVImpl_Vtbl
;
318 *ppv
= &This
->IAudioEndpointVolumeEx_iface
;