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