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.%04u ms %u.%04u 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.%04u 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
);