Reactos
at master 318 lines 8.7 kB view raw
1/* 2 * Copyright 2010 Maarten Lankhorst for CodeWeavers 3 * 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. 8 * 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. 13 * 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 17 */ 18 19#define COBJMACROS 20 21#include <stdarg.h> 22 23#include "windef.h" 24#include "winbase.h" 25#include "winnls.h" 26#include "winreg.h" 27#include "wine/debug.h" 28 29#include "ole2.h" 30#include "mmdeviceapi.h" 31#include "mmsystem.h" 32#include "dsound.h" 33#include "audioclient.h" 34#include "endpointvolume.h" 35#include "audiopolicy.h" 36 37#include "mmdevapi.h" 38 39WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi); 40 41typedef struct AEVImpl { 42 IAudioEndpointVolumeEx IAudioEndpointVolumeEx_iface; 43 LONG ref; 44 float master_vol; 45 BOOL mute; 46} AEVImpl; 47 48static inline AEVImpl *impl_from_IAudioEndpointVolumeEx(IAudioEndpointVolumeEx *iface) 49{ 50 return CONTAINING_RECORD(iface, AEVImpl, IAudioEndpointVolumeEx_iface); 51} 52 53static void AudioEndpointVolume_Destroy(AEVImpl *This) 54{ 55 HeapFree(GetProcessHeap(), 0, This); 56} 57 58static HRESULT WINAPI AEV_QueryInterface(IAudioEndpointVolumeEx *iface, REFIID riid, void **ppv) 59{ 60 AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface); 61 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppv); 62 if (!ppv) 63 return E_POINTER; 64 *ppv = NULL; 65 if (IsEqualIID(riid, &IID_IUnknown) || 66 IsEqualIID(riid, &IID_IAudioEndpointVolume) || 67 IsEqualIID(riid, &IID_IAudioEndpointVolumeEx)) { 68 *ppv = &This->IAudioEndpointVolumeEx_iface; 69 } 70 else 71 return E_NOINTERFACE; 72 IUnknown_AddRef((IUnknown *)*ppv); 73 return S_OK; 74} 75 76static ULONG WINAPI AEV_AddRef(IAudioEndpointVolumeEx *iface) 77{ 78 AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface); 79 ULONG ref = InterlockedIncrement(&This->ref); 80 TRACE("(%p) new ref %u\n", This, ref); 81 return ref; 82} 83 84static ULONG WINAPI AEV_Release(IAudioEndpointVolumeEx *iface) 85{ 86 AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface); 87 ULONG ref = InterlockedDecrement(&This->ref); 88 TRACE("(%p) new ref %u\n", This, ref); 89 if (!ref) 90 AudioEndpointVolume_Destroy(This); 91 return ref; 92} 93 94static HRESULT WINAPI AEV_RegisterControlChangeNotify(IAudioEndpointVolumeEx *iface, IAudioEndpointVolumeCallback *notify) 95{ 96 TRACE("(%p)->(%p)\n", iface, notify); 97 if (!notify) 98 return E_POINTER; 99 FIXME("stub\n"); 100 return S_OK; 101} 102 103static HRESULT WINAPI AEV_UnregisterControlChangeNotify(IAudioEndpointVolumeEx *iface, IAudioEndpointVolumeCallback *notify) 104{ 105 TRACE("(%p)->(%p)\n", iface, notify); 106 if (!notify) 107 return E_POINTER; 108 FIXME("stub\n"); 109 return S_OK; 110} 111 112static HRESULT WINAPI AEV_GetChannelCount(IAudioEndpointVolumeEx *iface, UINT *count) 113{ 114 TRACE("(%p)->(%p)\n", iface, count); 115 if (!count) 116 return E_POINTER; 117 FIXME("stub\n"); 118 return E_NOTIMPL; 119} 120 121static HRESULT WINAPI AEV_SetMasterVolumeLevel(IAudioEndpointVolumeEx *iface, float leveldb, const GUID *ctx) 122{ 123 AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface); 124 125 TRACE("(%p)->(%f,%s)\n", iface, leveldb, debugstr_guid(ctx)); 126 127 if(leveldb < -100.f || leveldb > 0.f) 128 return E_INVALIDARG; 129 130 This->master_vol = leveldb; 131 132 return S_OK; 133} 134 135static HRESULT WINAPI AEV_SetMasterVolumeLevelScalar(IAudioEndpointVolumeEx *iface, float level, const GUID *ctx) 136{ 137 TRACE("(%p)->(%f,%s)\n", iface, level, debugstr_guid(ctx)); 138 FIXME("stub\n"); 139 return E_NOTIMPL; 140} 141 142static HRESULT WINAPI AEV_GetMasterVolumeLevel(IAudioEndpointVolumeEx *iface, float *leveldb) 143{ 144 AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface); 145 146 TRACE("(%p)->(%p)\n", iface, leveldb); 147 148 if (!leveldb) 149 return E_POINTER; 150 151 *leveldb = This->master_vol; 152 153 return S_OK; 154} 155 156static HRESULT WINAPI AEV_GetMasterVolumeLevelScalar(IAudioEndpointVolumeEx *iface, float *level) 157{ 158 TRACE("(%p)->(%p)\n", iface, level); 159 if (!level) 160 return E_POINTER; 161 FIXME("stub\n"); 162 return E_NOTIMPL; 163} 164 165static HRESULT WINAPI AEV_SetChannelVolumeLevel(IAudioEndpointVolumeEx *iface, UINT chan, float leveldb, const GUID *ctx) 166{ 167 TRACE("(%p)->(%f,%s)\n", iface, leveldb, debugstr_guid(ctx)); 168 FIXME("stub\n"); 169 return E_NOTIMPL; 170} 171 172static HRESULT WINAPI AEV_SetChannelVolumeLevelScalar(IAudioEndpointVolumeEx *iface, UINT chan, float level, const GUID *ctx) 173{ 174 TRACE("(%p)->(%u,%f,%s)\n", iface, chan, level, debugstr_guid(ctx)); 175 FIXME("stub\n"); 176 return E_NOTIMPL; 177} 178 179static HRESULT WINAPI AEV_GetChannelVolumeLevel(IAudioEndpointVolumeEx *iface, UINT chan, float *leveldb) 180{ 181 TRACE("(%p)->(%u,%p)\n", iface, chan, leveldb); 182 if (!leveldb) 183 return E_POINTER; 184 FIXME("stub\n"); 185 return E_NOTIMPL; 186} 187 188static HRESULT WINAPI AEV_GetChannelVolumeLevelScalar(IAudioEndpointVolumeEx *iface, UINT chan, float *level) 189{ 190 TRACE("(%p)->(%u,%p)\n", iface, chan, level); 191 if (!level) 192 return E_POINTER; 193 FIXME("stub\n"); 194 return E_NOTIMPL; 195} 196 197static HRESULT WINAPI AEV_SetMute(IAudioEndpointVolumeEx *iface, BOOL mute, const GUID *ctx) 198{ 199 AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface); 200 HRESULT ret; 201 202 TRACE("(%p)->(%u,%s)\n", iface, mute, debugstr_guid(ctx)); 203 204 ret = This->mute == mute ? S_FALSE : S_OK; 205 206 This->mute = mute; 207 208 return ret; 209} 210 211static HRESULT WINAPI AEV_GetMute(IAudioEndpointVolumeEx *iface, BOOL *mute) 212{ 213 AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface); 214 215 TRACE("(%p)->(%p)\n", iface, mute); 216 217 if (!mute) 218 return E_POINTER; 219 220 *mute = This->mute; 221 222 return S_OK; 223} 224 225static HRESULT WINAPI AEV_GetVolumeStepInfo(IAudioEndpointVolumeEx *iface, UINT *stepsize, UINT *stepcount) 226{ 227 TRACE("(%p)->(%p,%p)\n", iface, stepsize, stepcount); 228 if (!stepsize && !stepcount) 229 return E_POINTER; 230 FIXME("stub\n"); 231 return E_NOTIMPL; 232} 233 234static HRESULT WINAPI AEV_VolumeStepUp(IAudioEndpointVolumeEx *iface, const GUID *ctx) 235{ 236 TRACE("(%p)->(%s)\n", iface, debugstr_guid(ctx)); 237 FIXME("stub\n"); 238 return E_NOTIMPL; 239} 240 241static HRESULT WINAPI AEV_VolumeStepDown(IAudioEndpointVolumeEx *iface, const GUID *ctx) 242{ 243 TRACE("(%p)->(%s)\n", iface, debugstr_guid(ctx)); 244 FIXME("stub\n"); 245 return E_NOTIMPL; 246} 247 248static HRESULT WINAPI AEV_QueryHardwareSupport(IAudioEndpointVolumeEx *iface, DWORD *mask) 249{ 250 TRACE("(%p)->(%p)\n", iface, mask); 251 if (!mask) 252 return E_POINTER; 253 FIXME("stub\n"); 254 return E_NOTIMPL; 255} 256 257static HRESULT WINAPI AEV_GetVolumeRange(IAudioEndpointVolumeEx *iface, float *mindb, float *maxdb, float *inc) 258{ 259 TRACE("(%p)->(%p,%p,%p)\n", iface, mindb, maxdb, inc); 260 261 if (!mindb || !maxdb || !inc) 262 return E_POINTER; 263 264 *mindb = -100.f; 265 *maxdb = 0.f; 266 *inc = 1.f; 267 268 return S_OK; 269} 270 271static HRESULT WINAPI AEV_GetVolumeRangeChannel(IAudioEndpointVolumeEx *iface, UINT chan, float *mindb, float *maxdb, float *inc) 272{ 273 TRACE("(%p)->(%p,%p,%p)\n", iface, mindb, maxdb, inc); 274 if (!mindb || !maxdb || !inc) 275 return E_POINTER; 276 FIXME("stub\n"); 277 return E_NOTIMPL; 278} 279 280static const IAudioEndpointVolumeExVtbl AEVImpl_Vtbl = { 281 AEV_QueryInterface, 282 AEV_AddRef, 283 AEV_Release, 284 AEV_RegisterControlChangeNotify, 285 AEV_UnregisterControlChangeNotify, 286 AEV_GetChannelCount, 287 AEV_SetMasterVolumeLevel, 288 AEV_SetMasterVolumeLevelScalar, 289 AEV_GetMasterVolumeLevel, 290 AEV_GetMasterVolumeLevelScalar, 291 AEV_SetChannelVolumeLevel, 292 AEV_SetChannelVolumeLevelScalar, 293 AEV_GetChannelVolumeLevel, 294 AEV_GetChannelVolumeLevelScalar, 295 AEV_SetMute, 296 AEV_GetMute, 297 AEV_GetVolumeStepInfo, 298 AEV_VolumeStepUp, 299 AEV_VolumeStepDown, 300 AEV_QueryHardwareSupport, 301 AEV_GetVolumeRange, 302 AEV_GetVolumeRangeChannel 303}; 304 305HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolumeEx **ppv) 306{ 307 AEVImpl *This; 308 309 *ppv = NULL; 310 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This)); 311 if (!This) 312 return E_OUTOFMEMORY; 313 This->IAudioEndpointVolumeEx_iface.lpVtbl = &AEVImpl_Vtbl; 314 This->ref = 1; 315 316 *ppv = &This->IAudioEndpointVolumeEx_iface; 317 return S_OK; 318}