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
19 /* This test is for audio capture specific mechanisms
21 * - IAudioClient with eCapture and IAudioCaptureClient
26 #include "wine/test.h"
36 #include "mmdeviceapi.h"
37 #include "audioclient.h"
39 #define NULL_PTR_ERR MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, RPC_X_NULL_REF_POINTER)
41 static IMMDevice *dev = NULL;
43 static void test_uninitialized(IAudioClient *ac)
49 HANDLE handle = CreateEventW(NULL, FALSE, FALSE, NULL);
52 hr = IAudioClient_GetBufferSize(ac, &num);
53 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetBufferSize call returns %08x\n", hr);
55 hr = IAudioClient_GetStreamLatency(ac, &t1);
56 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetStreamLatency call returns %08x\n", hr);
58 hr = IAudioClient_GetCurrentPadding(ac, &num);
59 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetCurrentPadding call returns %08x\n", hr);
61 hr = IAudioClient_Start(ac);
62 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized Start call returns %08x\n", hr);
64 hr = IAudioClient_Stop(ac);
65 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized Stop call returns %08x\n", hr);
67 hr = IAudioClient_Reset(ac);
68 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized Reset call returns %08x\n", hr);
70 hr = IAudioClient_SetEventHandle(ac, handle);
71 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized SetEventHandle call returns %08x\n", hr);
73 hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&unk);
74 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetService call returns %08x\n", hr);
79 static void test_capture(IAudioClient *ac, HANDLE handle, WAVEFORMATEX *wfx)
81 IAudioCaptureClient *acc;
86 UINT64 devpos, qpcpos;
88 hr = IAudioClient_GetService(ac, &IID_IAudioCaptureClient, (void**)&acc);
89 ok(hr == S_OK, "IAudioClient_GetService(IID_IAudioCaptureClient) returns %08x\n", hr);
93 hr = IAudioCaptureClient_GetNextPacketSize(acc, NULL);
94 ok(hr == E_POINTER, "IAudioCaptureClient_GetNextPacketSize(NULL) returns %08x\n", hr);
96 ok(WaitForSingleObject(handle, 2000) == WAIT_OBJECT_0, "Waiting on event handle failed!\n");
98 /* frames can be 0 if no data is available yet.. */
99 hr = IAudioCaptureClient_GetNextPacketSize(acc, &frames);
100 ok(hr == S_OK, "IAudioCaptureClient_GetNextPacketSize returns %08x\n", hr);
102 data = (BYTE*)(DWORD_PTR)0xdeadbeef;
103 hr = IAudioCaptureClient_GetBuffer(acc, &data, NULL, NULL, NULL, NULL);
104 ok(hr == E_POINTER, "IAudioCaptureClient_GetBuffer(data, NULL, NULL) returns %08x\n", hr);
105 ok((DWORD_PTR)data == 0xdeadbeef, "data is reset to %p\n", data);
108 hr = IAudioCaptureClient_GetBuffer(acc, NULL, &frames, NULL, NULL, NULL);
109 ok(hr == E_POINTER, "IAudioCaptureClient_GetBuffer(NULL, &frames, NULL) returns %08x\n", hr);
110 ok(frames == 0xdeadbeef, "frames is reset to %08x\n", frames);
113 hr = IAudioCaptureClient_GetBuffer(acc, NULL, NULL, &flags, NULL, NULL);
114 ok(hr == E_POINTER, "IAudioCaptureClient_GetBuffer(NULL, NULL, &flags) returns %08x\n", hr);
115 ok(flags == 0xdeadbeef, "flags is reset to %08x\n", flags);
117 hr = IAudioCaptureClient_GetBuffer(acc, &data, &frames, NULL, NULL, NULL);
118 ok(hr == E_POINTER, "IAudioCaptureClient_GetBuffer(&ata, &frames, NULL) returns %08x\n", hr);
120 hr = IAudioCaptureClient_GetBuffer(acc, &data, &frames, &flags, &devpos, &qpcpos);
121 ok(hr == S_OK || hr == AUDCLNT_S_BUFFER_EMPTY, "Valid IAudioCaptureClient_GetBuffer returns %08x\n", hr);
123 ok(frames, "Amount of frames locked is 0!\n");
124 else if (hr == AUDCLNT_S_BUFFER_EMPTY)
125 ok(!frames, "Amount of frames locked with empty buffer is %u!\n", frames);
127 ok(0, "GetBuffer returned %08x\n", hr);
128 trace("Device position is at %u, amount of frames locked: %u\n", (DWORD)devpos, frames);
131 hr = IAudioCaptureClient_GetBuffer(acc, &data, &frames, &flags, &devpos, &qpcpos);
132 ok(hr == AUDCLNT_E_OUT_OF_ORDER, "Out of order IAudioCaptureClient_GetBuffer returns %08x\n", hr);
135 hr = IAudioCaptureClient_ReleaseBuffer(acc, frames);
136 ok(hr == S_OK, "Releasing buffer returns %08x\n", hr);
139 hr = IAudioCaptureClient_ReleaseBuffer(acc, frames);
140 ok(hr == AUDCLNT_E_OUT_OF_ORDER, "Releasing buffer twice returns %08x\n", hr);
143 IUnknown_Release(acc);
146 static void test_audioclient(void)
152 WAVEFORMATEX *pwfx, *pwfx2;
153 REFERENCE_TIME t1, t2;
156 hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
158 ok(hr == S_OK, "Activation failed with %08x\n", hr);
162 handle = CreateEventW(NULL, FALSE, FALSE, NULL);
164 hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, NULL);
165 ok(hr == E_POINTER, "QueryInterface(NULL) returned %08x\n", hr);
167 unk = (void*)(LONG_PTR)0x12345678;
168 hr = IAudioClient_QueryInterface(ac, &IID_NULL, (void**)&unk);
169 ok(hr == E_NOINTERFACE, "QueryInterface(IID_NULL) returned %08x\n", hr);
170 ok(!unk, "QueryInterface(IID_NULL) returned non-null pointer %p\n", unk);
172 hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, (void**)&unk);
173 ok(hr == S_OK, "QueryInterface(IID_IUnknown) returned %08x\n", hr);
176 ref = IUnknown_Release(unk);
177 ok(ref == 1, "Released count is %u\n", ref);
180 hr = IAudioClient_QueryInterface(ac, &IID_IAudioClient, (void**)&unk);
181 ok(hr == S_OK, "QueryInterface(IID_IAudioClient) returned %08x\n", hr);
184 ref = IUnknown_Release(unk);
185 ok(ref == 1, "Released count is %u\n", ref);
188 hr = IAudioClient_GetDevicePeriod(ac, NULL, NULL);
189 ok(hr == E_POINTER, "Invalid GetDevicePeriod call returns %08x\n", hr);
191 hr = IAudioClient_GetDevicePeriod(ac, &t1, NULL);
192 ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr);
194 hr = IAudioClient_GetDevicePeriod(ac, NULL, &t2);
195 ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr);
197 hr = IAudioClient_GetDevicePeriod(ac, &t1, &t2);
198 ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr);
199 trace("Returned periods: %u.%05u ms %u.%05u ms\n",
200 (UINT)(t1/10000), (UINT)(t1 % 10000),
201 (UINT)(t2/10000), (UINT)(t2 % 10000));
203 hr = IAudioClient_GetMixFormat(ac, NULL);
204 ok(hr == E_POINTER, "GetMixFormat returns %08x\n", hr);
206 hr = IAudioClient_GetMixFormat(ac, &pwfx);
207 ok(hr == S_OK, "Valid GetMixFormat returns %08x\n", hr);
211 trace("pwfx: %p\n", pwfx);
212 trace("Tag: %04x\n", pwfx->wFormatTag);
213 trace("bits: %u\n", pwfx->wBitsPerSample);
214 trace("chan: %u\n", pwfx->nChannels);
215 trace("rate: %u\n", pwfx->nSamplesPerSec);
216 trace("align: %u\n", pwfx->nBlockAlign);
217 trace("extra: %u\n", pwfx->cbSize);
218 ok(pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE, "wFormatTag is %x\n", pwfx->wFormatTag);
219 if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
221 WAVEFORMATEXTENSIBLE *pwfxe = (void*)pwfx;
222 trace("Res: %u\n", pwfxe->Samples.wReserved);
223 trace("Mask: %x\n", pwfxe->dwChannelMask);
225 IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)?"PCM":
226 (IsEqualGUID(&pwfxe->SubFormat,
227 &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)?"FLOAT":"Other"));
230 hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
231 ok(hr == S_OK, "Valid IsFormatSupported(Shared) call returns %08x\n", hr);
232 ok(pwfx2 == NULL, "pwfx2 is non-null\n");
233 CoTaskMemFree(pwfx2);
235 hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, NULL, NULL);
236 ok(hr == E_POINTER, "IsFormatSupported(NULL) call returns %08x\n", hr);
238 hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, NULL);
239 ok(hr == E_POINTER, "IsFormatSupported(Shared,NULL) call returns %08x\n", hr);
241 hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
242 ok(hr == S_OK || hr == AUDCLNT_E_UNSUPPORTED_FORMAT, "IsFormatSupported(Exclusive) call returns %08x\n", hr);
244 hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, &pwfx2);
245 ok(hr == S_OK || hr == AUDCLNT_E_UNSUPPORTED_FORMAT, "IsFormatSupported(Exclusive) call returns %08x\n", hr);
246 ok(pwfx2 == NULL, "pwfx2 non-null on exclusive IsFormatSupported\n");
248 hr = IAudioClient_IsFormatSupported(ac, 0xffffffff, pwfx, NULL);
249 ok(hr == E_INVALIDARG, "IsFormatSupported(0xffffffff) call returns %08x\n", hr);
252 test_uninitialized(ac);
254 hr = IAudioClient_Initialize(ac, 3, 0, 5000000, 0, pwfx, NULL);
255 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Initialize with invalid sharemode returns %08x\n", hr);
257 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0xffffffff, 5000000, 0, pwfx, NULL);
258 ok(hr == E_INVALIDARG, "Initialize with invalid flags returns %08x\n", hr);
260 /* It seems that if length > 2s or periodicity != 0 the length is ignored and call succeeds
261 * Since we can only initialize successfully once skip those tests
263 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, NULL, NULL);
264 ok(hr == E_POINTER, "Initialize with null format returns %08x\n", hr);
266 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 5000000, 0, pwfx, NULL);
267 ok(hr == S_OK, "Valid Initialize returns %08x\n", hr);
271 skip("Cannot initialize %08x, remainder of tests is useless\n", hr);
276 hr = IAudioClient_GetStreamLatency(ac, NULL);
277 ok(hr == E_POINTER, "GetStreamLatency(NULL) call returns %08x\n", hr);
279 hr = IAudioClient_GetStreamLatency(ac, &t1);
280 ok(hr == S_OK, "Valid GetStreamLatency call returns %08x\n", hr);
281 trace("Returned latency: %u.%05u ms\n",
282 (UINT)(t1/10000), (UINT)(t1 % 10000));
284 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL);
285 ok(hr == AUDCLNT_E_ALREADY_INITIALIZED, "Calling Initialize twice returns %08x\n", hr);
287 hr = IAudioClient_SetEventHandle(ac, NULL);
288 ok(hr == E_INVALIDARG, "SetEventHandle(NULL) returns %08x\n", hr);
290 hr = IAudioClient_Start(ac);
291 ok(hr == AUDCLNT_E_EVENTHANDLE_NOT_SET, "Start before SetEventHandle returns %08x\n", hr);
293 hr = IAudioClient_SetEventHandle(ac, handle);
294 ok(hr == S_OK, "SetEventHandle returns %08x\n", hr);
296 hr = IAudioClient_Reset(ac);
297 ok(hr == S_OK, "Reset on a resetted stream returns %08x\n", hr);
299 hr = IAudioClient_Stop(ac);
300 ok(hr == S_FALSE, "Stop on a stopped stream returns %08x\n", hr);
302 hr = IAudioClient_Start(ac);
303 ok(hr == S_OK, "Start on a stopped stream returns %08x\n", hr);
305 test_capture(ac, handle, pwfx);
307 IAudioClient_Release(ac);
312 static void test_streamvolume(void)
315 IAudioStreamVolume *asv;
321 hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
323 ok(hr == S_OK, "Activation failed with %08x\n", hr);
327 hr = IAudioClient_GetMixFormat(ac, &fmt);
328 ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
330 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
332 ok(hr == S_OK, "Initialize failed: %08x\n", hr);
334 hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&asv);
335 ok(hr == S_OK, "GetService failed: %08x\n", hr);
337 hr = IAudioStreamVolume_GetChannelCount(asv, NULL);
338 ok(hr == E_POINTER, "GetChannelCount gave wrong error: %08x\n", hr);
340 hr = IAudioStreamVolume_GetChannelCount(asv, &chans);
341 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
342 ok(chans == fmt->nChannels, "GetChannelCount gave wrong number of channels: %d\n", chans);
344 hr = IAudioStreamVolume_GetChannelVolume(asv, fmt->nChannels, NULL);
345 ok(hr == E_POINTER, "GetChannelCount gave wrong error: %08x\n", hr);
347 hr = IAudioStreamVolume_GetChannelVolume(asv, fmt->nChannels, &vol);
348 ok(hr == E_INVALIDARG, "GetChannelCount gave wrong error: %08x\n", hr);
350 hr = IAudioStreamVolume_GetChannelVolume(asv, 0, NULL);
351 ok(hr == E_POINTER, "GetChannelCount gave wrong error: %08x\n", hr);
353 hr = IAudioStreamVolume_GetChannelVolume(asv, 0, &vol);
354 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
355 ok(vol == 1.f, "Channel volume was not 1: %f\n", vol);
357 hr = IAudioStreamVolume_SetChannelVolume(asv, fmt->nChannels, -1.f);
358 ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
360 hr = IAudioStreamVolume_SetChannelVolume(asv, 0, -1.f);
361 ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
363 hr = IAudioStreamVolume_SetChannelVolume(asv, 0, 2.f);
364 ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
366 hr = IAudioStreamVolume_SetChannelVolume(asv, 0, 0.2f);
367 ok(hr == S_OK, "SetChannelVolume failed: %08x\n", hr);
369 hr = IAudioStreamVolume_GetChannelVolume(asv, 0, &vol);
370 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
371 ok(fabsf(vol - 0.2f) < 0.05f, "Channel volume wasn't 0.2: %f\n", vol);
373 hr = IAudioStreamVolume_GetAllVolumes(asv, 0, NULL);
374 ok(hr == E_POINTER, "GetAllVolumes gave wrong error: %08x\n", hr);
376 hr = IAudioStreamVolume_GetAllVolumes(asv, fmt->nChannels, NULL);
377 ok(hr == E_POINTER, "GetAllVolumes gave wrong error: %08x\n", hr);
379 vols = HeapAlloc(GetProcessHeap(), 0, fmt->nChannels * sizeof(float));
380 ok(vols != NULL, "HeapAlloc failed\n");
382 hr = IAudioStreamVolume_GetAllVolumes(asv, fmt->nChannels - 1, vols);
383 ok(hr == E_INVALIDARG, "GetAllVolumes gave wrong error: %08x\n", hr);
385 hr = IAudioStreamVolume_GetAllVolumes(asv, fmt->nChannels, vols);
386 ok(hr == S_OK, "GetAllVolumes failed: %08x\n", hr);
387 ok(fabsf(vols[0] - 0.2f) < 0.05f, "Channel 0 volume wasn't 0.2: %f\n", vol);
388 for(i = 1; i < fmt->nChannels; ++i)
389 ok(vols[i] == 1.f, "Channel %d volume is not 1: %f\n", i, vols[i]);
391 hr = IAudioStreamVolume_SetAllVolumes(asv, 0, NULL);
392 ok(hr == E_POINTER, "SetAllVolumes gave wrong error: %08x\n", hr);
394 hr = IAudioStreamVolume_SetAllVolumes(asv, fmt->nChannels, NULL);
395 ok(hr == E_POINTER, "SetAllVolumes gave wrong error: %08x\n", hr);
397 hr = IAudioStreamVolume_SetAllVolumes(asv, fmt->nChannels - 1, vols);
398 ok(hr == E_INVALIDARG, "SetAllVolumes gave wrong error: %08x\n", hr);
400 hr = IAudioStreamVolume_SetAllVolumes(asv, fmt->nChannels, vols);
401 ok(hr == S_OK, "SetAllVolumes failed: %08x\n", hr);
403 HeapFree(GetProcessHeap(), 0, vols);
404 IAudioStreamVolume_Release(asv);
405 IAudioClient_Release(ac);
409 static void test_channelvolume(void)
412 IChannelAudioVolume *acv;
418 hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
420 ok(hr == S_OK, "Activation failed with %08x\n", hr);
424 hr = IAudioClient_GetMixFormat(ac, &fmt);
425 ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
427 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
428 AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, NULL);
429 ok(hr == S_OK, "Initialize failed: %08x\n", hr);
431 hr = IAudioClient_GetService(ac, &IID_IChannelAudioVolume, (void**)&acv);
432 ok(hr == S_OK, "GetService failed: %08x\n", hr);
434 hr = IChannelAudioVolume_GetChannelCount(acv, NULL);
435 ok(hr == NULL_PTR_ERR, "GetChannelCount gave wrong error: %08x\n", hr);
437 hr = IChannelAudioVolume_GetChannelCount(acv, &chans);
438 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
439 ok(chans == fmt->nChannels, "GetChannelCount gave wrong number of channels: %d\n", chans);
441 hr = IChannelAudioVolume_GetChannelVolume(acv, fmt->nChannels, NULL);
442 ok(hr == NULL_PTR_ERR, "GetChannelCount gave wrong error: %08x\n", hr);
444 hr = IChannelAudioVolume_GetChannelVolume(acv, fmt->nChannels, &vol);
445 ok(hr == E_INVALIDARG, "GetChannelCount gave wrong error: %08x\n", hr);
447 hr = IChannelAudioVolume_GetChannelVolume(acv, 0, NULL);
448 ok(hr == NULL_PTR_ERR, "GetChannelCount gave wrong error: %08x\n", hr);
450 hr = IChannelAudioVolume_GetChannelVolume(acv, 0, &vol);
451 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
452 ok(vol == 1.f, "Channel volume was not 1: %f\n", vol);
454 hr = IChannelAudioVolume_SetChannelVolume(acv, fmt->nChannels, -1.f, NULL);
455 ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
457 hr = IChannelAudioVolume_SetChannelVolume(acv, 0, -1.f, NULL);
458 ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
460 hr = IChannelAudioVolume_SetChannelVolume(acv, 0, 2.f, NULL);
461 ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
463 hr = IChannelAudioVolume_SetChannelVolume(acv, 0, 0.2f, NULL);
464 ok(hr == S_OK, "SetChannelVolume failed: %08x\n", hr);
466 hr = IChannelAudioVolume_GetChannelVolume(acv, 0, &vol);
467 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
468 ok(fabsf(vol - 0.2f) < 0.05f, "Channel volume wasn't 0.2: %f\n", vol);
470 hr = IChannelAudioVolume_GetAllVolumes(acv, 0, NULL);
471 ok(hr == NULL_PTR_ERR, "GetAllVolumes gave wrong error: %08x\n", hr);
473 hr = IChannelAudioVolume_GetAllVolumes(acv, fmt->nChannels, NULL);
474 ok(hr == NULL_PTR_ERR, "GetAllVolumes gave wrong error: %08x\n", hr);
476 vols = HeapAlloc(GetProcessHeap(), 0, fmt->nChannels * sizeof(float));
477 ok(vols != NULL, "HeapAlloc failed\n");
479 hr = IChannelAudioVolume_GetAllVolumes(acv, fmt->nChannels - 1, vols);
480 ok(hr == E_INVALIDARG, "GetAllVolumes gave wrong error: %08x\n", hr);
482 hr = IChannelAudioVolume_GetAllVolumes(acv, fmt->nChannels, vols);
483 ok(hr == S_OK, "GetAllVolumes failed: %08x\n", hr);
484 ok(fabsf(vols[0] - 0.2f) < 0.05f, "Channel 0 volume wasn't 0.2: %f\n", vol);
485 for(i = 1; i < fmt->nChannels; ++i)
486 ok(vols[i] == 1.f, "Channel %d volume is not 1: %f\n", i, vols[i]);
488 hr = IChannelAudioVolume_SetAllVolumes(acv, 0, NULL, NULL);
489 ok(hr == NULL_PTR_ERR, "SetAllVolumes gave wrong error: %08x\n", hr);
491 hr = IChannelAudioVolume_SetAllVolumes(acv, fmt->nChannels, NULL, NULL);
492 ok(hr == NULL_PTR_ERR, "SetAllVolumes gave wrong error: %08x\n", hr);
494 hr = IChannelAudioVolume_SetAllVolumes(acv, fmt->nChannels - 1, vols, NULL);
495 ok(hr == E_INVALIDARG, "SetAllVolumes gave wrong error: %08x\n", hr);
497 hr = IChannelAudioVolume_SetAllVolumes(acv, fmt->nChannels, vols, NULL);
498 ok(hr == S_OK, "SetAllVolumes failed: %08x\n", hr);
500 hr = IChannelAudioVolume_SetChannelVolume(acv, 0, 1.0f, NULL);
501 ok(hr == S_OK, "SetChannelVolume failed: %08x\n", hr);
503 HeapFree(GetProcessHeap(), 0, vols);
504 IChannelAudioVolume_Release(acv);
505 IAudioClient_Release(ac);
509 static void test_simplevolume(void)
512 ISimpleAudioVolume *sav;
518 hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
520 ok(hr == S_OK, "Activation failed with %08x\n", hr);
524 hr = IAudioClient_GetMixFormat(ac, &fmt);
525 ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
527 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
528 AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, NULL);
529 ok(hr == S_OK, "Initialize failed: %08x\n", hr);
531 hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
532 ok(hr == S_OK, "GetService failed: %08x\n", hr);
534 hr = ISimpleAudioVolume_GetMasterVolume(sav, NULL);
535 ok(hr == NULL_PTR_ERR, "GetMasterVolume gave wrong error: %08x\n", hr);
537 hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
538 ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
539 ok(vol == 1.f, "Master volume wasn't 1: %f\n", vol);
541 hr = ISimpleAudioVolume_SetMasterVolume(sav, -1.f, NULL);
542 ok(hr == E_INVALIDARG, "SetMasterVolume gave wrong error: %08x\n", hr);
544 hr = ISimpleAudioVolume_SetMasterVolume(sav, 2.f, NULL);
545 ok(hr == E_INVALIDARG, "SetMasterVolume gave wrong error: %08x\n", hr);
547 hr = ISimpleAudioVolume_SetMasterVolume(sav, 0.2f, NULL);
548 ok(hr == S_OK, "SetMasterVolume failed: %08x\n", hr);
550 hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
551 ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
552 ok(fabsf(vol - 0.2f) < 0.05f, "Master volume wasn't 0.2: %f\n", vol);
554 hr = ISimpleAudioVolume_GetMute(sav, NULL);
555 ok(hr == NULL_PTR_ERR, "GetMute gave wrong error: %08x\n", hr);
558 hr = ISimpleAudioVolume_GetMute(sav, &mute);
559 ok(hr == S_OK, "GetMute failed: %08x\n", hr);
560 ok(mute == FALSE, "Session is already muted\n");
562 hr = ISimpleAudioVolume_SetMute(sav, TRUE, NULL);
563 ok(hr == S_OK, "SetMute failed: %08x\n", hr);
566 hr = ISimpleAudioVolume_GetMute(sav, &mute);
567 ok(hr == S_OK, "GetMute failed: %08x\n", hr);
568 ok(mute == TRUE, "Session should have been muted\n");
570 hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
571 ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
572 ok(fabsf(vol - 0.2f) < 0.05f, "Master volume wasn't 0.2: %f\n", vol);
574 hr = ISimpleAudioVolume_SetMasterVolume(sav, 1.f, NULL);
575 ok(hr == S_OK, "SetMasterVolume failed: %08x\n", hr);
578 hr = ISimpleAudioVolume_GetMute(sav, &mute);
579 ok(hr == S_OK, "GetMute failed: %08x\n", hr);
580 ok(mute == TRUE, "Session should have been muted\n");
582 hr = ISimpleAudioVolume_SetMute(sav, FALSE, NULL);
583 ok(hr == S_OK, "SetMute failed: %08x\n", hr);
585 ISimpleAudioVolume_Release(sav);
586 IAudioClient_Release(ac);
590 static void test_volume_dependence(void)
592 IAudioClient *ac, *ac2;
593 ISimpleAudioVolume *sav;
594 IChannelAudioVolume *cav;
595 IAudioStreamVolume *asv;
602 hr = CoCreateGuid(&session);
603 ok(hr == S_OK, "CoCreateGuid failed: %08x\n", hr);
605 hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
607 ok(hr == S_OK, "Activation failed with %08x\n", hr);
609 hr = IAudioClient_GetMixFormat(ac, &fmt);
610 ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
612 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
613 AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, &session);
614 ok(hr == S_OK, "Initialize failed: %08x\n", hr);
616 hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
617 ok(hr == S_OK, "GetService (SimpleAudioVolume) failed: %08x\n", hr);
619 hr = IAudioClient_GetService(ac, &IID_IChannelAudioVolume, (void**)&cav);
620 ok(hr == S_OK, "GetService (ChannelAudioVolme) failed: %08x\n", hr);
622 hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&asv);
623 ok(hr == S_OK, "GetService (AudioStreamVolume) failed: %08x\n", hr);
625 hr = IAudioStreamVolume_SetChannelVolume(asv, 0, 0.2f);
626 ok(hr == S_OK, "ASV_SetChannelVolume failed: %08x\n", hr);
628 hr = IChannelAudioVolume_SetChannelVolume(cav, 0, 0.4f, NULL);
629 ok(hr == S_OK, "CAV_SetChannelVolume failed: %08x\n", hr);
631 hr = ISimpleAudioVolume_SetMasterVolume(sav, 0.6f, NULL);
632 ok(hr == S_OK, "SAV_SetMasterVolume failed: %08x\n", hr);
634 hr = IAudioStreamVolume_GetChannelVolume(asv, 0, &vol);
635 ok(hr == S_OK, "ASV_GetChannelVolume failed: %08x\n", hr);
636 ok(fabsf(vol - 0.2) < 0.05f, "ASV_GetChannelVolume gave wrong volume: %f\n", vol);
638 hr = IChannelAudioVolume_GetChannelVolume(cav, 0, &vol);
639 ok(hr == S_OK, "CAV_GetChannelVolume failed: %08x\n", hr);
640 ok(fabsf(vol - 0.4) < 0.05f, "CAV_GetChannelVolume gave wrong volume: %f\n", vol);
642 hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
643 ok(hr == S_OK, "SAV_GetMasterVolume failed: %08x\n", hr);
644 ok(fabsf(vol - 0.6) < 0.05f, "SAV_GetMasterVolume gave wrong volume: %f\n", vol);
646 hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
649 IChannelAudioVolume *cav2;
650 IAudioStreamVolume *asv2;
652 hr = IAudioClient_Initialize(ac2, AUDCLNT_SHAREMODE_SHARED,
653 AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, &session);
654 ok(hr == S_OK, "Initialize failed: %08x\n", hr);
656 hr = IAudioClient_GetService(ac2, &IID_IChannelAudioVolume, (void**)&cav2);
657 ok(hr == S_OK, "GetService failed: %08x\n", hr);
659 hr = IAudioClient_GetService(ac2, &IID_IAudioStreamVolume, (void**)&asv2);
660 ok(hr == S_OK, "GetService failed: %08x\n", hr);
662 hr = IChannelAudioVolume_GetChannelVolume(cav2, 0, &vol);
663 ok(hr == S_OK, "CAV_GetChannelVolume failed: %08x\n", hr);
664 ok(fabsf(vol - 0.4) < 0.05f, "CAV_GetChannelVolume gave wrong volume: %f\n", vol);
666 hr = IAudioStreamVolume_GetChannelVolume(asv2, 0, &vol);
667 ok(hr == S_OK, "ASV_GetChannelVolume failed: %08x\n", hr);
668 ok(vol == 1.f, "ASV_GetChannelVolume gave wrong volume: %f\n", vol);
670 hr = IChannelAudioVolume_GetChannelCount(cav2, &nch);
671 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
672 ok(nch == fmt->nChannels, "Got wrong channel count, expected %u: %u\n", fmt->nChannels, nch);
674 hr = IAudioStreamVolume_GetChannelCount(asv2, &nch);
675 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
676 ok(nch == fmt->nChannels, "Got wrong channel count, expected %u: %u\n", fmt->nChannels, nch);
678 IAudioStreamVolume_Release(asv2);
679 IChannelAudioVolume_Release(cav2);
680 IAudioClient_Release(ac2);
682 skip("Unable to open the same device twice. Skipping session volume control tests\n");
684 hr = IChannelAudioVolume_SetChannelVolume(cav, 0, 1.f, NULL);
685 ok(hr == S_OK, "CAV_SetChannelVolume failed: %08x\n", hr);
687 hr = ISimpleAudioVolume_SetMasterVolume(sav, 1.f, NULL);
688 ok(hr == S_OK, "SAV_SetMasterVolume failed: %08x\n", hr);
691 ISimpleAudioVolume_Release(sav);
692 IChannelAudioVolume_Release(cav);
693 IAudioStreamVolume_Release(asv);
694 IAudioClient_Release(ac);
700 IMMDeviceEnumerator *mme = NULL;
702 CoInitializeEx(NULL, COINIT_MULTITHREADED);
703 hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme);
706 skip("mmdevapi not available: 0x%08x\n", hr);
710 hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme, eCapture, eMultimedia, &dev);
711 ok(hr == S_OK || hr == E_NOTFOUND, "GetDefaultAudioEndpoint failed: 0x%08x\n", hr);
712 if (hr != S_OK || !dev)
714 if (hr == E_NOTFOUND)
715 skip("No sound card available\n");
717 skip("GetDefaultAudioEndpoint returns 0x%08x\n", hr);
723 test_channelvolume();
725 test_volume_dependence();
727 IMMDevice_Release(dev);
731 IMMDeviceEnumerator_Release(mme);