22613fe33e5d66c2e13d5c33771b2b8789fc4055
[reactos.git] / dll / win32 / mmdevapi / audiovolume.c
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 }