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
;
42 static const LARGE_INTEGER ullZero
;
44 static void test_uninitialized(IAudioClient
*ac
)
50 HANDLE handle
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
53 hr
= IAudioClient_GetBufferSize(ac
, &num
);
54 ok(hr
== AUDCLNT_E_NOT_INITIALIZED
, "Uninitialized GetBufferSize call returns %08x\n", hr
);
56 hr
= IAudioClient_GetStreamLatency(ac
, &t1
);
57 ok(hr
== AUDCLNT_E_NOT_INITIALIZED
, "Uninitialized GetStreamLatency call returns %08x\n", hr
);
59 hr
= IAudioClient_GetCurrentPadding(ac
, &num
);
60 ok(hr
== AUDCLNT_E_NOT_INITIALIZED
, "Uninitialized GetCurrentPadding call returns %08x\n", hr
);
62 hr
= IAudioClient_Start(ac
);
63 ok(hr
== AUDCLNT_E_NOT_INITIALIZED
, "Uninitialized Start call returns %08x\n", hr
);
65 hr
= IAudioClient_Stop(ac
);
66 ok(hr
== AUDCLNT_E_NOT_INITIALIZED
, "Uninitialized Stop call returns %08x\n", hr
);
68 hr
= IAudioClient_Reset(ac
);
69 ok(hr
== AUDCLNT_E_NOT_INITIALIZED
, "Uninitialized Reset call returns %08x\n", hr
);
71 hr
= IAudioClient_SetEventHandle(ac
, handle
);
72 ok(hr
== AUDCLNT_E_NOT_INITIALIZED
, "Uninitialized SetEventHandle call returns %08x\n", hr
);
74 hr
= IAudioClient_GetService(ac
, &IID_IAudioStreamVolume
, (void**)&unk
);
75 ok(hr
== AUDCLNT_E_NOT_INITIALIZED
, "Uninitialized GetService call returns %08x\n", hr
);
80 static void test_capture(IAudioClient
*ac
, HANDLE handle
, WAVEFORMATEX
*wfx
)
82 IAudioCaptureClient
*acc
;
84 UINT32 frames
, next
, pad
, sum
= 0;
88 REFERENCE_TIME period
;
90 hr
= IAudioClient_GetService(ac
, &IID_IAudioCaptureClient
, (void**)&acc
);
91 ok(hr
== S_OK
, "IAudioClient_GetService(IID_IAudioCaptureClient) returns %08x\n", hr
);
96 data
= (void*)0xdeadf00d;
98 pos
= qpc
= 0xdeadbeef;
99 hr
= IAudioCaptureClient_GetBuffer(acc
, &data
, &frames
, &flags
, &pos
, &qpc
);
100 ok(hr
== AUDCLNT_S_BUFFER_EMPTY
, "Initial IAudioCaptureClient_GetBuffer returns %08x\n", hr
);
102 /* should be empty right after start. Otherwise consume one packet */
104 hr
= IAudioCaptureClient_ReleaseBuffer(acc
, frames
);
105 ok(hr
== S_OK
, "Releasing buffer returns %08x\n", hr
);
109 data
= (void*)0xdeadf00d;
111 pos
= qpc
= 0xdeadbeef;
112 hr
= IAudioCaptureClient_GetBuffer(acc
, &data
, &frames
, &flags
, &pos
, &qpc
);
113 ok(hr
== AUDCLNT_S_BUFFER_EMPTY
, "Initial IAudioCaptureClient_GetBuffer returns %08x\n", hr
);
116 if(hr
== AUDCLNT_S_BUFFER_EMPTY
){
117 ok(!frames
, "frames changed to %u\n", frames
);
118 ok(data
== (void*)0xdeadf00d, "data changed to %p\n", data
);
119 ok(flags
== 0xabadcafe, "flags changed to %x\n", flags
);
120 ok(pos
== 0xdeadbeef, "position changed to %u\n", (UINT
)pos
);
121 ok(qpc
== 0xdeadbeef, "timer changed to %u\n", (UINT
)qpc
);
123 /* GetNextPacketSize yields 0 if no data is yet available
124 * it is not constantly period_size * SamplesPerSec */
125 hr
= IAudioCaptureClient_GetNextPacketSize(acc
, &next
);
126 ok(hr
== S_OK
, "IAudioCaptureClient_GetNextPacketSize returns %08x\n", hr
);
127 ok(!next
, "GetNextPacketSize %u\n", next
);
130 hr
= IAudioCaptureClient_ReleaseBuffer(acc
, frames
);
131 ok(hr
== S_OK
, "Releasing buffer returns %08x\n", hr
);
134 ok(ResetEvent(handle
), "ResetEvent\n");
136 hr
= IAudioCaptureClient_GetNextPacketSize(acc
, &next
);
137 ok(hr
== S_OK
, "IAudioCaptureClient_GetNextPacketSize returns %08x\n", hr
);
139 hr
= IAudioClient_GetCurrentPadding(ac
, &pad
);
140 ok(hr
== S_OK
, "GetCurrentPadding call returns %08x\n", hr
);
141 ok(next
== pad
, "GetNextPacketSize %u vs. GCP %u\n", next
, pad
);
142 /* later GCP will grow, while GNPS is 0 or period size */
144 hr
= IAudioCaptureClient_GetNextPacketSize(acc
, NULL
);
145 ok(hr
== E_POINTER
, "IAudioCaptureClient_GetNextPacketSize(NULL) returns %08x\n", hr
);
147 data
= (void*)0xdeadf00d;
150 hr
= IAudioCaptureClient_GetBuffer(acc
, &data
, NULL
, NULL
, NULL
, NULL
);
151 ok(hr
== E_POINTER
, "IAudioCaptureClient_GetBuffer(data, NULL, NULL) returns %08x\n", hr
);
153 hr
= IAudioCaptureClient_GetBuffer(acc
, NULL
, &frames
, NULL
, NULL
, NULL
);
154 ok(hr
== E_POINTER
, "IAudioCaptureClient_GetBuffer(NULL, &frames, NULL) returns %08x\n", hr
);
156 hr
= IAudioCaptureClient_GetBuffer(acc
, NULL
, NULL
, &flags
, NULL
, NULL
);
157 ok(hr
== E_POINTER
, "IAudioCaptureClient_GetBuffer(NULL, NULL, &flags) returns %08x\n", hr
);
159 hr
= IAudioCaptureClient_GetBuffer(acc
, &data
, &frames
, NULL
, NULL
, NULL
);
160 ok(hr
== E_POINTER
, "IAudioCaptureClient_GetBuffer(&ata, &frames, NULL) returns %08x\n", hr
);
161 ok((DWORD_PTR
)data
== 0xdeadf00d, "data is reset to %p\n", data
);
162 ok(frames
== 0xdeadbeef, "frames is reset to %08x\n", frames
);
163 ok(flags
== 0xabadcafe, "flags is reset to %08x\n", flags
);
165 hr
= IAudioClient_GetDevicePeriod(ac
, &period
, NULL
);
166 ok(hr
== S_OK
, "GetDevicePeriod failed: %08x\n", hr
);
167 period
= MulDiv(period
, wfx
->nSamplesPerSec
, 10000000); /* as in render.c */
169 ok(WaitForSingleObject(handle
, 1000) == WAIT_OBJECT_0
, "Waiting on event handle failed!\n");
171 data
= (void*)0xdeadf00d;
172 hr
= IAudioCaptureClient_GetBuffer(acc
, &data
, &frames
, &flags
, &pos
, &qpc
);
173 ok(hr
== S_OK
|| hr
== AUDCLNT_S_BUFFER_EMPTY
, "Valid IAudioCaptureClient_GetBuffer returns %08x\n", hr
);
175 ok(frames
, "Amount of frames locked is 0!\n");
176 /* broken: some w7 machines return pad == 0 and DATA_DISCONTINUITY here,
177 * AUDCLNT_S_BUFFER_EMPTY above, yet pos == 1-2 * period rather than 0 */
178 ok(pos
== sum
|| broken(pos
== period
|| pos
== 2*period
),
179 "Position %u expected %u\n", (UINT
)pos
, sum
);
181 }else if (hr
== AUDCLNT_S_BUFFER_EMPTY
){
182 ok(!frames
, "Amount of frames locked with empty buffer is %u!\n", frames
);
183 ok(data
== (void*)0xdeadf00d, "No data changed to %p\n", data
);
186 trace("Wait'ed position %d pad %u flags %x, amount of frames locked: %u\n",
187 hr
==S_OK
? (UINT
)pos
: -1, pad
, flags
, frames
);
189 hr
= IAudioCaptureClient_GetNextPacketSize(acc
, &next
);
190 ok(hr
== S_OK
, "IAudioCaptureClient_GetNextPacketSize returns %08x\n", hr
);
191 ok(next
== frames
, "GetNextPacketSize %u vs. GetBuffer %u\n", next
, frames
);
193 hr
= IAudioCaptureClient_ReleaseBuffer(acc
, frames
);
194 ok(hr
== S_OK
, "Releasing buffer returns %08x\n", hr
);
196 hr
= IAudioCaptureClient_ReleaseBuffer(acc
, 0);
197 ok(hr
== S_OK
, "Releasing 0 returns %08x\n", hr
);
199 hr
= IAudioCaptureClient_GetNextPacketSize(acc
, &next
);
200 ok(hr
== S_OK
, "IAudioCaptureClient_GetNextPacketSize returns %08x\n", hr
);
203 hr
= IAudioCaptureClient_ReleaseBuffer(acc
, frames
);
204 ok(hr
== AUDCLNT_E_OUT_OF_ORDER
, "Releasing buffer twice returns %08x\n", hr
);
208 Sleep(350); /* for sure there's data now */
210 hr
= IAudioClient_GetCurrentPadding(ac
, &pad
);
211 ok(hr
== S_OK
, "GetCurrentPadding call returns %08x\n", hr
);
213 /** GetNextPacketSize
214 * returns either 0 or one period worth of frames
215 * whereas GetCurrentPadding grows when input is not consumed. */
216 hr
= IAudioCaptureClient_GetNextPacketSize(acc
, &next
);
217 ok(hr
== S_OK
, "IAudioCaptureClient_GetNextPacketSize returns %08x\n", hr
);
218 ok(next
< pad
, "GetNextPacketSize %u vs. GCP %u\n", next
, pad
);
220 hr
= IAudioCaptureClient_GetBuffer(acc
, &data
, &frames
, &flags
, &pos
, &qpc
);
221 ok(hr
== S_OK
, "Valid IAudioCaptureClient_GetBuffer returns %08x\n", hr
);
222 ok(next
== frames
, "GetNextPacketSize %u vs. GetBuffer %u\n", next
, frames
);
225 UINT32 frames2
= frames
;
227 ok(frames
, "Amount of frames locked is 0!\n");
228 ok(pos
== sum
, "Position %u expected %u\n", (UINT
)pos
, sum
);
230 hr
= IAudioCaptureClient_ReleaseBuffer(acc
, 0);
231 ok(hr
== S_OK
, "Releasing 0 returns %08x\n", hr
);
233 /* GCP did not decrement, no data consumed */
234 hr
= IAudioClient_GetCurrentPadding(ac
, &frames
);
235 ok(hr
== S_OK
, "GetCurrentPadding call returns %08x\n", hr
);
236 ok(frames
== pad
|| frames
== pad
+ next
/* concurrent feeder */,
237 "GCP %u past ReleaseBuffer(0) initially %u\n", frames
, pad
);
239 /* should re-get the same data */
240 hr
= IAudioCaptureClient_GetBuffer(acc
, &data
, &frames
, &flags
, &pos2
, &qpc2
);
241 ok(hr
== S_OK
, "Valid IAudioCaptureClient_GetBuffer returns %08x\n", hr
);
242 ok(frames2
== frames
, "GetBuffer after ReleaseBuffer(0) %u/%u\n", frames2
, frames
);
243 ok(pos2
== pos
, "Position after ReleaseBuffer(0) %u/%u\n", (UINT
)pos2
, (UINT
)pos
);
244 todo_wine
ok(qpc2
== qpc
, "HPC after ReleaseBuffer(0) %u vs. %u\n", (UINT
)qpc2
, (UINT
)qpc
);
247 /* trace after the GCP test because log output to MS-DOS console disturbs timing */
248 trace("Sleep.1 position %d pad %u flags %x, amount of frames locked: %u\n",
249 hr
==S_OK
? (UINT
)pos
: -1, pad
, flags
, frames
);
252 UINT32 frames2
= 0xabadcafe;
253 BYTE
*data2
= (void*)0xdeadf00d;
256 ok(pos
== sum
, "Position %u expected %u\n", (UINT
)pos
, sum
);
258 pos
= qpc
= 0xdeadbeef;
259 hr
= IAudioCaptureClient_GetBuffer(acc
, &data2
, &frames2
, &flags
, &pos
, &qpc
);
260 ok(hr
== AUDCLNT_E_OUT_OF_ORDER
, "Out of order IAudioCaptureClient_GetBuffer returns %08x\n", hr
);
261 ok(frames2
== 0xabadcafe, "Out of order frames changed to %x\n", frames2
);
262 ok(data2
== (void*)0xdeadf00d, "Out of order data changed to %p\n", data2
);
263 ok(flags
== 0xabadcafe, "Out of order flags changed to %x\n", flags
);
264 ok(pos
== 0xdeadbeef, "Out of order position changed to %x\n", (UINT
)pos
);
265 ok(qpc
== 0xdeadbeef, "Out of order timer changed to %x\n", (UINT
)qpc
);
267 hr
= IAudioCaptureClient_ReleaseBuffer(acc
, frames
+1);
268 ok(hr
== AUDCLNT_E_INVALID_SIZE
, "Releasing buffer+1 returns %08x\n", hr
);
270 hr
= IAudioCaptureClient_ReleaseBuffer(acc
, 1);
271 ok(hr
== AUDCLNT_E_INVALID_SIZE
, "Releasing 1 returns %08x\n", hr
);
273 hr
= IAudioClient_Reset(ac
);
274 ok(hr
== AUDCLNT_E_NOT_STOPPED
, "Reset failed: %08x\n", hr
);
277 hr
= IAudioCaptureClient_ReleaseBuffer(acc
, frames
);
278 ok(hr
== S_OK
, "Releasing buffer returns %08x\n", hr
);
282 hr
= IAudioCaptureClient_ReleaseBuffer(acc
, frames
);
283 ok(hr
== AUDCLNT_E_OUT_OF_ORDER
, "Releasing buffer twice returns %08x\n", hr
);
287 ok(next
== frames
, "GetNextPacketSize %u vs. GetDevicePeriod %u\n", next
, frames
);
289 /* GetBufferSize is not a multiple of the period size! */
290 hr
= IAudioClient_GetBufferSize(ac
, &next
);
291 ok(hr
== S_OK
, "GetBufferSize failed: %08x\n", hr
);
292 trace("GetBufferSize %u period size %u\n", next
, frames
);
294 Sleep(400); /* overrun */
296 hr
= IAudioClient_GetCurrentPadding(ac
, &pad
);
297 ok(hr
== S_OK
, "GetCurrentPadding call returns %08x\n", hr
);
299 hr
= IAudioCaptureClient_GetBuffer(acc
, &data
, &frames
, &flags
, &pos
, &qpc
);
300 ok(hr
== S_OK
, "Valid IAudioCaptureClient_GetBuffer returns %08x\n", hr
);
302 trace("Overrun position %d pad %u flags %x, amount of frames locked: %u\n",
303 hr
==S_OK
? (UINT
)pos
: -1, pad
, flags
, frames
);
306 /* The discontinuity is reported here, but is this an old or new packet? */
307 todo_wine
ok(flags
& AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY
, "expect DISCONTINUITY %x\n", flags
);
308 ok(pad
== next
, "GCP %u vs. BufferSize %u\n", (UINT32
)pad
, next
);
310 /* Native's position is one period further than what we read.
311 * Perhaps that's precisely the meaning of DATA_DISCONTINUITY:
312 * signal when the position jump left a gap. */
313 todo_wine
ok(pos
== sum
+ frames
, "Position %u gap %d\n",
314 (UINT
)pos
, (UINT
)pos
- sum
);
315 if(flags
& AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY
)
319 hr
= IAudioCaptureClient_ReleaseBuffer(acc
, frames
);
320 ok(hr
== S_OK
, "Releasing buffer returns %08x\n", hr
);
323 hr
= IAudioClient_GetCurrentPadding(ac
, &pad
);
324 ok(hr
== S_OK
, "GetCurrentPadding call returns %08x\n", hr
);
326 hr
= IAudioCaptureClient_GetBuffer(acc
, &data
, &frames
, &flags
, &pos
, &qpc
);
327 ok(hr
== S_OK
, "Valid IAudioCaptureClient_GetBuffer returns %08x\n", hr
);
329 trace("Cont'ed position %d pad %u flags %x, amount of frames locked: %u\n",
330 hr
==S_OK
? (UINT
)pos
: -1, pad
, flags
, frames
);
333 ok(pos
== sum
, "Position %u expected %u\n", (UINT
)pos
, sum
);
334 ok(!flags
, "flags %u\n", flags
);
336 hr
= IAudioCaptureClient_ReleaseBuffer(acc
, frames
);
337 ok(hr
== S_OK
, "Releasing buffer returns %08x\n", hr
);
341 hr
= IAudioClient_Stop(ac
);
342 ok(hr
== S_OK
, "Stop on a started stream returns %08x\n", hr
);
344 hr
= IAudioClient_Start(ac
);
345 ok(hr
== S_OK
, "Start on a stopped stream returns %08x\n", hr
);
347 hr
= IAudioCaptureClient_GetBuffer(acc
, &data
, &frames
, &flags
, &pos
, &qpc
);
348 ok(hr
== S_OK
, "Valid IAudioCaptureClient_GetBuffer returns %08x\n", hr
);
350 hr
= IAudioClient_GetCurrentPadding(ac
, &pad
);
351 ok(hr
== S_OK
, "GetCurrentPadding call returns %08x\n", hr
);
353 trace("Restart position %d pad %u flags %x, amount of frames locked: %u\n",
354 hr
==S_OK
? (UINT
)pos
: -1, pad
, flags
, frames
);
355 ok(pad
> sum
, "restarted GCP %u\n", pad
); /* GCP is still near buffer size */
358 ok(pos
== sum
, "Position %u expected %u\n", (UINT
)pos
, sum
);
359 ok(!flags
, "flags %u\n", flags
);
361 hr
= IAudioCaptureClient_ReleaseBuffer(acc
, frames
);
362 ok(hr
== S_OK
, "Releasing buffer returns %08x\n", hr
);
366 hr
= IAudioClient_Stop(ac
);
367 ok(hr
== S_OK
, "Stop on a started stream returns %08x\n", hr
);
369 hr
= IAudioClient_Reset(ac
);
370 ok(hr
== S_OK
, "Reset on a stopped stream returns %08x\n", hr
);
373 hr
= IAudioClient_Start(ac
);
374 ok(hr
== S_OK
, "Start on a stopped stream returns %08x\n", hr
);
376 hr
= IAudioClient_GetCurrentPadding(ac
, &pad
);
377 ok(hr
== S_OK
, "GetCurrentPadding call returns %08x\n", hr
);
380 hr
= IAudioCaptureClient_GetBuffer(acc
, &data
, &frames
, &flags
, &pos
, &qpc
);
381 ok(hr
== AUDCLNT_S_BUFFER_EMPTY
|| /*PulseAudio*/hr
== S_OK
,
382 "Initial IAudioCaptureClient_GetBuffer returns %08x\n", hr
);
384 trace("Reset position %d pad %u flags %x, amount of frames locked: %u\n",
385 hr
==S_OK
? (UINT
)pos
: -1, pad
, flags
, frames
);
388 /* Only PulseAudio goes here; despite snd_pcm_drop it manages
389 * to fill GetBufferSize with a single snd_pcm_read */
390 trace("Test marked todo: only PulseAudio gets here\n");
391 todo_wine
ok(flags
& AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY
, "expect DISCONTINUITY %x\n", flags
);
392 /* Reset zeroes padding, not the position */
393 ok(pos
>= sum
, "Position %u last %u\n", (UINT
)pos
, sum
);
394 /*sum = pos; check after next GetBuffer */
396 hr
= IAudioCaptureClient_ReleaseBuffer(acc
, frames
);
397 ok(hr
== S_OK
, "Releasing buffer returns %08x\n", hr
);
400 else if(hr
== AUDCLNT_S_BUFFER_EMPTY
){
401 ok(!pad
, "resetted GCP %u\n", pad
);
405 hr
= IAudioClient_GetCurrentPadding(ac
, &pad
);
406 ok(hr
== S_OK
, "GetCurrentPadding call returns %08x\n", hr
);
408 hr
= IAudioCaptureClient_GetBuffer(acc
, &data
, &frames
, &flags
, &pos
, &qpc
);
409 ok(hr
== S_OK
, "Valid IAudioCaptureClient_GetBuffer returns %08x\n", hr
);
410 trace("Running position %d pad %u flags %x, amount of frames locked: %u\n",
411 hr
==S_OK
? (UINT
)pos
: -1, pad
, flags
, frames
);
414 /* Some w7 machines signal DATA_DISCONTINUITY here following the
415 * previous AUDCLNT_S_BUFFER_EMPTY, others not. What logic? */
416 ok(pos
>= sum
, "Position %u gap %d\n", (UINT
)pos
, (UINT
)pos
- sum
);
417 IAudioCaptureClient_ReleaseBuffer(acc
, frames
);
420 hr
= IAudioClient_Stop(ac
);
421 ok(hr
== S_OK
, "Stop failed: %08x\n", hr
);
423 ok(ResetEvent(handle
), "ResetEvent\n");
425 /* Still receiving events! */
426 r
= WaitForSingleObject(handle
, 20);
427 ok(r
== WAIT_OBJECT_0
, "Wait(event) after Stop gave %x\n", r
);
429 hr
= IAudioClient_Reset(ac
);
430 ok(hr
== S_OK
, "Reset failed: %08x\n", hr
);
432 ok(ResetEvent(handle
), "ResetEvent\n");
434 r
= WaitForSingleObject(handle
, 120);
435 ok(r
== WAIT_OBJECT_0
, "Wait(event) after Reset gave %x\n", r
);
437 hr
= IAudioClient_SetEventHandle(ac
, NULL
);
438 ok(hr
== E_INVALIDARG
, "SetEventHandle(NULL) returns %08x\n", hr
);
440 r
= WaitForSingleObject(handle
, 70);
441 ok(r
== WAIT_OBJECT_0
, "Wait(NULL event) gave %x\n", r
);
443 hr
= IAudioClient_Start(ac
);
444 ok(hr
== S_OK
, "Start failed: %08x\n", hr
);
446 IAudioCaptureClient_Release(acc
);
449 static void test_audioclient(void)
455 WAVEFORMATEX
*pwfx
, *pwfx2
;
456 REFERENCE_TIME t1
, t2
;
459 hr
= IMMDevice_Activate(dev
, &IID_IAudioClient
, CLSCTX_INPROC_SERVER
,
461 ok(hr
== S_OK
, "Activation failed with %08x\n", hr
);
465 handle
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
467 hr
= IAudioClient_QueryInterface(ac
, &IID_IUnknown
, NULL
);
468 ok(hr
== E_POINTER
, "QueryInterface(NULL) returned %08x\n", hr
);
470 unk
= (void*)(LONG_PTR
)0x12345678;
471 hr
= IAudioClient_QueryInterface(ac
, &IID_NULL
, (void**)&unk
);
472 ok(hr
== E_NOINTERFACE
, "QueryInterface(IID_NULL) returned %08x\n", hr
);
473 ok(!unk
, "QueryInterface(IID_NULL) returned non-null pointer %p\n", unk
);
475 hr
= IAudioClient_QueryInterface(ac
, &IID_IUnknown
, (void**)&unk
);
476 ok(hr
== S_OK
, "QueryInterface(IID_IUnknown) returned %08x\n", hr
);
479 ref
= IUnknown_Release(unk
);
480 ok(ref
== 1, "Released count is %u\n", ref
);
483 hr
= IAudioClient_QueryInterface(ac
, &IID_IAudioClient
, (void**)&unk
);
484 ok(hr
== S_OK
, "QueryInterface(IID_IAudioClient) returned %08x\n", hr
);
487 ref
= IUnknown_Release(unk
);
488 ok(ref
== 1, "Released count is %u\n", ref
);
491 hr
= IAudioClient_GetDevicePeriod(ac
, NULL
, NULL
);
492 ok(hr
== E_POINTER
, "Invalid GetDevicePeriod call returns %08x\n", hr
);
494 hr
= IAudioClient_GetDevicePeriod(ac
, &t1
, NULL
);
495 ok(hr
== S_OK
, "Valid GetDevicePeriod call returns %08x\n", hr
);
497 hr
= IAudioClient_GetDevicePeriod(ac
, NULL
, &t2
);
498 ok(hr
== S_OK
, "Valid GetDevicePeriod call returns %08x\n", hr
);
500 hr
= IAudioClient_GetDevicePeriod(ac
, &t1
, &t2
);
501 ok(hr
== S_OK
, "Valid GetDevicePeriod call returns %08x\n", hr
);
502 trace("Returned periods: %u.%04u ms %u.%04u ms\n",
503 (UINT
)(t1
/10000), (UINT
)(t1
% 10000),
504 (UINT
)(t2
/10000), (UINT
)(t2
% 10000));
506 hr
= IAudioClient_GetMixFormat(ac
, NULL
);
507 ok(hr
== E_POINTER
, "GetMixFormat returns %08x\n", hr
);
509 hr
= IAudioClient_GetMixFormat(ac
, &pwfx
);
510 ok(hr
== S_OK
, "Valid GetMixFormat returns %08x\n", hr
);
514 trace("pwfx: %p\n", pwfx
);
515 trace("Tag: %04x\n", pwfx
->wFormatTag
);
516 trace("bits: %u\n", pwfx
->wBitsPerSample
);
517 trace("chan: %u\n", pwfx
->nChannels
);
518 trace("rate: %u\n", pwfx
->nSamplesPerSec
);
519 trace("align: %u\n", pwfx
->nBlockAlign
);
520 trace("extra: %u\n", pwfx
->cbSize
);
521 ok(pwfx
->wFormatTag
== WAVE_FORMAT_EXTENSIBLE
, "wFormatTag is %x\n", pwfx
->wFormatTag
);
522 if (pwfx
->wFormatTag
== WAVE_FORMAT_EXTENSIBLE
)
524 WAVEFORMATEXTENSIBLE
*pwfxe
= (void*)pwfx
;
525 trace("Res: %u\n", pwfxe
->Samples
.wReserved
);
526 trace("Mask: %x\n", pwfxe
->dwChannelMask
);
528 IsEqualGUID(&pwfxe
->SubFormat
, &KSDATAFORMAT_SUBTYPE_PCM
)?"PCM":
529 (IsEqualGUID(&pwfxe
->SubFormat
,
530 &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
)?"FLOAT":"Other"));
533 hr
= IAudioClient_IsFormatSupported(ac
, AUDCLNT_SHAREMODE_SHARED
, pwfx
, &pwfx2
);
534 ok(hr
== S_OK
, "Valid IsFormatSupported(Shared) call returns %08x\n", hr
);
535 ok(pwfx2
== NULL
, "pwfx2 is non-null\n");
536 CoTaskMemFree(pwfx2
);
538 hr
= IAudioClient_IsFormatSupported(ac
, AUDCLNT_SHAREMODE_SHARED
, NULL
, NULL
);
539 ok(hr
== E_POINTER
, "IsFormatSupported(NULL) call returns %08x\n", hr
);
541 hr
= IAudioClient_IsFormatSupported(ac
, AUDCLNT_SHAREMODE_SHARED
, pwfx
, NULL
);
542 ok(hr
== E_POINTER
, "IsFormatSupported(Shared,NULL) call returns %08x\n", hr
);
544 hr
= IAudioClient_IsFormatSupported(ac
, AUDCLNT_SHAREMODE_EXCLUSIVE
, pwfx
, NULL
);
545 ok(hr
== S_OK
|| hr
== AUDCLNT_E_UNSUPPORTED_FORMAT
, "IsFormatSupported(Exclusive) call returns %08x\n", hr
);
547 hr
= IAudioClient_IsFormatSupported(ac
, AUDCLNT_SHAREMODE_EXCLUSIVE
, pwfx
, &pwfx2
);
548 ok(hr
== S_OK
|| hr
== AUDCLNT_E_UNSUPPORTED_FORMAT
, "IsFormatSupported(Exclusive) call returns %08x\n", hr
);
549 ok(pwfx2
== NULL
, "pwfx2 non-null on exclusive IsFormatSupported\n");
551 hr
= IAudioClient_IsFormatSupported(ac
, 0xffffffff, pwfx
, NULL
);
552 ok(hr
== E_INVALIDARG
/*w32*/ ||
553 broken(hr
== AUDCLNT_E_UNSUPPORTED_FORMAT
/*w64 response from exclusive mode driver */),
554 "IsFormatSupported(0xffffffff) call returns %08x\n", hr
);
557 test_uninitialized(ac
);
559 hr
= IAudioClient_Initialize(ac
, 3, 0, 5000000, 0, pwfx
, NULL
);
560 ok(hr
== AUDCLNT_E_NOT_INITIALIZED
, "Initialize with invalid sharemode returns %08x\n", hr
);
562 hr
= IAudioClient_Initialize(ac
, AUDCLNT_SHAREMODE_SHARED
, 0xffffffff, 5000000, 0, pwfx
, NULL
);
563 ok(hr
== E_INVALIDARG
|| hr
== AUDCLNT_E_INVALID_STREAM_FLAG
, "Initialize with invalid flags returns %08x\n", hr
);
565 /* A period != 0 is ignored and the call succeeds.
566 * Since we can only initialize successfully once, skip those tests.
568 hr
= IAudioClient_Initialize(ac
, AUDCLNT_SHAREMODE_SHARED
, 0, 5000000, 0, NULL
, NULL
);
569 ok(hr
== E_POINTER
, "Initialize with null format returns %08x\n", hr
);
571 hr
= IAudioClient_Initialize(ac
, AUDCLNT_SHAREMODE_SHARED
, AUDCLNT_STREAMFLAGS_EVENTCALLBACK
, 4987654, 0, pwfx
, NULL
);
572 ok(hr
== S_OK
, "Valid Initialize returns %08x\n", hr
);
576 skip("Cannot initialize %08x, remainder of tests is useless\n", hr
);
581 hr
= IAudioClient_GetStreamLatency(ac
, NULL
);
582 ok(hr
== E_POINTER
, "GetStreamLatency(NULL) call returns %08x\n", hr
);
584 hr
= IAudioClient_GetStreamLatency(ac
, &t1
);
585 ok(hr
== S_OK
, "Valid GetStreamLatency call returns %08x\n", hr
);
586 trace("Returned latency: %u.%04u ms\n",
587 (UINT
)(t1
/10000), (UINT
)(t1
% 10000));
589 hr
= IAudioClient_Initialize(ac
, AUDCLNT_SHAREMODE_SHARED
, 0, 5000000, 0, pwfx
, NULL
);
590 ok(hr
== AUDCLNT_E_ALREADY_INITIALIZED
, "Calling Initialize twice returns %08x\n", hr
);
592 hr
= IAudioClient_SetEventHandle(ac
, NULL
);
593 ok(hr
== E_INVALIDARG
, "SetEventHandle(NULL) returns %08x\n", hr
);
595 hr
= IAudioClient_Start(ac
);
596 ok(hr
== AUDCLNT_E_EVENTHANDLE_NOT_SET
, "Start before SetEventHandle returns %08x\n", hr
);
598 hr
= IAudioClient_SetEventHandle(ac
, handle
);
599 ok(hr
== S_OK
, "SetEventHandle returns %08x\n", hr
);
601 hr
= IAudioClient_Reset(ac
);
602 ok(hr
== S_OK
, "Reset on a resetted stream returns %08x\n", hr
);
604 hr
= IAudioClient_Stop(ac
);
605 ok(hr
== S_FALSE
, "Stop on a stopped stream returns %08x\n", hr
);
607 hr
= IAudioClient_Start(ac
);
608 ok(hr
== S_OK
, "Start on a stopped stream returns %08x\n", hr
);
610 test_capture(ac
, handle
, pwfx
);
612 IAudioClient_Release(ac
);
617 static void test_streamvolume(void)
620 IAudioStreamVolume
*asv
;
626 hr
= IMMDevice_Activate(dev
, &IID_IAudioClient
, CLSCTX_INPROC_SERVER
,
628 ok(hr
== S_OK
, "Activation failed with %08x\n", hr
);
632 hr
= IAudioClient_GetMixFormat(ac
, &fmt
);
633 ok(hr
== S_OK
, "GetMixFormat failed: %08x\n", hr
);
635 hr
= IAudioClient_Initialize(ac
, AUDCLNT_SHAREMODE_SHARED
, 0, 5000000,
637 ok(hr
== S_OK
, "Initialize failed: %08x\n", hr
);
641 hr
= IAudioClient_GetService(ac
, &IID_IAudioStreamVolume
, (void**)&asv
);
642 ok(hr
== S_OK
, "GetService failed: %08x\n", hr
);
644 hr
= IAudioStreamVolume_GetChannelCount(asv
, NULL
);
645 ok(hr
== E_POINTER
, "GetChannelCount gave wrong error: %08x\n", hr
);
647 hr
= IAudioStreamVolume_GetChannelCount(asv
, &chans
);
648 ok(hr
== S_OK
, "GetChannelCount failed: %08x\n", hr
);
649 ok(chans
== fmt
->nChannels
, "GetChannelCount gave wrong number of channels: %d\n", chans
);
651 hr
= IAudioStreamVolume_GetChannelVolume(asv
, fmt
->nChannels
, NULL
);
652 ok(hr
== E_POINTER
, "GetChannelCount gave wrong error: %08x\n", hr
);
654 hr
= IAudioStreamVolume_GetChannelVolume(asv
, fmt
->nChannels
, &vol
);
655 ok(hr
== E_INVALIDARG
, "GetChannelCount gave wrong error: %08x\n", hr
);
657 hr
= IAudioStreamVolume_GetChannelVolume(asv
, 0, NULL
);
658 ok(hr
== E_POINTER
, "GetChannelCount gave wrong error: %08x\n", hr
);
660 hr
= IAudioStreamVolume_GetChannelVolume(asv
, 0, &vol
);
661 ok(hr
== S_OK
, "GetChannelCount failed: %08x\n", hr
);
662 ok(vol
== 1.f
, "Channel volume was not 1: %f\n", vol
);
664 hr
= IAudioStreamVolume_SetChannelVolume(asv
, fmt
->nChannels
, -1.f
);
665 ok(hr
== E_INVALIDARG
, "SetChannelVolume gave wrong error: %08x\n", hr
);
667 hr
= IAudioStreamVolume_SetChannelVolume(asv
, 0, -1.f
);
668 ok(hr
== E_INVALIDARG
, "SetChannelVolume gave wrong error: %08x\n", hr
);
670 hr
= IAudioStreamVolume_SetChannelVolume(asv
, 0, 2.f
);
671 ok(hr
== E_INVALIDARG
, "SetChannelVolume gave wrong error: %08x\n", hr
);
673 hr
= IAudioStreamVolume_SetChannelVolume(asv
, 0, 0.2f
);
674 ok(hr
== S_OK
, "SetChannelVolume failed: %08x\n", hr
);
676 hr
= IAudioStreamVolume_GetChannelVolume(asv
, 0, &vol
);
677 ok(hr
== S_OK
, "GetChannelCount failed: %08x\n", hr
);
678 ok(fabsf(vol
- 0.2f
) < 0.05f
, "Channel volume wasn't 0.2: %f\n", vol
);
680 hr
= IAudioStreamVolume_GetAllVolumes(asv
, 0, NULL
);
681 ok(hr
== E_POINTER
, "GetAllVolumes gave wrong error: %08x\n", hr
);
683 hr
= IAudioStreamVolume_GetAllVolumes(asv
, fmt
->nChannels
, NULL
);
684 ok(hr
== E_POINTER
, "GetAllVolumes gave wrong error: %08x\n", hr
);
686 vols
= HeapAlloc(GetProcessHeap(), 0, fmt
->nChannels
* sizeof(float));
687 ok(vols
!= NULL
, "HeapAlloc failed\n");
689 hr
= IAudioStreamVolume_GetAllVolumes(asv
, fmt
->nChannels
- 1, vols
);
690 ok(hr
== E_INVALIDARG
, "GetAllVolumes gave wrong error: %08x\n", hr
);
692 hr
= IAudioStreamVolume_GetAllVolumes(asv
, fmt
->nChannels
, vols
);
693 ok(hr
== S_OK
, "GetAllVolumes failed: %08x\n", hr
);
694 ok(fabsf(vols
[0] - 0.2f
) < 0.05f
, "Channel 0 volume wasn't 0.2: %f\n", vol
);
695 for(i
= 1; i
< fmt
->nChannels
; ++i
)
696 ok(vols
[i
] == 1.f
, "Channel %d volume is not 1: %f\n", i
, vols
[i
]);
698 hr
= IAudioStreamVolume_SetAllVolumes(asv
, 0, NULL
);
699 ok(hr
== E_POINTER
, "SetAllVolumes gave wrong error: %08x\n", hr
);
701 hr
= IAudioStreamVolume_SetAllVolumes(asv
, fmt
->nChannels
, NULL
);
702 ok(hr
== E_POINTER
, "SetAllVolumes gave wrong error: %08x\n", hr
);
704 hr
= IAudioStreamVolume_SetAllVolumes(asv
, fmt
->nChannels
- 1, vols
);
705 ok(hr
== E_INVALIDARG
, "SetAllVolumes gave wrong error: %08x\n", hr
);
707 hr
= IAudioStreamVolume_SetAllVolumes(asv
, fmt
->nChannels
, vols
);
708 ok(hr
== S_OK
, "SetAllVolumes failed: %08x\n", hr
);
710 HeapFree(GetProcessHeap(), 0, vols
);
711 IAudioStreamVolume_Release(asv
);
712 IAudioClient_Release(ac
);
716 static void test_channelvolume(void)
719 IChannelAudioVolume
*acv
;
725 hr
= IMMDevice_Activate(dev
, &IID_IAudioClient
, CLSCTX_INPROC_SERVER
,
727 ok(hr
== S_OK
, "Activation failed with %08x\n", hr
);
731 hr
= IAudioClient_GetMixFormat(ac
, &fmt
);
732 ok(hr
== S_OK
, "GetMixFormat failed: %08x\n", hr
);
734 hr
= IAudioClient_Initialize(ac
, AUDCLNT_SHAREMODE_SHARED
,
735 AUDCLNT_STREAMFLAGS_NOPERSIST
, 5000000, 0, fmt
, NULL
);
736 ok(hr
== S_OK
, "Initialize failed: %08x\n", hr
);
738 hr
= IAudioClient_GetService(ac
, &IID_IChannelAudioVolume
, (void**)&acv
);
739 ok(hr
== S_OK
, "GetService failed: %08x\n", hr
);
743 hr
= IChannelAudioVolume_GetChannelCount(acv
, NULL
);
744 ok(hr
== NULL_PTR_ERR
, "GetChannelCount gave wrong error: %08x\n", hr
);
746 hr
= IChannelAudioVolume_GetChannelCount(acv
, &chans
);
747 ok(hr
== S_OK
, "GetChannelCount failed: %08x\n", hr
);
748 ok(chans
== fmt
->nChannels
, "GetChannelCount gave wrong number of channels: %d\n", chans
);
750 hr
= IChannelAudioVolume_GetChannelVolume(acv
, fmt
->nChannels
, NULL
);
751 ok(hr
== NULL_PTR_ERR
, "GetChannelCount gave wrong error: %08x\n", hr
);
753 hr
= IChannelAudioVolume_GetChannelVolume(acv
, fmt
->nChannels
, &vol
);
754 ok(hr
== E_INVALIDARG
, "GetChannelCount gave wrong error: %08x\n", hr
);
756 hr
= IChannelAudioVolume_GetChannelVolume(acv
, 0, NULL
);
757 ok(hr
== NULL_PTR_ERR
, "GetChannelCount gave wrong error: %08x\n", hr
);
759 hr
= IChannelAudioVolume_GetChannelVolume(acv
, 0, &vol
);
760 ok(hr
== S_OK
, "GetChannelCount failed: %08x\n", hr
);
761 ok(vol
== 1.f
, "Channel volume was not 1: %f\n", vol
);
763 hr
= IChannelAudioVolume_SetChannelVolume(acv
, fmt
->nChannels
, -1.f
, NULL
);
764 ok(hr
== E_INVALIDARG
, "SetChannelVolume gave wrong error: %08x\n", hr
);
766 hr
= IChannelAudioVolume_SetChannelVolume(acv
, 0, -1.f
, NULL
);
767 ok(hr
== E_INVALIDARG
, "SetChannelVolume gave wrong error: %08x\n", hr
);
769 hr
= IChannelAudioVolume_SetChannelVolume(acv
, 0, 2.f
, NULL
);
770 ok(hr
== E_INVALIDARG
, "SetChannelVolume gave wrong error: %08x\n", hr
);
772 hr
= IChannelAudioVolume_SetChannelVolume(acv
, 0, 0.2f
, NULL
);
773 ok(hr
== S_OK
, "SetChannelVolume failed: %08x\n", hr
);
775 hr
= IChannelAudioVolume_GetChannelVolume(acv
, 0, &vol
);
776 ok(hr
== S_OK
, "GetChannelCount failed: %08x\n", hr
);
777 ok(fabsf(vol
- 0.2f
) < 0.05f
, "Channel volume wasn't 0.2: %f\n", vol
);
779 hr
= IChannelAudioVolume_GetAllVolumes(acv
, 0, NULL
);
780 ok(hr
== NULL_PTR_ERR
, "GetAllVolumes gave wrong error: %08x\n", hr
);
782 hr
= IChannelAudioVolume_GetAllVolumes(acv
, fmt
->nChannels
, NULL
);
783 ok(hr
== NULL_PTR_ERR
, "GetAllVolumes gave wrong error: %08x\n", hr
);
785 vols
= HeapAlloc(GetProcessHeap(), 0, fmt
->nChannels
* sizeof(float));
786 ok(vols
!= NULL
, "HeapAlloc failed\n");
788 hr
= IChannelAudioVolume_GetAllVolumes(acv
, fmt
->nChannels
- 1, vols
);
789 ok(hr
== E_INVALIDARG
, "GetAllVolumes gave wrong error: %08x\n", hr
);
791 hr
= IChannelAudioVolume_GetAllVolumes(acv
, fmt
->nChannels
, vols
);
792 ok(hr
== S_OK
, "GetAllVolumes failed: %08x\n", hr
);
793 ok(fabsf(vols
[0] - 0.2f
) < 0.05f
, "Channel 0 volume wasn't 0.2: %f\n", vol
);
794 for(i
= 1; i
< fmt
->nChannels
; ++i
)
795 ok(vols
[i
] == 1.f
, "Channel %d volume is not 1: %f\n", i
, vols
[i
]);
797 hr
= IChannelAudioVolume_SetAllVolumes(acv
, 0, NULL
, NULL
);
798 ok(hr
== NULL_PTR_ERR
, "SetAllVolumes gave wrong error: %08x\n", hr
);
800 hr
= IChannelAudioVolume_SetAllVolumes(acv
, fmt
->nChannels
, NULL
, NULL
);
801 ok(hr
== NULL_PTR_ERR
, "SetAllVolumes gave wrong error: %08x\n", hr
);
803 hr
= IChannelAudioVolume_SetAllVolumes(acv
, fmt
->nChannels
- 1, vols
, NULL
);
804 ok(hr
== E_INVALIDARG
, "SetAllVolumes gave wrong error: %08x\n", hr
);
806 hr
= IChannelAudioVolume_SetAllVolumes(acv
, fmt
->nChannels
, vols
, NULL
);
807 ok(hr
== S_OK
, "SetAllVolumes failed: %08x\n", hr
);
809 hr
= IChannelAudioVolume_SetChannelVolume(acv
, 0, 1.0f
, NULL
);
810 ok(hr
== S_OK
, "SetChannelVolume failed: %08x\n", hr
);
812 HeapFree(GetProcessHeap(), 0, vols
);
813 IChannelAudioVolume_Release(acv
);
814 IAudioClient_Release(ac
);
818 static void test_simplevolume(void)
821 ISimpleAudioVolume
*sav
;
827 hr
= IMMDevice_Activate(dev
, &IID_IAudioClient
, CLSCTX_INPROC_SERVER
,
829 ok(hr
== S_OK
, "Activation failed with %08x\n", hr
);
833 hr
= IAudioClient_GetMixFormat(ac
, &fmt
);
834 ok(hr
== S_OK
, "GetMixFormat failed: %08x\n", hr
);
836 hr
= IAudioClient_Initialize(ac
, AUDCLNT_SHAREMODE_SHARED
,
837 AUDCLNT_STREAMFLAGS_NOPERSIST
, 5000000, 0, fmt
, NULL
);
838 ok(hr
== S_OK
, "Initialize failed: %08x\n", hr
);
840 hr
= IAudioClient_GetService(ac
, &IID_ISimpleAudioVolume
, (void**)&sav
);
841 ok(hr
== S_OK
, "GetService failed: %08x\n", hr
);
845 hr
= ISimpleAudioVolume_GetMasterVolume(sav
, NULL
);
846 ok(hr
== NULL_PTR_ERR
, "GetMasterVolume gave wrong error: %08x\n", hr
);
848 hr
= ISimpleAudioVolume_GetMasterVolume(sav
, &vol
);
849 ok(hr
== S_OK
, "GetMasterVolume failed: %08x\n", hr
);
850 ok(vol
== 1.f
, "Master volume wasn't 1: %f\n", vol
);
852 hr
= ISimpleAudioVolume_SetMasterVolume(sav
, -1.f
, NULL
);
853 ok(hr
== E_INVALIDARG
, "SetMasterVolume gave wrong error: %08x\n", hr
);
855 hr
= ISimpleAudioVolume_SetMasterVolume(sav
, 2.f
, NULL
);
856 ok(hr
== E_INVALIDARG
, "SetMasterVolume gave wrong error: %08x\n", hr
);
858 hr
= ISimpleAudioVolume_SetMasterVolume(sav
, 0.2f
, NULL
);
859 ok(hr
== S_OK
, "SetMasterVolume failed: %08x\n", hr
);
861 hr
= ISimpleAudioVolume_GetMasterVolume(sav
, &vol
);
862 ok(hr
== S_OK
, "GetMasterVolume failed: %08x\n", hr
);
863 ok(fabsf(vol
- 0.2f
) < 0.05f
, "Master volume wasn't 0.2: %f\n", vol
);
865 hr
= ISimpleAudioVolume_GetMute(sav
, NULL
);
866 ok(hr
== NULL_PTR_ERR
, "GetMute gave wrong error: %08x\n", hr
);
869 hr
= ISimpleAudioVolume_GetMute(sav
, &mute
);
870 ok(hr
== S_OK
, "GetMute failed: %08x\n", hr
);
871 ok(mute
== FALSE
, "Session is already muted\n");
873 hr
= ISimpleAudioVolume_SetMute(sav
, TRUE
, NULL
);
874 ok(hr
== S_OK
, "SetMute failed: %08x\n", hr
);
877 hr
= ISimpleAudioVolume_GetMute(sav
, &mute
);
878 ok(hr
== S_OK
, "GetMute failed: %08x\n", hr
);
879 ok(mute
== TRUE
, "Session should have been muted\n");
881 hr
= ISimpleAudioVolume_GetMasterVolume(sav
, &vol
);
882 ok(hr
== S_OK
, "GetMasterVolume failed: %08x\n", hr
);
883 ok(fabsf(vol
- 0.2f
) < 0.05f
, "Master volume wasn't 0.2: %f\n", vol
);
885 hr
= ISimpleAudioVolume_SetMasterVolume(sav
, 1.f
, NULL
);
886 ok(hr
== S_OK
, "SetMasterVolume failed: %08x\n", hr
);
889 hr
= ISimpleAudioVolume_GetMute(sav
, &mute
);
890 ok(hr
== S_OK
, "GetMute failed: %08x\n", hr
);
891 ok(mute
== TRUE
, "Session should have been muted\n");
893 hr
= ISimpleAudioVolume_SetMute(sav
, FALSE
, NULL
);
894 ok(hr
== S_OK
, "SetMute failed: %08x\n", hr
);
896 ISimpleAudioVolume_Release(sav
);
897 IAudioClient_Release(ac
);
901 static void test_volume_dependence(void)
903 IAudioClient
*ac
, *ac2
;
904 ISimpleAudioVolume
*sav
;
905 IChannelAudioVolume
*cav
;
906 IAudioStreamVolume
*asv
;
913 hr
= CoCreateGuid(&session
);
914 ok(hr
== S_OK
, "CoCreateGuid failed: %08x\n", hr
);
916 hr
= IMMDevice_Activate(dev
, &IID_IAudioClient
, CLSCTX_INPROC_SERVER
,
918 ok(hr
== S_OK
, "Activation failed with %08x\n", hr
);
922 hr
= IAudioClient_GetMixFormat(ac
, &fmt
);
923 ok(hr
== S_OK
, "GetMixFormat failed: %08x\n", hr
);
925 hr
= IAudioClient_Initialize(ac
, AUDCLNT_SHAREMODE_SHARED
,
926 AUDCLNT_STREAMFLAGS_NOPERSIST
, 5000000, 0, fmt
, &session
);
927 ok(hr
== S_OK
, "Initialize failed: %08x\n", hr
);
929 hr
= IAudioClient_GetService(ac
, &IID_ISimpleAudioVolume
, (void**)&sav
);
930 ok(hr
== S_OK
, "GetService (SimpleAudioVolume) failed: %08x\n", hr
);
932 hr
= IAudioClient_GetService(ac
, &IID_IChannelAudioVolume
, (void**)&cav
);
933 ok(hr
== S_OK
, "GetService (ChannelAudioVolme) failed: %08x\n", hr
);
935 hr
= IAudioClient_GetService(ac
, &IID_IAudioStreamVolume
, (void**)&asv
);
936 ok(hr
== S_OK
, "GetService (AudioStreamVolume) failed: %08x\n", hr
);
940 hr
= IAudioStreamVolume_SetChannelVolume(asv
, 0, 0.2f
);
941 ok(hr
== S_OK
, "ASV_SetChannelVolume failed: %08x\n", hr
);
943 hr
= IChannelAudioVolume_SetChannelVolume(cav
, 0, 0.4f
, NULL
);
944 ok(hr
== S_OK
, "CAV_SetChannelVolume failed: %08x\n", hr
);
946 hr
= ISimpleAudioVolume_SetMasterVolume(sav
, 0.6f
, NULL
);
947 ok(hr
== S_OK
, "SAV_SetMasterVolume failed: %08x\n", hr
);
949 hr
= IAudioStreamVolume_GetChannelVolume(asv
, 0, &vol
);
950 ok(hr
== S_OK
, "ASV_GetChannelVolume failed: %08x\n", hr
);
951 ok(fabsf(vol
- 0.2) < 0.05f
, "ASV_GetChannelVolume gave wrong volume: %f\n", vol
);
953 hr
= IChannelAudioVolume_GetChannelVolume(cav
, 0, &vol
);
954 ok(hr
== S_OK
, "CAV_GetChannelVolume failed: %08x\n", hr
);
955 ok(fabsf(vol
- 0.4) < 0.05f
, "CAV_GetChannelVolume gave wrong volume: %f\n", vol
);
957 hr
= ISimpleAudioVolume_GetMasterVolume(sav
, &vol
);
958 ok(hr
== S_OK
, "SAV_GetMasterVolume failed: %08x\n", hr
);
959 ok(fabsf(vol
- 0.6) < 0.05f
, "SAV_GetMasterVolume gave wrong volume: %f\n", vol
);
961 hr
= IMMDevice_Activate(dev
, &IID_IAudioClient
, CLSCTX_INPROC_SERVER
,
964 IChannelAudioVolume
*cav2
;
965 IAudioStreamVolume
*asv2
;
967 hr
= IAudioClient_Initialize(ac2
, AUDCLNT_SHAREMODE_SHARED
,
968 AUDCLNT_STREAMFLAGS_NOPERSIST
, 5000000, 0, fmt
, &session
);
969 ok(hr
== S_OK
, "Initialize failed: %08x\n", hr
);
971 hr
= IAudioClient_GetService(ac2
, &IID_IChannelAudioVolume
, (void**)&cav2
);
972 ok(hr
== S_OK
, "GetService failed: %08x\n", hr
);
974 hr
= IAudioClient_GetService(ac2
, &IID_IAudioStreamVolume
, (void**)&asv2
);
975 ok(hr
== S_OK
, "GetService failed: %08x\n", hr
);
977 hr
= IChannelAudioVolume_GetChannelVolume(cav2
, 0, &vol
);
978 ok(hr
== S_OK
, "CAV_GetChannelVolume failed: %08x\n", hr
);
979 ok(fabsf(vol
- 0.4) < 0.05f
, "CAV_GetChannelVolume gave wrong volume: %f\n", vol
);
981 hr
= IAudioStreamVolume_GetChannelVolume(asv2
, 0, &vol
);
982 ok(hr
== S_OK
, "ASV_GetChannelVolume failed: %08x\n", hr
);
983 ok(vol
== 1.f
, "ASV_GetChannelVolume gave wrong volume: %f\n", vol
);
985 hr
= IChannelAudioVolume_GetChannelCount(cav2
, &nch
);
986 ok(hr
== S_OK
, "GetChannelCount failed: %08x\n", hr
);
987 ok(nch
== fmt
->nChannels
, "Got wrong channel count, expected %u: %u\n", fmt
->nChannels
, nch
);
989 hr
= IAudioStreamVolume_GetChannelCount(asv2
, &nch
);
990 ok(hr
== S_OK
, "GetChannelCount failed: %08x\n", hr
);
991 ok(nch
== fmt
->nChannels
, "Got wrong channel count, expected %u: %u\n", fmt
->nChannels
, nch
);
993 IAudioStreamVolume_Release(asv2
);
994 IChannelAudioVolume_Release(cav2
);
995 IAudioClient_Release(ac2
);
997 skip("Unable to open the same device twice. Skipping session volume control tests\n");
999 hr
= IChannelAudioVolume_SetChannelVolume(cav
, 0, 1.f
, NULL
);
1000 ok(hr
== S_OK
, "CAV_SetChannelVolume failed: %08x\n", hr
);
1002 hr
= ISimpleAudioVolume_SetMasterVolume(sav
, 1.f
, NULL
);
1003 ok(hr
== S_OK
, "SAV_SetMasterVolume failed: %08x\n", hr
);
1006 ISimpleAudioVolume_Release(sav
);
1007 IChannelAudioVolume_Release(cav
);
1008 IAudioStreamVolume_Release(asv
);
1009 IAudioClient_Release(ac
);
1012 static void test_marshal(void)
1015 IAudioClient
*ac
, *acDest
;
1016 IAudioCaptureClient
*cc
, *ccDest
;
1020 hr
= IMMDevice_Activate(dev
, &IID_IAudioClient
, CLSCTX_INPROC_SERVER
,
1022 ok(hr
== S_OK
, "Activation failed with %08x\n", hr
);
1026 hr
= IAudioClient_GetMixFormat(ac
, &pwfx
);
1027 ok(hr
== S_OK
, "GetMixFormat failed: %08x\n", hr
);
1029 hr
= IAudioClient_Initialize(ac
, AUDCLNT_SHAREMODE_SHARED
, 0, 5000000,
1031 ok(hr
== S_OK
, "Initialize failed: %08x\n", hr
);
1033 CoTaskMemFree(pwfx
);
1035 hr
= IAudioClient_GetService(ac
, &IID_IAudioCaptureClient
, (void**)&cc
);
1036 ok(hr
== S_OK
, "GetService failed: %08x\n", hr
);
1038 IAudioClient_Release(ac
);
1042 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &pStream
);
1043 ok(hr
== S_OK
, "CreateStreamOnHGlobal failed 0x%08x\n", hr
);
1045 /* marshal IAudioClient */
1047 hr
= CoMarshalInterface(pStream
, &IID_IAudioClient
, (IUnknown
*)ac
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1048 ok(hr
== S_OK
, "CoMarshalInterface IAudioClient failed 0x%08x\n", hr
);
1050 IStream_Seek(pStream
, ullZero
, STREAM_SEEK_SET
, NULL
);
1051 hr
= CoUnmarshalInterface(pStream
, &IID_IAudioClient
, (void **)&acDest
);
1052 ok(hr
== S_OK
, "CoUnmarshalInterface IAudioClient failed 0x%08x\n", hr
);
1054 IAudioClient_Release(acDest
);
1056 IStream_Seek(pStream
, ullZero
, STREAM_SEEK_SET
, NULL
);
1057 /* marshal IAudioCaptureClient */
1059 hr
= CoMarshalInterface(pStream
, &IID_IAudioCaptureClient
, (IUnknown
*)cc
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1060 ok(hr
== S_OK
, "CoMarshalInterface IAudioCaptureClient failed 0x%08x\n", hr
);
1062 IStream_Seek(pStream
, ullZero
, STREAM_SEEK_SET
, NULL
);
1063 hr
= CoUnmarshalInterface(pStream
, &IID_IAudioCaptureClient
, (void **)&ccDest
);
1064 ok(hr
== S_OK
, "CoUnmarshalInterface IAudioCaptureClient failed 0x%08x\n", hr
);
1066 IAudioCaptureClient_Release(ccDest
);
1068 IStream_Release(pStream
);
1070 IAudioClient_Release(ac
);
1071 IAudioCaptureClient_Release(cc
);
1078 IMMDeviceEnumerator
*mme
= NULL
;
1080 CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
1081 hr
= CoCreateInstance(&CLSID_MMDeviceEnumerator
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMMDeviceEnumerator
, (void**)&mme
);
1084 skip("mmdevapi not available: 0x%08x\n", hr
);
1088 hr
= IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme
, eCapture
, eMultimedia
, &dev
);
1089 ok(hr
== S_OK
|| hr
== E_NOTFOUND
, "GetDefaultAudioEndpoint failed: 0x%08x\n", hr
);
1090 if (hr
!= S_OK
|| !dev
)
1092 if (hr
== E_NOTFOUND
)
1093 skip("No sound card available\n");
1095 skip("GetDefaultAudioEndpoint returns 0x%08x\n", hr
);
1100 test_streamvolume();
1101 test_channelvolume();
1102 test_simplevolume();
1103 test_volume_dependence();
1106 IMMDevice_Release(dev
);
1110 IMMDeviceEnumerator_Release(mme
);