ReactOS 0.4.15-dev-7788-g1ad9096
capture.c
Go to the documentation of this file.
1/*
2 * Copyright 2010 Maarten Lankhorst for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19/* This test is for audio capture specific mechanisms
20 * Tests:
21 * - IAudioClient with eCapture and IAudioCaptureClient
22 */
23
24#include <math.h>
25
26#include "wine/test.h"
27
28#define COBJMACROS
29
30#ifdef STANDALONE
31#include "initguid.h"
32#endif
33
34#include "unknwn.h"
35#include "uuids.h"
36#include "mmdeviceapi.h"
37#include "audioclient.h"
38
39#define NULL_PTR_ERR MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, RPC_X_NULL_REF_POINTER)
40
41/* undocumented error code */
42#define D3D11_ERROR_4E MAKE_HRESULT(SEVERITY_ERROR, FACILITY_DIRECT3D11, 0x4e)
43
44static IMMDevice *dev = NULL;
46
48{
49 HRESULT hr;
50 UINT32 num;
52
54 IUnknown *unk;
55
56 hr = IAudioClient_GetBufferSize(ac, &num);
57 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetBufferSize call returns %08x\n", hr);
58
59 hr = IAudioClient_GetStreamLatency(ac, &t1);
60 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetStreamLatency call returns %08x\n", hr);
61
62 hr = IAudioClient_GetCurrentPadding(ac, &num);
63 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetCurrentPadding call returns %08x\n", hr);
64
65 hr = IAudioClient_Start(ac);
66 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized Start call returns %08x\n", hr);
67
68 hr = IAudioClient_Stop(ac);
69 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized Stop call returns %08x\n", hr);
70
71 hr = IAudioClient_Reset(ac);
72 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized Reset call returns %08x\n", hr);
73
74 hr = IAudioClient_SetEventHandle(ac, handle);
75 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized SetEventHandle call returns %08x\n", hr);
76
77 hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&unk);
78 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetService call returns %08x\n", hr);
79
81}
82
84{
86 HRESULT hr;
87 UINT32 frames, next, pad, sum = 0;
88 BYTE *data;
90 UINT64 pos, qpc;
91 REFERENCE_TIME period;
92
93 hr = IAudioClient_GetService(ac, &IID_IAudioCaptureClient, (void**)&acc);
94 ok(hr == S_OK, "IAudioClient_GetService(IID_IAudioCaptureClient) returns %08x\n", hr);
95 if (hr != S_OK)
96 return;
97
98 frames = 0xabadcafe;
99 data = (void*)0xdeadf00d;
100 flags = 0xabadcafe;
101 pos = qpc = 0xdeadbeef;
102 hr = IAudioCaptureClient_GetBuffer(acc, &data, &frames, &flags, &pos, &qpc);
103 ok(hr == AUDCLNT_S_BUFFER_EMPTY, "Initial IAudioCaptureClient_GetBuffer returns %08x\n", hr);
104
105 /* should be empty right after start. Otherwise consume one packet */
106 if(hr == S_OK){
107 hr = IAudioCaptureClient_ReleaseBuffer(acc, frames);
108 ok(hr == S_OK, "Releasing buffer returns %08x\n", hr);
109 sum += frames;
110
111 frames = 0xabadcafe;
112 data = (void*)0xdeadf00d;
113 flags = 0xabadcafe;
114 pos = qpc = 0xdeadbeef;
115 hr = IAudioCaptureClient_GetBuffer(acc, &data, &frames, &flags, &pos, &qpc);
116 ok(hr == AUDCLNT_S_BUFFER_EMPTY, "Initial IAudioCaptureClient_GetBuffer returns %08x\n", hr);
117 }
118
119 if(hr == AUDCLNT_S_BUFFER_EMPTY){
120 ok(!frames, "frames changed to %u\n", frames);
121 ok(data == (void*)0xdeadf00d, "data changed to %p\n", data);
122 ok(flags == 0xabadcafe, "flags changed to %x\n", flags);
123 ok(pos == 0xdeadbeef, "position changed to %u\n", (UINT)pos);
124 ok(qpc == 0xdeadbeef, "timer changed to %u\n", (UINT)qpc);
125
126 /* GetNextPacketSize yields 0 if no data is yet available
127 * it is not constantly period_size * SamplesPerSec */
128 hr = IAudioCaptureClient_GetNextPacketSize(acc, &next);
129 ok(hr == S_OK, "IAudioCaptureClient_GetNextPacketSize returns %08x\n", hr);
130 ok(!next, "GetNextPacketSize %u\n", next);
131 }
132
133 hr = IAudioCaptureClient_ReleaseBuffer(acc, frames);
134 ok(hr == S_OK, "Releasing buffer returns %08x\n", hr);
135 sum += frames;
136
137 ok(ResetEvent(handle), "ResetEvent\n");
138
139 hr = IAudioCaptureClient_GetNextPacketSize(acc, &next);
140 ok(hr == S_OK, "IAudioCaptureClient_GetNextPacketSize returns %08x\n", hr);
141
142 hr = IAudioClient_GetCurrentPadding(ac, &pad);
143 ok(hr == S_OK, "GetCurrentPadding call returns %08x\n", hr);
144 ok(next == pad, "GetNextPacketSize %u vs. GCP %u\n", next, pad);
145 /* later GCP will grow, while GNPS is 0 or period size */
146
147 hr = IAudioCaptureClient_GetNextPacketSize(acc, NULL);
148 ok(hr == E_POINTER, "IAudioCaptureClient_GetNextPacketSize(NULL) returns %08x\n", hr);
149
150 data = (void*)0xdeadf00d;
151 frames = 0xdeadbeef;
152 flags = 0xabadcafe;
153 hr = IAudioCaptureClient_GetBuffer(acc, &data, NULL, NULL, NULL, NULL);
154 ok(hr == E_POINTER, "IAudioCaptureClient_GetBuffer(data, NULL, NULL) returns %08x\n", hr);
155
156 hr = IAudioCaptureClient_GetBuffer(acc, NULL, &frames, NULL, NULL, NULL);
157 ok(hr == E_POINTER, "IAudioCaptureClient_GetBuffer(NULL, &frames, NULL) returns %08x\n", hr);
158
159 hr = IAudioCaptureClient_GetBuffer(acc, NULL, NULL, &flags, NULL, NULL);
160 ok(hr == E_POINTER, "IAudioCaptureClient_GetBuffer(NULL, NULL, &flags) returns %08x\n", hr);
161
162 hr = IAudioCaptureClient_GetBuffer(acc, &data, &frames, NULL, NULL, NULL);
163 ok(hr == E_POINTER, "IAudioCaptureClient_GetBuffer(&ata, &frames, NULL) returns %08x\n", hr);
164 ok((DWORD_PTR)data == 0xdeadf00d, "data is reset to %p\n", data);
165 ok(frames == 0xdeadbeef, "frames is reset to %08x\n", frames);
166 ok(flags == 0xabadcafe, "flags is reset to %08x\n", flags);
167
168 hr = IAudioClient_GetDevicePeriod(ac, &period, NULL);
169 ok(hr == S_OK, "GetDevicePeriod failed: %08x\n", hr);
170 period = MulDiv(period, wfx->nSamplesPerSec, 10000000); /* as in render.c */
171
172 ok(WaitForSingleObject(handle, 1000) == WAIT_OBJECT_0, "Waiting on event handle failed!\n");
173
174 data = (void*)0xdeadf00d;
175 hr = IAudioCaptureClient_GetBuffer(acc, &data, &frames, &flags, &pos, &qpc);
176 ok(hr == S_OK || hr == AUDCLNT_S_BUFFER_EMPTY, "Valid IAudioCaptureClient_GetBuffer returns %08x\n", hr);
177 if (hr == S_OK){
178 ok(frames, "Amount of frames locked is 0!\n");
179 /* broken: some w7 machines return pad == 0 and DATA_DISCONTINUITY here,
180 * AUDCLNT_S_BUFFER_EMPTY above, yet pos == 1-2 * period rather than 0 */
181 ok(pos == sum || broken(pos == period || pos == 2*period),
182 "Position %u expected %u\n", (UINT)pos, sum);
183 sum = pos;
184 }else if (hr == AUDCLNT_S_BUFFER_EMPTY){
185 ok(!frames, "Amount of frames locked with empty buffer is %u!\n", frames);
186 ok(data == (void*)0xdeadf00d, "No data changed to %p\n", data);
187 }
188
189 trace("Wait'ed position %d pad %u flags %x, amount of frames locked: %u\n",
190 hr==S_OK ? (UINT)pos : -1, pad, flags, frames);
191
192 hr = IAudioCaptureClient_GetNextPacketSize(acc, &next);
193 ok(hr == S_OK, "IAudioCaptureClient_GetNextPacketSize returns %08x\n", hr);
194 ok(next == frames, "GetNextPacketSize %u vs. GetBuffer %u\n", next, frames);
195
196 hr = IAudioCaptureClient_ReleaseBuffer(acc, frames);
197 ok(hr == S_OK, "Releasing buffer returns %08x\n", hr);
198
199 hr = IAudioCaptureClient_ReleaseBuffer(acc, 0);
200 ok(hr == S_OK, "Releasing 0 returns %08x\n", hr);
201
202 hr = IAudioCaptureClient_GetNextPacketSize(acc, &next);
203 ok(hr == S_OK, "IAudioCaptureClient_GetNextPacketSize returns %08x\n", hr);
204
205 if (frames) {
206 hr = IAudioCaptureClient_ReleaseBuffer(acc, frames);
207 ok(hr == AUDCLNT_E_OUT_OF_ORDER, "Releasing buffer twice returns %08x\n", hr);
208 sum += frames;
209 }
210
211 Sleep(350); /* for sure there's data now */
212
213 hr = IAudioClient_GetCurrentPadding(ac, &pad);
214 ok(hr == S_OK, "GetCurrentPadding call returns %08x\n", hr);
215
219 hr = IAudioCaptureClient_GetNextPacketSize(acc, &next);
220 ok(hr == S_OK, "IAudioCaptureClient_GetNextPacketSize returns %08x\n", hr);
221 ok(next < pad, "GetNextPacketSize %u vs. GCP %u\n", next, pad);
222
223 hr = IAudioCaptureClient_GetBuffer(acc, &data, &frames, &flags, &pos, &qpc);
224 ok(hr == S_OK, "Valid IAudioCaptureClient_GetBuffer returns %08x\n", hr);
225 ok(next == frames, "GetNextPacketSize %u vs. GetBuffer %u\n", next, frames);
226
227 if(hr == S_OK){
228 UINT32 frames2 = frames;
229 UINT64 pos2, qpc2;
230 ok(frames, "Amount of frames locked is 0!\n");
231 ok(pos == sum, "Position %u expected %u\n", (UINT)pos, sum);
232
233 hr = IAudioCaptureClient_ReleaseBuffer(acc, 0);
234 ok(hr == S_OK, "Releasing 0 returns %08x\n", hr);
235
236 /* GCP did not decrement, no data consumed */
237 hr = IAudioClient_GetCurrentPadding(ac, &frames);
238 ok(hr == S_OK, "GetCurrentPadding call returns %08x\n", hr);
239 ok(frames == pad || frames == pad + next /* concurrent feeder */,
240 "GCP %u past ReleaseBuffer(0) initially %u\n", frames, pad);
241
242 /* should re-get the same data */
243 hr = IAudioCaptureClient_GetBuffer(acc, &data, &frames, &flags, &pos2, &qpc2);
244 ok(hr == S_OK, "Valid IAudioCaptureClient_GetBuffer returns %08x\n", hr);
245 ok(frames2 == frames, "GetBuffer after ReleaseBuffer(0) %u/%u\n", frames2, frames);
246 ok(pos2 == pos, "Position after ReleaseBuffer(0) %u/%u\n", (UINT)pos2, (UINT)pos);
247 todo_wine_if(qpc2 != qpc)
248 /* FIXME: Some drivers fail */
249 ok(qpc2 == qpc, "HPC after ReleaseBuffer(0) %u vs. %u\n", (UINT)qpc2, (UINT)qpc);
250 }
251
252 /* trace after the GCP test because log output to MS-DOS console disturbs timing */
253 trace("Sleep.1 position %d pad %u flags %x, amount of frames locked: %u\n",
254 hr==S_OK ? (UINT)pos : -1, pad, flags, frames);
255
256 if(hr == S_OK){
257 UINT32 frames2 = 0xabadcafe;
258 BYTE *data2 = (void*)0xdeadf00d;
259 flags = 0xabadcafe;
260
261 ok(pos == sum, "Position %u expected %u\n", (UINT)pos, sum);
262
263 pos = qpc = 0xdeadbeef;
264 hr = IAudioCaptureClient_GetBuffer(acc, &data2, &frames2, &flags, &pos, &qpc);
265 ok(hr == AUDCLNT_E_OUT_OF_ORDER, "Out of order IAudioCaptureClient_GetBuffer returns %08x\n", hr);
266 ok(frames2 == 0xabadcafe, "Out of order frames changed to %x\n", frames2);
267 ok(data2 == (void*)0xdeadf00d, "Out of order data changed to %p\n", data2);
268 ok(flags == 0xabadcafe, "Out of order flags changed to %x\n", flags);
269 ok(pos == 0xdeadbeef, "Out of order position changed to %x\n", (UINT)pos);
270 ok(qpc == 0xdeadbeef, "Out of order timer changed to %x\n", (UINT)qpc);
271
272 hr = IAudioCaptureClient_ReleaseBuffer(acc, frames+1);
273 ok(hr == AUDCLNT_E_INVALID_SIZE, "Releasing buffer+1 returns %08x\n", hr);
274
275 hr = IAudioCaptureClient_ReleaseBuffer(acc, 1);
276 ok(hr == AUDCLNT_E_INVALID_SIZE, "Releasing 1 returns %08x\n", hr);
277
278 hr = IAudioClient_Reset(ac);
279 ok(hr == AUDCLNT_E_NOT_STOPPED, "Reset failed: %08x\n", hr);
280 }
281
282 hr = IAudioCaptureClient_ReleaseBuffer(acc, frames);
283 ok(hr == S_OK, "Releasing buffer returns %08x\n", hr);
284
285 if (frames) {
286 sum += frames;
287 hr = IAudioCaptureClient_ReleaseBuffer(acc, frames);
288 ok(hr == AUDCLNT_E_OUT_OF_ORDER, "Releasing buffer twice returns %08x\n", hr);
289 }
290
291 frames = period;
292 ok(next == frames, "GetNextPacketSize %u vs. GetDevicePeriod %u\n", next, frames);
293
294 /* GetBufferSize is not a multiple of the period size! */
295 hr = IAudioClient_GetBufferSize(ac, &next);
296 ok(hr == S_OK, "GetBufferSize failed: %08x\n", hr);
297 trace("GetBufferSize %u period size %u\n", next, frames);
298
299 Sleep(400); /* overrun */
300
301 hr = IAudioClient_GetCurrentPadding(ac, &pad);
302 ok(hr == S_OK, "GetCurrentPadding call returns %08x\n", hr);
303
304 hr = IAudioCaptureClient_GetBuffer(acc, &data, &frames, &flags, &pos, &qpc);
305 ok(hr == S_OK, "Valid IAudioCaptureClient_GetBuffer returns %08x\n", hr);
306
307 trace("Overrun position %d pad %u flags %x, amount of frames locked: %u\n",
308 hr==S_OK ? (UINT)pos : -1, pad, flags, frames);
309
310 if(hr == S_OK){
312 /* Native's position is one period further than what we read.
313 * Perhaps that's precisely the meaning of DATA_DISCONTINUITY:
314 * signal when the position jump left a gap. */
315 ok(pos == sum + frames, "Position %u last %u frames %u\n", (UINT)pos, sum, frames);
316 sum = pos;
317 }else{ /* win10 */
318 ok(pos == sum, "Position %u last %u frames %u\n", (UINT)pos, sum, frames);
319 }
320
321 ok(pad == next, "GCP %u vs. BufferSize %u\n", (UINT32)pad, next);
322 }
323
324 hr = IAudioCaptureClient_ReleaseBuffer(acc, frames);
325 ok(hr == S_OK, "Releasing buffer returns %08x\n", hr);
326 sum += frames;
327
328 hr = IAudioClient_GetCurrentPadding(ac, &pad);
329 ok(hr == S_OK, "GetCurrentPadding call returns %08x\n", hr);
330
331 hr = IAudioCaptureClient_GetBuffer(acc, &data, &frames, &flags, &pos, &qpc);
332 ok(hr == S_OK, "Valid IAudioCaptureClient_GetBuffer returns %08x\n", hr);
333
334 trace("Cont'ed position %d pad %u flags %x, amount of frames locked: %u\n",
335 hr==S_OK ? (UINT)pos : -1, pad, flags, frames);
336
337 if(hr == S_OK){
338 ok(pos == sum, "Position %u expected %u\n", (UINT)pos, sum);
339 ok(!flags, "flags %u\n", flags);
340
341 hr = IAudioCaptureClient_ReleaseBuffer(acc, frames);
342 ok(hr == S_OK, "Releasing buffer returns %08x\n", hr);
343 sum += frames;
344 }
345
346 hr = IAudioClient_Stop(ac);
347 ok(hr == S_OK, "Stop on a started stream returns %08x\n", hr);
348
349 hr = IAudioClient_Start(ac);
350 ok(hr == S_OK, "Start on a stopped stream returns %08x\n", hr);
351
352 hr = IAudioCaptureClient_GetBuffer(acc, &data, &frames, &flags, &pos, &qpc);
353 ok(hr == S_OK, "Valid IAudioCaptureClient_GetBuffer returns %08x\n", hr);
354
355 hr = IAudioClient_GetCurrentPadding(ac, &pad);
356 ok(hr == S_OK, "GetCurrentPadding call returns %08x\n", hr);
357
358 trace("Restart position %d pad %u flags %x, amount of frames locked: %u\n",
359 hr==S_OK ? (UINT)pos : -1, pad, flags, frames);
360 ok(pad > sum, "restarted GCP %u\n", pad); /* GCP is still near buffer size */
361
362 if(frames){
363 ok(pos == sum, "Position %u expected %u\n", (UINT)pos, sum);
364 ok(!flags, "flags %u\n", flags);
365
366 hr = IAudioCaptureClient_ReleaseBuffer(acc, frames);
367 ok(hr == S_OK, "Releasing buffer returns %08x\n", hr);
368 sum += frames;
369 }
370
371 hr = IAudioClient_Stop(ac);
372 ok(hr == S_OK, "Stop on a started stream returns %08x\n", hr);
373
374 hr = IAudioClient_Reset(ac);
375 ok(hr == S_OK, "Reset on a stopped stream returns %08x\n", hr);
376 sum += pad - frames;
377
378 hr = IAudioClient_Start(ac);
379 ok(hr == S_OK, "Start on a stopped stream returns %08x\n", hr);
380
381 hr = IAudioClient_GetCurrentPadding(ac, &pad);
382 ok(hr == S_OK, "GetCurrentPadding call returns %08x\n", hr);
383
384 flags = 0xabadcafe;
385 hr = IAudioCaptureClient_GetBuffer(acc, &data, &frames, &flags, &pos, &qpc);
386 ok(hr == AUDCLNT_S_BUFFER_EMPTY || /*PulseAudio*/hr == S_OK,
387 "Initial IAudioCaptureClient_GetBuffer returns %08x\n", hr);
388
389 trace("Reset position %d pad %u flags %x, amount of frames locked: %u\n",
390 hr==S_OK ? (UINT)pos : -1, pad, flags, frames);
391
392 if(hr == S_OK){
393 /* Only PulseAudio goes here; despite snd_pcm_drop it manages
394 * to fill GetBufferSize with a single snd_pcm_read */
395 trace("Test marked todo: only PulseAudio gets here\n");
396 todo_wine ok(flags & AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY, "expect DISCONTINUITY %x\n", flags);
397 /* Reset zeroes padding, not the position */
398 ok(pos >= sum, "Position %u last %u\n", (UINT)pos, sum);
399 /*sum = pos; check after next GetBuffer */
400
401 hr = IAudioCaptureClient_ReleaseBuffer(acc, frames);
402 ok(hr == S_OK, "Releasing buffer returns %08x\n", hr);
403 sum += frames;
404 }
405 else if(hr == AUDCLNT_S_BUFFER_EMPTY){
406 ok(!pad, "reset GCP %u\n", pad);
407 Sleep(180);
408 }
409
410 hr = IAudioClient_GetCurrentPadding(ac, &pad);
411 ok(hr == S_OK, "GetCurrentPadding call returns %08x\n", hr);
412
413 hr = IAudioCaptureClient_GetBuffer(acc, &data, &frames, &flags, &pos, &qpc);
414 ok(hr == S_OK, "Valid IAudioCaptureClient_GetBuffer returns %08x\n", hr);
415 trace("Running position %d pad %u flags %x, amount of frames locked: %u\n",
416 SUCCEEDED(hr) ? (UINT)pos : -1, pad, flags, frames);
417
418 if(SUCCEEDED(hr)){
419 /* Some w7 machines signal DATA_DISCONTINUITY here following the
420 * previous AUDCLNT_S_BUFFER_EMPTY, others not. What logic? */
421 ok(pos >= sum, "Position %u gap %d\n", (UINT)pos, (UINT)pos - sum);
422 IAudioCaptureClient_ReleaseBuffer(acc, frames);
423 }
424
425 IAudioCaptureClient_Release(acc);
426}
427
428static void test_audioclient(void)
429{
430 IAudioClient *ac;
431 IUnknown *unk;
432 HRESULT hr;
433 ULONG ref;
434 WAVEFORMATEX *pwfx, *pwfx2;
435 REFERENCE_TIME t1, t2;
437
438 hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
439 NULL, (void**)&ac);
440 ok(hr == S_OK, "Activation failed with %08x\n", hr);
441 if(hr != S_OK)
442 return;
443
445
446 hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, NULL);
447 ok(hr == E_POINTER, "QueryInterface(NULL) returned %08x\n", hr);
448
449 unk = (void*)(LONG_PTR)0x12345678;
450 hr = IAudioClient_QueryInterface(ac, &IID_NULL, (void**)&unk);
451 ok(hr == E_NOINTERFACE, "QueryInterface(IID_NULL) returned %08x\n", hr);
452 ok(!unk, "QueryInterface(IID_NULL) returned non-null pointer %p\n", unk);
453
454 hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, (void**)&unk);
455 ok(hr == S_OK, "QueryInterface(IID_IUnknown) returned %08x\n", hr);
456 if (unk)
457 {
458 ref = IUnknown_Release(unk);
459 ok(ref == 1, "Released count is %u\n", ref);
460 }
461
462 hr = IAudioClient_QueryInterface(ac, &IID_IAudioClient, (void**)&unk);
463 ok(hr == S_OK, "QueryInterface(IID_IAudioClient) returned %08x\n", hr);
464 if (unk)
465 {
466 ref = IUnknown_Release(unk);
467 ok(ref == 1, "Released count is %u\n", ref);
468 }
469
470 hr = IAudioClient_GetDevicePeriod(ac, NULL, NULL);
471 ok(hr == E_POINTER, "Invalid GetDevicePeriod call returns %08x\n", hr);
472
473 hr = IAudioClient_GetDevicePeriod(ac, &t1, NULL);
474 ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr);
475
476 hr = IAudioClient_GetDevicePeriod(ac, NULL, &t2);
477 ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr);
478
479 hr = IAudioClient_GetDevicePeriod(ac, &t1, &t2);
480 ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr);
481 trace("Returned periods: %u.%04u ms %u.%04u ms\n",
482 (UINT)(t1/10000), (UINT)(t1 % 10000),
483 (UINT)(t2/10000), (UINT)(t2 % 10000));
484
485 hr = IAudioClient_GetMixFormat(ac, NULL);
486 ok(hr == E_POINTER, "GetMixFormat returns %08x\n", hr);
487
488 hr = IAudioClient_GetMixFormat(ac, &pwfx);
489 ok(hr == S_OK, "Valid GetMixFormat returns %08x\n", hr);
490
491 if (hr == S_OK)
492 {
493 trace("pwfx: %p\n", pwfx);
494 trace("Tag: %04x\n", pwfx->wFormatTag);
495 trace("bits: %u\n", pwfx->wBitsPerSample);
496 trace("chan: %u\n", pwfx->nChannels);
497 trace("rate: %u\n", pwfx->nSamplesPerSec);
498 trace("align: %u\n", pwfx->nBlockAlign);
499 trace("extra: %u\n", pwfx->cbSize);
500 ok(pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE, "wFormatTag is %x\n", pwfx->wFormatTag);
502 {
503 WAVEFORMATEXTENSIBLE *pwfxe = (void*)pwfx;
504 trace("Res: %u\n", pwfxe->Samples.wReserved);
505 trace("Mask: %x\n", pwfxe->dwChannelMask);
506 trace("Alg: %s\n",
508 (IsEqualGUID(&pwfxe->SubFormat,
509 &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)?"FLOAT":"Other"));
510 }
511
512 hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
513 ok(hr == S_OK, "Valid IsFormatSupported(Shared) call returns %08x\n", hr);
514 ok(pwfx2 == NULL, "pwfx2 is non-null\n");
515 CoTaskMemFree(pwfx2);
516
517 hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, NULL, NULL);
518 ok(hr == E_POINTER, "IsFormatSupported(NULL) call returns %08x\n", hr);
519
520 hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, NULL);
521 ok(hr == E_POINTER, "IsFormatSupported(Shared,NULL) call returns %08x\n", hr);
522
523 hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
524 ok(hr == S_OK || hr == AUDCLNT_E_UNSUPPORTED_FORMAT, "IsFormatSupported(Exclusive) call returns %08x\n", hr);
525
526 hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, &pwfx2);
527 ok(hr == S_OK || hr == AUDCLNT_E_UNSUPPORTED_FORMAT, "IsFormatSupported(Exclusive) call returns %08x\n", hr);
528 ok(pwfx2 == NULL, "pwfx2 non-null on exclusive IsFormatSupported\n");
529
530 hr = IAudioClient_IsFormatSupported(ac, 0xffffffff, pwfx, NULL);
531 ok(hr == E_INVALIDARG/*w32*/ ||
532 broken(hr == AUDCLNT_E_UNSUPPORTED_FORMAT/*w64 response from exclusive mode driver */),
533 "IsFormatSupported(0xffffffff) call returns %08x\n", hr);
534 }
535
537
538 hr = IAudioClient_Initialize(ac, 3, 0, 5000000, 0, pwfx, NULL);
539 ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Initialize with invalid sharemode returns %08x\n", hr);
540
541 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0xffffffff, 5000000, 0, pwfx, NULL);
542 ok(hr == E_INVALIDARG || hr == AUDCLNT_E_INVALID_STREAM_FLAG, "Initialize with invalid flags returns %08x\n", hr);
543
544 /* A period != 0 is ignored and the call succeeds.
545 * Since we can only initialize successfully once, skip those tests.
546 */
547 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, NULL, NULL);
548 ok(hr == E_POINTER, "Initialize with null format returns %08x\n", hr);
549
550 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 4987654, 0, pwfx, NULL);
551 ok(hr == S_OK, "Valid Initialize returns %08x\n", hr);
552
553 if (hr != S_OK)
554 {
555 skip("Cannot initialize %08x, remainder of tests is useless\n", hr);
556 goto cleanup;
557 }
558
559 hr = IAudioClient_GetStreamLatency(ac, NULL);
560 ok(hr == E_POINTER, "GetStreamLatency(NULL) call returns %08x\n", hr);
561
562 hr = IAudioClient_GetStreamLatency(ac, &t1);
563 ok(hr == S_OK, "Valid GetStreamLatency call returns %08x\n", hr);
564 trace("Returned latency: %u.%04u ms\n",
565 (UINT)(t1/10000), (UINT)(t1 % 10000));
566
567 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL);
568 ok(hr == AUDCLNT_E_ALREADY_INITIALIZED, "Calling Initialize twice returns %08x\n", hr);
569
570 hr = IAudioClient_SetEventHandle(ac, NULL);
571 ok(hr == E_INVALIDARG, "SetEventHandle(NULL) returns %08x\n", hr);
572
573 hr = IAudioClient_Start(ac);
574 ok(hr == AUDCLNT_E_EVENTHANDLE_NOT_SET ||
575 hr == D3D11_ERROR_4E /* win10 */, "Start before SetEventHandle returns %08x\n", hr);
576
577 hr = IAudioClient_SetEventHandle(ac, handle);
578 ok(hr == S_OK, "SetEventHandle returns %08x\n", hr);
579
580 hr = IAudioClient_Reset(ac);
581 ok(hr == S_OK, "Reset on an already reset stream returns %08x\n", hr);
582
583 hr = IAudioClient_Stop(ac);
584 ok(hr == S_FALSE, "Stop on a stopped stream returns %08x\n", hr);
585
586 hr = IAudioClient_Start(ac);
587 ok(hr == S_OK, "Start on a stopped stream returns %08x\n", hr);
588
589 test_capture(ac, handle, pwfx);
590
591cleanup:
592 IAudioClient_Release(ac);
594 CoTaskMemFree(pwfx);
595}
596
597static void test_streamvolume(void)
598{
599 IAudioClient *ac;
602 UINT32 chans, i;
603 HRESULT hr;
604 float vol, *vols;
605
606 hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
607 NULL, (void**)&ac);
608 ok(hr == S_OK, "Activation failed with %08x\n", hr);
609 if(hr != S_OK)
610 return;
611
612 hr = IAudioClient_GetMixFormat(ac, &fmt);
613 ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
614
615 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
616 0, fmt, NULL);
617 ok(hr == S_OK, "Initialize failed: %08x\n", hr);
618 if(hr != S_OK)
619 return;
620
621 hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&asv);
622 ok(hr == S_OK, "GetService failed: %08x\n", hr);
623
624 hr = IAudioStreamVolume_GetChannelCount(asv, NULL);
625 ok(hr == E_POINTER, "GetChannelCount gave wrong error: %08x\n", hr);
626
627 hr = IAudioStreamVolume_GetChannelCount(asv, &chans);
628 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
629 ok(chans == fmt->nChannels, "GetChannelCount gave wrong number of channels: %d\n", chans);
630
631 hr = IAudioStreamVolume_GetChannelVolume(asv, fmt->nChannels, NULL);
632 ok(hr == E_POINTER, "GetChannelCount gave wrong error: %08x\n", hr);
633
634 hr = IAudioStreamVolume_GetChannelVolume(asv, fmt->nChannels, &vol);
635 ok(hr == E_INVALIDARG, "GetChannelCount gave wrong error: %08x\n", hr);
636
637 hr = IAudioStreamVolume_GetChannelVolume(asv, 0, NULL);
638 ok(hr == E_POINTER, "GetChannelCount gave wrong error: %08x\n", hr);
639
640 hr = IAudioStreamVolume_GetChannelVolume(asv, 0, &vol);
641 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
642 ok(vol == 1.f, "Channel volume was not 1: %f\n", vol);
643
644 hr = IAudioStreamVolume_SetChannelVolume(asv, fmt->nChannels, -1.f);
645 ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
646
647 hr = IAudioStreamVolume_SetChannelVolume(asv, 0, -1.f);
648 ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
649
650 hr = IAudioStreamVolume_SetChannelVolume(asv, 0, 2.f);
651 ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
652
653 hr = IAudioStreamVolume_SetChannelVolume(asv, 0, 0.2f);
654 ok(hr == S_OK, "SetChannelVolume failed: %08x\n", hr);
655
656 hr = IAudioStreamVolume_GetChannelVolume(asv, 0, &vol);
657 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
658 ok(fabsf(vol - 0.2f) < 0.05f, "Channel volume wasn't 0.2: %f\n", vol);
659
660 hr = IAudioStreamVolume_GetAllVolumes(asv, 0, NULL);
661 ok(hr == E_POINTER, "GetAllVolumes gave wrong error: %08x\n", hr);
662
663 hr = IAudioStreamVolume_GetAllVolumes(asv, fmt->nChannels, NULL);
664 ok(hr == E_POINTER, "GetAllVolumes gave wrong error: %08x\n", hr);
665
666 vols = HeapAlloc(GetProcessHeap(), 0, fmt->nChannels * sizeof(float));
667 ok(vols != NULL, "HeapAlloc failed\n");
668
669 hr = IAudioStreamVolume_GetAllVolumes(asv, fmt->nChannels - 1, vols);
670 ok(hr == E_INVALIDARG, "GetAllVolumes gave wrong error: %08x\n", hr);
671
672 hr = IAudioStreamVolume_GetAllVolumes(asv, fmt->nChannels, vols);
673 ok(hr == S_OK, "GetAllVolumes failed: %08x\n", hr);
674 ok(fabsf(vols[0] - 0.2f) < 0.05f, "Channel 0 volume wasn't 0.2: %f\n", vol);
675 for(i = 1; i < fmt->nChannels; ++i)
676 ok(vols[i] == 1.f, "Channel %d volume is not 1: %f\n", i, vols[i]);
677
678 hr = IAudioStreamVolume_SetAllVolumes(asv, 0, NULL);
679 ok(hr == E_POINTER, "SetAllVolumes gave wrong error: %08x\n", hr);
680
681 hr = IAudioStreamVolume_SetAllVolumes(asv, fmt->nChannels, NULL);
682 ok(hr == E_POINTER, "SetAllVolumes gave wrong error: %08x\n", hr);
683
684 hr = IAudioStreamVolume_SetAllVolumes(asv, fmt->nChannels - 1, vols);
685 ok(hr == E_INVALIDARG, "SetAllVolumes gave wrong error: %08x\n", hr);
686
687 hr = IAudioStreamVolume_SetAllVolumes(asv, fmt->nChannels, vols);
688 ok(hr == S_OK, "SetAllVolumes failed: %08x\n", hr);
689
690 HeapFree(GetProcessHeap(), 0, vols);
691 IAudioStreamVolume_Release(asv);
692 IAudioClient_Release(ac);
694}
695
696static void test_channelvolume(void)
697{
698 IAudioClient *ac;
701 UINT32 chans, i;
702 HRESULT hr;
703 float vol, *vols;
704
705 hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
706 NULL, (void**)&ac);
707 ok(hr == S_OK, "Activation failed with %08x\n", hr);
708 if(hr != S_OK)
709 return;
710
711 hr = IAudioClient_GetMixFormat(ac, &fmt);
712 ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
713
714 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
716 ok(hr == S_OK, "Initialize failed: %08x\n", hr);
717
718 hr = IAudioClient_GetService(ac, &IID_IChannelAudioVolume, (void**)&acv);
719 ok(hr == S_OK, "GetService failed: %08x\n", hr);
720 if(hr != S_OK)
721 return;
722
723 hr = IChannelAudioVolume_GetChannelCount(acv, NULL);
724 ok(hr == NULL_PTR_ERR, "GetChannelCount gave wrong error: %08x\n", hr);
725
726 hr = IChannelAudioVolume_GetChannelCount(acv, &chans);
727 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
728 ok(chans == fmt->nChannels, "GetChannelCount gave wrong number of channels: %d\n", chans);
729
730 hr = IChannelAudioVolume_GetChannelVolume(acv, fmt->nChannels, NULL);
731 ok(hr == NULL_PTR_ERR, "GetChannelCount gave wrong error: %08x\n", hr);
732
733 hr = IChannelAudioVolume_GetChannelVolume(acv, fmt->nChannels, &vol);
734 ok(hr == E_INVALIDARG, "GetChannelCount gave wrong error: %08x\n", hr);
735
736 hr = IChannelAudioVolume_GetChannelVolume(acv, 0, NULL);
737 ok(hr == NULL_PTR_ERR, "GetChannelCount gave wrong error: %08x\n", hr);
738
739 hr = IChannelAudioVolume_GetChannelVolume(acv, 0, &vol);
740 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
741 ok(vol == 1.f, "Channel volume was not 1: %f\n", vol);
742
743 hr = IChannelAudioVolume_SetChannelVolume(acv, fmt->nChannels, -1.f, NULL);
744 ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
745
746 hr = IChannelAudioVolume_SetChannelVolume(acv, 0, -1.f, NULL);
747 ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
748
749 hr = IChannelAudioVolume_SetChannelVolume(acv, 0, 2.f, NULL);
750 ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
751
752 hr = IChannelAudioVolume_SetChannelVolume(acv, 0, 0.2f, NULL);
753 ok(hr == S_OK, "SetChannelVolume failed: %08x\n", hr);
754
755 hr = IChannelAudioVolume_GetChannelVolume(acv, 0, &vol);
756 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
757 ok(fabsf(vol - 0.2f) < 0.05f, "Channel volume wasn't 0.2: %f\n", vol);
758
759 hr = IChannelAudioVolume_GetAllVolumes(acv, 0, NULL);
760 ok(hr == NULL_PTR_ERR, "GetAllVolumes gave wrong error: %08x\n", hr);
761
762 hr = IChannelAudioVolume_GetAllVolumes(acv, fmt->nChannels, NULL);
763 ok(hr == NULL_PTR_ERR, "GetAllVolumes gave wrong error: %08x\n", hr);
764
765 vols = HeapAlloc(GetProcessHeap(), 0, fmt->nChannels * sizeof(float));
766 ok(vols != NULL, "HeapAlloc failed\n");
767
768 hr = IChannelAudioVolume_GetAllVolumes(acv, fmt->nChannels - 1, vols);
769 ok(hr == E_INVALIDARG, "GetAllVolumes gave wrong error: %08x\n", hr);
770
771 hr = IChannelAudioVolume_GetAllVolumes(acv, fmt->nChannels, vols);
772 ok(hr == S_OK, "GetAllVolumes failed: %08x\n", hr);
773 ok(fabsf(vols[0] - 0.2f) < 0.05f, "Channel 0 volume wasn't 0.2: %f\n", vol);
774 for(i = 1; i < fmt->nChannels; ++i)
775 ok(vols[i] == 1.f, "Channel %d volume is not 1: %f\n", i, vols[i]);
776
777 hr = IChannelAudioVolume_SetAllVolumes(acv, 0, NULL, NULL);
778 ok(hr == NULL_PTR_ERR, "SetAllVolumes gave wrong error: %08x\n", hr);
779
780 hr = IChannelAudioVolume_SetAllVolumes(acv, fmt->nChannels, NULL, NULL);
781 ok(hr == NULL_PTR_ERR, "SetAllVolumes gave wrong error: %08x\n", hr);
782
783 hr = IChannelAudioVolume_SetAllVolumes(acv, fmt->nChannels - 1, vols, NULL);
784 ok(hr == E_INVALIDARG, "SetAllVolumes gave wrong error: %08x\n", hr);
785
786 hr = IChannelAudioVolume_SetAllVolumes(acv, fmt->nChannels, vols, NULL);
787 ok(hr == S_OK, "SetAllVolumes failed: %08x\n", hr);
788
789 hr = IChannelAudioVolume_SetChannelVolume(acv, 0, 1.0f, NULL);
790 ok(hr == S_OK, "SetChannelVolume failed: %08x\n", hr);
791
792 HeapFree(GetProcessHeap(), 0, vols);
793 IChannelAudioVolume_Release(acv);
794 IAudioClient_Release(ac);
796}
797
798static void test_simplevolume(void)
799{
800 IAudioClient *ac;
803 HRESULT hr;
804 float vol;
805 BOOL mute;
806
807 hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
808 NULL, (void**)&ac);
809 ok(hr == S_OK, "Activation failed with %08x\n", hr);
810 if(hr != S_OK)
811 return;
812
813 hr = IAudioClient_GetMixFormat(ac, &fmt);
814 ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
815
816 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
818 ok(hr == S_OK, "Initialize failed: %08x\n", hr);
819
820 hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
821 ok(hr == S_OK, "GetService failed: %08x\n", hr);
822 if(hr != S_OK)
823 return;
824
825 hr = ISimpleAudioVolume_GetMasterVolume(sav, NULL);
826 ok(hr == NULL_PTR_ERR, "GetMasterVolume gave wrong error: %08x\n", hr);
827
828 hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
829 ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
830
831 hr = ISimpleAudioVolume_SetMasterVolume(sav, -1.f, NULL);
832 ok(hr == E_INVALIDARG, "SetMasterVolume gave wrong error: %08x\n", hr);
833
834 hr = ISimpleAudioVolume_SetMasterVolume(sav, 2.f, NULL);
835 ok(hr == E_INVALIDARG, "SetMasterVolume gave wrong error: %08x\n", hr);
836
837 hr = ISimpleAudioVolume_SetMasterVolume(sav, 0.2f, NULL);
838 ok(hr == S_OK, "SetMasterVolume failed: %08x\n", hr);
839
840 hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
841 ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
842 ok(fabsf(vol - 0.2f) < 0.05f, "Master volume wasn't 0.2: %f\n", vol);
843
844 hr = ISimpleAudioVolume_GetMute(sav, NULL);
845 ok(hr == NULL_PTR_ERR, "GetMute gave wrong error: %08x\n", hr);
846
847 mute = TRUE;
848 hr = ISimpleAudioVolume_GetMute(sav, &mute);
849 ok(hr == S_OK, "GetMute failed: %08x\n", hr);
850 ok(mute == FALSE, "Session is already muted\n");
851
852 hr = ISimpleAudioVolume_SetMute(sav, TRUE, NULL);
853 ok(hr == S_OK, "SetMute failed: %08x\n", hr);
854
855 mute = FALSE;
856 hr = ISimpleAudioVolume_GetMute(sav, &mute);
857 ok(hr == S_OK, "GetMute failed: %08x\n", hr);
858 ok(mute == TRUE, "Session should have been muted\n");
859
860 hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
861 ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
862 ok(fabsf(vol - 0.2f) < 0.05f, "Master volume wasn't 0.2: %f\n", vol);
863
864 hr = ISimpleAudioVolume_SetMasterVolume(sav, 1.f, NULL);
865 ok(hr == S_OK, "SetMasterVolume failed: %08x\n", hr);
866
867 mute = FALSE;
868 hr = ISimpleAudioVolume_GetMute(sav, &mute);
869 ok(hr == S_OK, "GetMute failed: %08x\n", hr);
870 ok(mute == TRUE, "Session should have been muted\n");
871
872 hr = ISimpleAudioVolume_SetMute(sav, FALSE, NULL);
873 ok(hr == S_OK, "SetMute failed: %08x\n", hr);
874
875 ISimpleAudioVolume_Release(sav);
876 IAudioClient_Release(ac);
878}
879
880static void test_volume_dependence(void)
881{
882 IAudioClient *ac, *ac2;
887 HRESULT hr;
888 float vol;
890 UINT32 nch;
891
893 ok(hr == S_OK, "CoCreateGuid failed: %08x\n", hr);
894
895 hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
896 NULL, (void**)&ac);
897 ok(hr == S_OK, "Activation failed with %08x\n", hr);
898 if(hr != S_OK)
899 return;
900
901 hr = IAudioClient_GetMixFormat(ac, &fmt);
902 ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
903
904 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
906 ok(hr == S_OK, "Initialize failed: %08x\n", hr);
907
908 hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
909 ok(hr == S_OK, "GetService (SimpleAudioVolume) failed: %08x\n", hr);
910
911 hr = IAudioClient_GetService(ac, &IID_IChannelAudioVolume, (void**)&cav);
912 ok(hr == S_OK, "GetService (ChannelAudioVolume) failed: %08x\n", hr);
913
914 hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&asv);
915 ok(hr == S_OK, "GetService (AudioStreamVolume) failed: %08x\n", hr);
916 if(hr != S_OK)
917 return;
918
919 hr = IAudioStreamVolume_SetChannelVolume(asv, 0, 0.2f);
920 ok(hr == S_OK, "ASV_SetChannelVolume failed: %08x\n", hr);
921
922 hr = IChannelAudioVolume_SetChannelVolume(cav, 0, 0.4f, NULL);
923 ok(hr == S_OK, "CAV_SetChannelVolume failed: %08x\n", hr);
924
925 hr = ISimpleAudioVolume_SetMasterVolume(sav, 0.6f, NULL);
926 ok(hr == S_OK, "SAV_SetMasterVolume failed: %08x\n", hr);
927
928 hr = IAudioStreamVolume_GetChannelVolume(asv, 0, &vol);
929 ok(hr == S_OK, "ASV_GetChannelVolume failed: %08x\n", hr);
930 ok(fabsf(vol - 0.2f) < 0.05f, "ASV_GetChannelVolume gave wrong volume: %f\n", vol);
931
932 hr = IChannelAudioVolume_GetChannelVolume(cav, 0, &vol);
933 ok(hr == S_OK, "CAV_GetChannelVolume failed: %08x\n", hr);
934 ok(fabsf(vol - 0.4f) < 0.05f, "CAV_GetChannelVolume gave wrong volume: %f\n", vol);
935
936 hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
937 ok(hr == S_OK, "SAV_GetMasterVolume failed: %08x\n", hr);
938 ok(fabsf(vol - 0.6f) < 0.05f, "SAV_GetMasterVolume gave wrong volume: %f\n", vol);
939
940 hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
941 NULL, (void**)&ac2);
942 if(SUCCEEDED(hr)){
944 IAudioStreamVolume *asv2;
945
946 hr = IAudioClient_Initialize(ac2, AUDCLNT_SHAREMODE_SHARED,
948 ok(hr == S_OK, "Initialize failed: %08x\n", hr);
949
950 hr = IAudioClient_GetService(ac2, &IID_IChannelAudioVolume, (void**)&cav2);
951 ok(hr == S_OK, "GetService failed: %08x\n", hr);
952
953 hr = IAudioClient_GetService(ac2, &IID_IAudioStreamVolume, (void**)&asv2);
954 ok(hr == S_OK, "GetService failed: %08x\n", hr);
955
956 hr = IChannelAudioVolume_GetChannelVolume(cav2, 0, &vol);
957 ok(hr == S_OK, "CAV_GetChannelVolume failed: %08x\n", hr);
958 ok(fabsf(vol - 0.4f) < 0.05f, "CAV_GetChannelVolume gave wrong volume: %f\n", vol);
959
960 hr = IAudioStreamVolume_GetChannelVolume(asv2, 0, &vol);
961 ok(hr == S_OK, "ASV_GetChannelVolume failed: %08x\n", hr);
962 ok(vol == 1.f, "ASV_GetChannelVolume gave wrong volume: %f\n", vol);
963
964 hr = IChannelAudioVolume_GetChannelCount(cav2, &nch);
965 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
966 ok(nch == fmt->nChannels, "Got wrong channel count, expected %u: %u\n", fmt->nChannels, nch);
967
968 hr = IAudioStreamVolume_GetChannelCount(asv2, &nch);
969 ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
970 ok(nch == fmt->nChannels, "Got wrong channel count, expected %u: %u\n", fmt->nChannels, nch);
971
972 IAudioStreamVolume_Release(asv2);
973 IChannelAudioVolume_Release(cav2);
974 IAudioClient_Release(ac2);
975 }else
976 skip("Unable to open the same device twice. Skipping session volume control tests\n");
977
978 hr = IChannelAudioVolume_SetChannelVolume(cav, 0, 1.f, NULL);
979 ok(hr == S_OK, "CAV_SetChannelVolume failed: %08x\n", hr);
980
981 hr = ISimpleAudioVolume_SetMasterVolume(sav, 1.f, NULL);
982 ok(hr == S_OK, "SAV_SetMasterVolume failed: %08x\n", hr);
983
985 ISimpleAudioVolume_Release(sav);
986 IChannelAudioVolume_Release(cav);
987 IAudioStreamVolume_Release(asv);
988 IAudioClient_Release(ac);
989}
990
991static void test_marshal(void)
992{
993 IStream *pStream;
994 IAudioClient *ac, *acDest;
995 IAudioCaptureClient *cc, *ccDest;
996 WAVEFORMATEX *pwfx;
997 HRESULT hr;
998
999 hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1000 NULL, (void**)&ac);
1001 ok(hr == S_OK, "Activation failed with %08x\n", hr);
1002 if(hr != S_OK)
1003 return;
1004
1005 hr = IAudioClient_GetMixFormat(ac, &pwfx);
1006 ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1007
1008 hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
1009 0, pwfx, NULL);
1010 ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1011
1012 CoTaskMemFree(pwfx);
1013
1014 hr = IAudioClient_GetService(ac, &IID_IAudioCaptureClient, (void**)&cc);
1015 ok(hr == S_OK, "GetService failed: %08x\n", hr);
1016 if(hr != S_OK) {
1017 IAudioClient_Release(ac);
1018 return;
1019 }
1020
1021 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1022 ok(hr == S_OK, "CreateStreamOnHGlobal failed 0x%08x\n", hr);
1023
1024 /* marshal IAudioClient */
1025
1026 hr = CoMarshalInterface(pStream, &IID_IAudioClient, (IUnknown*)ac, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1027 ok(hr == S_OK, "CoMarshalInterface IAudioClient failed 0x%08x\n", hr);
1028
1029 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1030 hr = CoUnmarshalInterface(pStream, &IID_IAudioClient, (void **)&acDest);
1031 ok(hr == S_OK, "CoUnmarshalInterface IAudioClient failed 0x%08x\n", hr);
1032 if (hr == S_OK)
1033 IAudioClient_Release(acDest);
1034
1035 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1036 /* marshal IAudioCaptureClient */
1037
1038 hr = CoMarshalInterface(pStream, &IID_IAudioCaptureClient, (IUnknown*)cc, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1039 ok(hr == S_OK, "CoMarshalInterface IAudioCaptureClient failed 0x%08x\n", hr);
1040
1041 IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
1042 hr = CoUnmarshalInterface(pStream, &IID_IAudioCaptureClient, (void **)&ccDest);
1043 ok(hr == S_OK, "CoUnmarshalInterface IAudioCaptureClient failed 0x%08x\n", hr);
1044 if (hr == S_OK)
1045 IAudioCaptureClient_Release(ccDest);
1046
1047 IStream_Release(pStream);
1048
1049 IAudioClient_Release(ac);
1050 IAudioCaptureClient_Release(cc);
1051
1052}
1053
1055{
1056 HRESULT hr;
1058
1060 hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme);
1061 if (FAILED(hr))
1062 {
1063 skip("mmdevapi not available: 0x%08x\n", hr);
1064 goto cleanup;
1065 }
1066
1067 hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme, eCapture, eMultimedia, &dev);
1068 ok(hr == S_OK || hr == E_NOTFOUND, "GetDefaultAudioEndpoint failed: 0x%08x\n", hr);
1069 if (hr != S_OK || !dev)
1070 {
1071 if (hr == E_NOTFOUND)
1072 skip("No sound card available\n");
1073 else
1074 skip("GetDefaultAudioEndpoint returns 0x%08x\n", hr);
1075 goto cleanup;
1076 }
1077
1083 test_marshal();
1084
1085 IMMDevice_Release(dev);
1086
1087cleanup:
1088 if (mme)
1089 IMMDeviceEnumerator_Release(mme);
1091}
unsigned long long UINT64
unsigned int UINT32
#define broken(x)
Definition: _sntprintf.h:21
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
@ AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY
Definition: audioclient.idl:62
#define AUDCLNT_STREAMFLAGS_EVENTCALLBACK
@ AUDCLNT_SHAREMODE_SHARED
@ AUDCLNT_SHAREMODE_EXCLUSIVE
#define AUDCLNT_STREAMFLAGS_NOPERSIST
const GUID IID_IUnknown
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
static void cleanup(void)
Definition: main.c:1335
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
HRESULT WINAPI CoCreateGuid(GUID *pguid)
Definition: compobj.c:2206
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
Definition: marshal.c:1981
HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, DWORD dwDestContext, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:1876
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
GLuint GLuint num
Definition: glext.h:9618
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
_Check_return_ __CRT_INLINE float __CRTDECL fabsf(_In_ float x)
Definition: math.h:179
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t cc
Definition: isohybrid.c:75
#define KSDATAFORMAT_SUBTYPE_PCM
Definition: ksmedia.h:1021
#define WAVE_FORMAT_EXTENSIBLE
Definition: ksmedia.h:651
#define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
Definition: ksmedia.h:1026
@ eCapture
Definition: mmdeviceapi.idl:64
@ eMultimedia
Definition: mmdeviceapi.idl:72
static void test_capture(void)
Definition: capture.c:174
static void test_simplevolume(void)
Definition: capture.c:798
static void test_audioclient(void)
Definition: capture.c:428
static const LARGE_INTEGER ullZero
Definition: capture.c:45
static void test_marshal(void)
Definition: capture.c:991
static void test_uninitialized(IAudioClient *ac)
Definition: capture.c:47
static void test_channelvolume(void)
Definition: capture.c:696
static void test_streamvolume(void)
Definition: capture.c:597
#define NULL_PTR_ERR
Definition: capture.c:39
#define D3D11_ERROR_4E
Definition: capture.c:42
static void test_volume_dependence(void)
Definition: capture.c:880
static IMMDeviceEnumerator * mme
Definition: render.c:63
#define todo_wine_if(is_todo)
Definition: custom.c:76
#define todo_wine
Definition: custom.c:79
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
unsigned int UINT
Definition: ndis.h:50
@ COINIT_MULTITHREADED
Definition: objbase.h:279
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IID_NULL
Definition: guiddef.h:98
static int sum(int x_, int y_)
Definition: ptr2_test.cpp:35
static unsigned __int64 next
Definition: rand_nt.c:6
int nch
Definition: scanf.h:135
HRESULT hr
Definition: shlfolder.c:183
union WAVEFORMATEXTENSIBLE::@3024 Samples
WORD wBitsPerSample
Definition: audioclient.idl:45
DWORD nSamplesPerSec
Definition: audioclient.idl:42
Definition: tftpd.h:138
Definition: dsound.c:943
Definition: send.c:48
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define WAIT_OBJECT_0
Definition: winbase.h:406
#define S_FALSE
Definition: winerror.h:2357
#define E_NOINTERFACE
Definition: winerror.h:2364
#define E_POINTER
Definition: winerror.h:2365
unsigned char BYTE
Definition: xxhash.c:193