mshtml: Wine Gecko 1.4 release.
[wine] / dlls / mmdevapi / tests / render.c
1 /*
2  * Copyright 2010 Maarten Lankhorst for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 /* This test is for audio playback specific mechanisms
20  * Tests:
21  * - IAudioClient with eRender and IAudioRenderClient
22  */
23
24 #include <math.h>
25 #include <stdio.h>
26
27 #include "wine/test.h"
28
29 #define COBJMACROS
30
31 #ifdef STANDALONE
32 #include "initguid.h"
33 #endif
34
35 #include "unknwn.h"
36 #include "uuids.h"
37 #include "mmdeviceapi.h"
38 #include "audioclient.h"
39 #include "audiopolicy.h"
40
41 #define NULL_PTR_ERR MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, RPC_X_NULL_REF_POINTER)
42
43 static IMMDeviceEnumerator *mme = NULL;
44 static IMMDevice *dev = NULL;
45 static HRESULT hexcl = S_OK; /* or AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED */
46
47 static inline const char *dbgstr_guid( const GUID *id )
48 {
49     static char ret[256];
50     sprintf(ret, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
51                              id->Data1, id->Data2, id->Data3,
52                              id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
53                              id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
54     return ret;
55 }
56
57 static void test_uninitialized(IAudioClient *ac)
58 {
59     HRESULT hr;
60     UINT32 num;
61     REFERENCE_TIME t1;
62
63     HANDLE handle = CreateEventW(NULL, FALSE, FALSE, NULL);
64     IUnknown *unk;
65
66     hr = IAudioClient_GetBufferSize(ac, &num);
67     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetBufferSize call returns %08x\n", hr);
68
69     hr = IAudioClient_GetStreamLatency(ac, &t1);
70     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetStreamLatency call returns %08x\n", hr);
71
72     hr = IAudioClient_GetCurrentPadding(ac, &num);
73     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetCurrentPadding call returns %08x\n", hr);
74
75     hr = IAudioClient_Start(ac);
76     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized Start call returns %08x\n", hr);
77
78     hr = IAudioClient_Stop(ac);
79     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized Stop call returns %08x\n", hr);
80
81     hr = IAudioClient_Reset(ac);
82     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized Reset call returns %08x\n", hr);
83
84     hr = IAudioClient_SetEventHandle(ac, handle);
85     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized SetEventHandle call returns %08x\n", hr);
86
87     hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&unk);
88     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetService call returns %08x\n", hr);
89
90     CloseHandle(handle);
91 }
92
93 static void test_audioclient(void)
94 {
95     IAudioClient *ac;
96     IUnknown *unk;
97     HRESULT hr;
98     ULONG ref;
99     WAVEFORMATEX *pwfx, *pwfx2;
100     REFERENCE_TIME t1, t2;
101     HANDLE handle;
102
103     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
104             NULL, (void**)&ac);
105     ok(hr == S_OK, "Activation failed with %08x\n", hr);
106     if(hr != S_OK)
107         return;
108
109     handle = CreateEventW(NULL, FALSE, FALSE, NULL);
110
111     hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, NULL);
112     ok(hr == E_POINTER, "QueryInterface(NULL) returned %08x\n", hr);
113
114     unk = (void*)(LONG_PTR)0x12345678;
115     hr = IAudioClient_QueryInterface(ac, &IID_NULL, (void**)&unk);
116     ok(hr == E_NOINTERFACE, "QueryInterface(IID_NULL) returned %08x\n", hr);
117     ok(!unk, "QueryInterface(IID_NULL) returned non-null pointer %p\n", unk);
118
119     hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, (void**)&unk);
120     ok(hr == S_OK, "QueryInterface(IID_IUnknown) returned %08x\n", hr);
121     if (unk)
122     {
123         ref = IUnknown_Release(unk);
124         ok(ref == 1, "Released count is %u\n", ref);
125     }
126
127     hr = IAudioClient_QueryInterface(ac, &IID_IAudioClient, (void**)&unk);
128     ok(hr == S_OK, "QueryInterface(IID_IAudioClient) returned %08x\n", hr);
129     if (unk)
130     {
131         ref = IUnknown_Release(unk);
132         ok(ref == 1, "Released count is %u\n", ref);
133     }
134
135     hr = IAudioClient_GetDevicePeriod(ac, NULL, NULL);
136     ok(hr == E_POINTER, "Invalid GetDevicePeriod call returns %08x\n", hr);
137
138     hr = IAudioClient_GetDevicePeriod(ac, &t1, NULL);
139     ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr);
140
141     hr = IAudioClient_GetDevicePeriod(ac, NULL, &t2);
142     ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr);
143
144     hr = IAudioClient_GetDevicePeriod(ac, &t1, &t2);
145     ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr);
146     trace("Returned periods: %u.%04u ms %u.%04u ms\n",
147           (UINT)(t1/10000), (UINT)(t1 % 10000),
148           (UINT)(t2/10000), (UINT)(t2 % 10000));
149
150     hr = IAudioClient_GetMixFormat(ac, NULL);
151     ok(hr == E_POINTER, "GetMixFormat returns %08x\n", hr);
152
153     hr = IAudioClient_GetMixFormat(ac, &pwfx);
154     ok(hr == S_OK, "Valid GetMixFormat returns %08x\n", hr);
155
156     if (hr == S_OK)
157     {
158         trace("pwfx: %p\n", pwfx);
159         trace("Tag: %04x\n", pwfx->wFormatTag);
160         trace("bits: %u\n", pwfx->wBitsPerSample);
161         trace("chan: %u\n", pwfx->nChannels);
162         trace("rate: %u\n", pwfx->nSamplesPerSec);
163         trace("align: %u\n", pwfx->nBlockAlign);
164         trace("extra: %u\n", pwfx->cbSize);
165         ok(pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE, "wFormatTag is %x\n", pwfx->wFormatTag);
166         if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
167         {
168             WAVEFORMATEXTENSIBLE *pwfxe = (void*)pwfx;
169             trace("Res: %u\n", pwfxe->Samples.wReserved);
170             trace("Mask: %x\n", pwfxe->dwChannelMask);
171             trace("Alg: %s\n",
172                   IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)?"PCM":
173                   (IsEqualGUID(&pwfxe->SubFormat,
174                                &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)?"FLOAT":"Other"));
175         }
176
177         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
178         ok(hr == S_OK, "Valid IsFormatSupported(Shared) call returns %08x\n", hr);
179         ok(pwfx2 == NULL, "pwfx2 is non-null\n");
180         CoTaskMemFree(pwfx2);
181
182         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, NULL, NULL);
183         ok(hr == E_POINTER, "IsFormatSupported(NULL) call returns %08x\n", hr);
184
185         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, NULL);
186         ok(hr == E_POINTER, "IsFormatSupported(Shared,NULL) call returns %08x\n", hr);
187
188         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
189         ok(hr == S_OK || hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED,
190            "IsFormatSupported(Exclusive) call returns %08x\n", hr);
191         hexcl = hr;
192
193         pwfx2 = (WAVEFORMATEX*)0xDEADF00D;
194         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, &pwfx2);
195         ok(hr == hexcl, "IsFormatSupported(Exclusive) call returns %08x\n", hr);
196         ok(pwfx2 == NULL, "pwfx2 non-null on exclusive IsFormatSupported\n");
197
198         if (hexcl != AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED)
199             hexcl = S_OK;
200
201         hr = IAudioClient_IsFormatSupported(ac, 0xffffffff, pwfx, NULL);
202         ok(hr == E_INVALIDARG ||
203            hr == AUDCLNT_E_UNSUPPORTED_FORMAT,
204            "IsFormatSupported(0xffffffff) call returns %08x\n", hr);
205     }
206
207     test_uninitialized(ac);
208
209     hr = IAudioClient_Initialize(ac, 3, 0, 5000000, 0, pwfx, NULL);
210     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Initialize with invalid sharemode returns %08x\n", hr);
211
212     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0xffffffff, 5000000, 0, pwfx, NULL);
213     ok(hr == E_INVALIDARG, "Initialize with invalid flags returns %08x\n", hr);
214
215     /* It seems that if length > 2s or periodicity != 0 the length is ignored and call succeeds
216      * Since we can only initialize successfully once, skip those tests.
217      */
218     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, NULL, NULL);
219     ok(hr == E_POINTER, "Initialize with null format returns %08x\n", hr);
220
221     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 0, 0, pwfx, NULL);
222     ok(hr == S_OK, "Initialize with 0 buffer size returns %08x\n", hr);
223     if(hr == S_OK){
224         UINT32 num;
225
226         hr = IAudioClient_GetBufferSize(ac, &num);
227         ok(hr == S_OK, "GetBufferSize from duration 0 returns %08x\n", hr);
228         if(hr == S_OK)
229             trace("Initialize(duration=0) GetBufferSize is %u\n", num);
230     }
231
232     IAudioClient_Release(ac);
233
234     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
235             NULL, (void**)&ac);
236     ok(hr == S_OK, "Activation failed with %08x\n", hr);
237
238     if(pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE){
239         WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE*)pwfx;
240         WAVEFORMATEX *fmt2 = NULL;
241
242         ok(fmtex->dwChannelMask != 0, "Got empty dwChannelMask\n");
243
244         fmtex->dwChannelMask = 0xffff;
245
246         hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL);
247         ok(hr == S_OK, "Initialize(dwChannelMask = 0xffff) returns %08x\n", hr);
248
249         IAudioClient_Release(ac);
250
251         hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
252                 NULL, (void**)&ac);
253         ok(hr == S_OK, "Activation failed with %08x\n", hr);
254
255         fmtex->dwChannelMask = 0;
256
257         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &fmt2);
258         ok(hr == S_OK, "IsFormatSupported(dwChannelMask = 0) call returns %08x\n", hr);
259         ok(fmtex->dwChannelMask == 0, "Passed format was modified\n");
260
261         CoTaskMemFree(fmt2);
262
263         hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL);
264         ok(hr == S_OK, "Initialize(dwChannelMask = 0) returns %08x\n", hr);
265
266         IAudioClient_Release(ac);
267
268         hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
269                 NULL, (void**)&ac);
270         ok(hr == S_OK, "Activation failed with %08x\n", hr);
271
272         CoTaskMemFree(pwfx);
273
274         hr = IAudioClient_GetMixFormat(ac, &pwfx);
275         ok(hr == S_OK, "Valid GetMixFormat returns %08x\n", hr);
276     }else
277         skip("Skipping dwChannelMask tests\n");
278
279     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL);
280     ok(hr == S_OK, "Valid Initialize returns %08x\n", hr);
281     if (hr != S_OK)
282     {
283         IAudioClient_Release(ac);
284         CoTaskMemFree(pwfx);
285         return;
286     }
287
288     hr = IAudioClient_GetStreamLatency(ac, NULL);
289     ok(hr == E_POINTER, "GetStreamLatency(NULL) call returns %08x\n", hr);
290
291     hr = IAudioClient_GetStreamLatency(ac, &t2);
292     ok(hr == S_OK, "Valid GetStreamLatency call returns %08x\n", hr);
293     trace("Returned latency: %u.%04u ms\n",
294           (UINT)(t2/10000), (UINT)(t2 % 10000));
295     ok(t2 >= t1, "Latency < default period, delta %ldus\n", (long)((t2-t1)/10));
296
297     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL);
298     ok(hr == AUDCLNT_E_ALREADY_INITIALIZED, "Calling Initialize twice returns %08x\n", hr);
299
300     hr = IAudioClient_SetEventHandle(ac, NULL);
301     ok(hr == E_INVALIDARG, "SetEventHandle(NULL) returns %08x\n", hr);
302
303     hr = IAudioClient_SetEventHandle(ac, handle);
304     ok(hr == AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED ||
305        broken(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME)) ||
306        broken(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) /* Some 2k8 */ ||
307        broken(hr == HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME)) /* Some Vista */
308        , "SetEventHandle returns %08x\n", hr);
309
310     hr = IAudioClient_Reset(ac);
311     ok(hr == S_OK, "Reset on an initialized stream returns %08x\n", hr);
312
313     hr = IAudioClient_Reset(ac);
314     ok(hr == S_OK, "Reset on a resetted stream returns %08x\n", hr);
315
316     hr = IAudioClient_Stop(ac);
317     ok(hr == S_FALSE, "Stop on a stopped stream returns %08x\n", hr);
318
319     hr = IAudioClient_Start(ac);
320     ok(hr == S_OK, "Start on a stopped stream returns %08x\n", hr);
321
322     hr = IAudioClient_Start(ac);
323     ok(hr == AUDCLNT_E_NOT_STOPPED, "Start twice returns %08x\n", hr);
324
325     IAudioClient_Release(ac);
326
327     CloseHandle(handle);
328     CoTaskMemFree(pwfx);
329 }
330
331 static void test_references(void)
332 {
333     IAudioClient *ac;
334     IAudioRenderClient *rc;
335     ISimpleAudioVolume *sav;
336     IAudioStreamVolume *asv;
337     IAudioClock *acl;
338     WAVEFORMATEX *pwfx;
339     HRESULT hr;
340     ULONG ref;
341
342     /* IAudioRenderClient */
343     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
344             NULL, (void**)&ac);
345     ok(hr == S_OK, "Activation failed with %08x\n", hr);
346     if(hr != S_OK)
347         return;
348
349     hr = IAudioClient_GetMixFormat(ac, &pwfx);
350     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
351
352     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
353             0, pwfx, NULL);
354     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
355
356     CoTaskMemFree(pwfx);
357
358     hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&rc);
359     ok(hr == S_OK, "GetService failed: %08x\n", hr);
360     if(hr != S_OK) {
361         IAudioClient_Release(ac);
362         return;
363     }
364
365     IAudioRenderClient_AddRef(rc);
366     ref = IAudioRenderClient_Release(rc);
367     ok(ref != 0, "RenderClient_Release gave wrong refcount: %u\n", ref);
368
369     ref = IAudioClient_Release(ac);
370     ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
371
372     ref = IAudioRenderClient_Release(rc);
373     ok(ref == 0, "RenderClient_Release gave wrong refcount: %u\n", ref);
374
375     /* ISimpleAudioVolume */
376     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
377             NULL, (void**)&ac);
378     ok(hr == S_OK, "Activation failed with %08x\n", hr);
379     if(hr != S_OK)
380         return;
381
382     hr = IAudioClient_GetMixFormat(ac, &pwfx);
383     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
384
385     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
386             0, pwfx, NULL);
387     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
388
389     CoTaskMemFree(pwfx);
390
391     hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
392     ok(hr == S_OK, "GetService failed: %08x\n", hr);
393
394     ISimpleAudioVolume_AddRef(sav);
395     ref = ISimpleAudioVolume_Release(sav);
396     ok(ref != 0, "SimpleAudioVolume_Release gave wrong refcount: %u\n", ref);
397
398     ref = IAudioClient_Release(ac);
399     ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
400
401     ref = ISimpleAudioVolume_Release(sav);
402     ok(ref == 0, "SimpleAudioVolume_Release gave wrong refcount: %u\n", ref);
403
404     /* IAudioClock */
405     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
406             NULL, (void**)&ac);
407     ok(hr == S_OK, "Activation failed with %08x\n", hr);
408     if(hr != S_OK)
409         return;
410
411     hr = IAudioClient_GetMixFormat(ac, &pwfx);
412     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
413
414     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
415             0, pwfx, NULL);
416     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
417
418     CoTaskMemFree(pwfx);
419
420     hr = IAudioClient_GetService(ac, &IID_IAudioClock, (void**)&acl);
421     ok(hr == S_OK, "GetService failed: %08x\n", hr);
422
423     IAudioClock_AddRef(acl);
424     ref = IAudioClock_Release(acl);
425     ok(ref != 0, "AudioClock_Release gave wrong refcount: %u\n", ref);
426
427     ref = IAudioClient_Release(ac);
428     ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
429
430     ref = IAudioClock_Release(acl);
431     ok(ref == 0, "AudioClock_Release gave wrong refcount: %u\n", ref);
432
433     /* IAudioStreamVolume */
434     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
435             NULL, (void**)&ac);
436     ok(hr == S_OK, "Activation failed with %08x\n", hr);
437     if(hr != S_OK)
438         return;
439
440     hr = IAudioClient_GetMixFormat(ac, &pwfx);
441     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
442
443     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
444             0, pwfx, NULL);
445     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
446
447     CoTaskMemFree(pwfx);
448
449     hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&asv);
450     ok(hr == S_OK, "GetService failed: %08x\n", hr);
451
452     IAudioStreamVolume_AddRef(asv);
453     ref = IAudioStreamVolume_Release(asv);
454     ok(ref != 0, "AudioStreamVolume_Release gave wrong refcount: %u\n", ref);
455
456     ref = IAudioClient_Release(ac);
457     ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
458
459     ref = IAudioStreamVolume_Release(asv);
460     ok(ref == 0, "AudioStreamVolume_Release gave wrong refcount: %u\n", ref);
461 }
462
463 static void test_event(void)
464 {
465     HANDLE event;
466     HRESULT hr;
467     IAudioClient *ac;
468     WAVEFORMATEX *pwfx;
469
470     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
471             NULL, (void**)&ac);
472     ok(hr == S_OK, "Activation failed with %08x\n", hr);
473     if(hr != S_OK)
474         return;
475
476     hr = IAudioClient_GetMixFormat(ac, &pwfx);
477     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
478
479     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
480             AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 5000000,
481             0, pwfx, NULL);
482     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
483
484     CoTaskMemFree(pwfx);
485
486     event = CreateEventW(NULL, FALSE, FALSE, NULL);
487     ok(event != NULL, "CreateEvent failed\n");
488
489     hr = IAudioClient_Start(ac);
490     ok(hr == AUDCLNT_E_EVENTHANDLE_NOT_SET, "Start failed: %08x\n", hr);
491
492     hr = IAudioClient_SetEventHandle(ac, event);
493     ok(hr == S_OK, "SetEventHandle failed: %08x\n", hr);
494
495     hr = IAudioClient_Start(ac);
496     ok(hr == S_OK, "Start failed: %08x\n", hr);
497
498     hr = IAudioClient_Stop(ac);
499     ok(hr == S_OK, "Stop failed: %08x\n", hr);
500
501     /* test releasing a playing stream */
502     hr = IAudioClient_Start(ac);
503     ok(hr == S_OK, "Start failed: %08x\n", hr);
504     IAudioClient_Release(ac);
505
506     CloseHandle(event);
507 }
508
509 static void test_padding(void)
510 {
511     HRESULT hr;
512     IAudioClient *ac;
513     IAudioRenderClient *arc;
514     WAVEFORMATEX *pwfx;
515     REFERENCE_TIME minp, defp;
516     BYTE *buf;
517     UINT32 psize, pad, written;
518
519     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
520             NULL, (void**)&ac);
521     ok(hr == S_OK, "Activation failed with %08x\n", hr);
522     if(hr != S_OK)
523         return;
524
525     hr = IAudioClient_GetMixFormat(ac, &pwfx);
526     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
527     if(hr != S_OK)
528         return;
529
530     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
531             0, 5000000, 0, pwfx, NULL);
532     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
533
534     hr = IAudioClient_GetDevicePeriod(ac, &defp, &minp);
535     ok(hr == S_OK, "GetDevicePeriod failed: %08x\n", hr);
536     ok(defp != 0, "Default period is 0\n");
537     ok(minp != 0, "Minimum period is 0\n");
538     ok(minp <= defp, "Mininum period is greater than default period\n");
539
540     hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&arc);
541     ok(hr == S_OK, "GetService failed: %08x\n", hr);
542
543     psize = (defp / 10000000.) * pwfx->nSamplesPerSec * 10;
544
545     written = 0;
546     hr = IAudioClient_GetCurrentPadding(ac, &pad);
547     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
548     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
549
550     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
551     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
552     ok(buf != NULL, "NULL buffer returned\n");
553
554     hr = IAudioClient_Reset(ac);
555     ok(hr == AUDCLNT_E_BUFFER_OPERATION_PENDING, "Reset failed: %08x\n", hr);
556
557     hr = IAudioRenderClient_ReleaseBuffer(arc, psize,
558             AUDCLNT_BUFFERFLAGS_SILENT);
559     ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
560     written += psize;
561
562     hr = IAudioClient_GetCurrentPadding(ac, &pad);
563     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
564     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
565
566     psize = (minp / 10000000.) * pwfx->nSamplesPerSec * 10;
567
568     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
569     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
570     ok(buf != NULL, "NULL buffer returned\n");
571
572     hr = IAudioRenderClient_ReleaseBuffer(arc, psize,
573             AUDCLNT_BUFFERFLAGS_SILENT);
574     ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
575     written += psize;
576
577     hr = IAudioClient_GetCurrentPadding(ac, &pad);
578     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
579     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
580
581     /* overfull buffer. requested 1/2s buffer size, so try
582      * to get a 1/2s buffer, which should fail */
583     psize = pwfx->nSamplesPerSec / 2.;
584     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
585     ok(hr == AUDCLNT_E_BUFFER_TOO_LARGE, "GetBuffer gave wrong error: %08x\n", hr);
586
587     hr = IAudioRenderClient_ReleaseBuffer(arc, psize, 0);
588     ok(hr == AUDCLNT_E_OUT_OF_ORDER, "ReleaseBuffer gave wrong error: %08x\n", hr);
589
590     hr = IAudioClient_GetCurrentPadding(ac, &pad);
591     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
592     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
593
594     CoTaskMemFree(pwfx);
595
596     IAudioRenderClient_Release(arc);
597     IAudioClient_Release(ac);
598 }
599
600 static void test_clock(void)
601 {
602     HRESULT hr;
603     IAudioClient *ac;
604     IAudioClock *acl;
605     IAudioRenderClient *arc;
606     UINT64 freq, pos, pcpos, last;
607     BYTE *data;
608     WAVEFORMATEX *pwfx;
609
610     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
611             NULL, (void**)&ac);
612     ok(hr == S_OK, "Activation failed with %08x\n", hr);
613     if(hr != S_OK)
614         return;
615
616     hr = IAudioClient_GetMixFormat(ac, &pwfx);
617     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
618     if(hr != S_OK)
619         return;
620
621     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
622             0, 5000000, 0, pwfx, NULL);
623     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
624
625     hr = IAudioClient_GetService(ac, &IID_IAudioClock, (void**)&acl);
626     ok(hr == S_OK, "GetService(IAudioClock) failed: %08x\n", hr);
627
628     hr = IAudioClock_GetFrequency(acl, &freq);
629     ok(hr == S_OK, "GetFrequency failed: %08x\n", hr);
630
631     hr = IAudioClock_GetPosition(acl, NULL, NULL);
632     ok(hr == E_POINTER, "GetPosition wrong error: %08x\n", hr);
633
634     pcpos = 0;
635     hr = IAudioClock_GetPosition(acl, &pos, &pcpos);
636     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
637     ok(pos == 0, "GetPosition returned non-zero pos before being started\n");
638     ok(pcpos != 0, "GetPosition returned zero pcpos\n");
639
640     hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&arc);
641     ok(hr == S_OK, "GetService(IAudioRenderClient) failed: %08x\n", hr);
642
643     hr = IAudioRenderClient_GetBuffer(arc, pwfx->nSamplesPerSec / 2., &data);
644     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
645
646     hr = IAudioRenderClient_ReleaseBuffer(arc, pwfx->nSamplesPerSec / 2., AUDCLNT_BUFFERFLAGS_SILENT);
647     ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
648
649     hr = IAudioClock_GetPosition(acl, &pos, NULL);
650     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
651     ok(pos == 0, "GetPosition returned non-zero pos before being started\n");
652
653     hr = IAudioClient_Start(ac);
654     ok(hr == S_OK, "Start failed: %08x\n", hr);
655
656     Sleep(100);
657
658     hr = IAudioClock_GetPosition(acl, &pos, NULL);
659     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
660     ok(pos > 0, "Position should have been further along...\n");
661     last = pos;
662
663     hr = IAudioClient_Stop(ac);
664     ok(hr == S_OK, "Stop failed: %08x\n", hr);
665
666     hr = IAudioClock_GetPosition(acl, &pos, NULL);
667     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
668     ok(pos >= last, "Position should have been further along...\n");
669     last = pos;
670
671     hr = IAudioClient_Start(ac);
672     ok(hr == S_OK, "Start failed: %08x\n", hr);
673
674     Sleep(100);
675
676     hr = IAudioClient_Stop(ac);
677     ok(hr == S_OK, "Stop failed: %08x\n", hr);
678
679     hr = IAudioClock_GetPosition(acl, &pos, NULL);
680     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
681     ok(pos >= last, "Position should have been further along...\n");
682     last = pos;
683
684     hr = IAudioClock_GetPosition(acl, &pos, NULL);
685     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
686     ok(pos == last, "Position should have been further along...\n");
687
688     hr = IAudioClient_Reset(ac);
689     ok(hr == S_OK, "Reset failed: %08x\n", hr);
690
691     hr = IAudioClock_GetPosition(acl, &pos, NULL);
692     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
693     ok(pos == 0, "GetPosition returned non-zero pos after Reset\n");
694
695     hr = IAudioRenderClient_GetBuffer(arc, pwfx->nSamplesPerSec / 2., &data);
696     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
697
698     hr = IAudioRenderClient_ReleaseBuffer(arc, pwfx->nSamplesPerSec / 2., AUDCLNT_BUFFERFLAGS_SILENT);
699     ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
700
701     hr = IAudioClock_GetPosition(acl, &pos, NULL);
702     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
703     ok(pos == 0, "GetPosition returned non-zero pos after Reset\n");
704     last = pos;
705
706     hr = IAudioClient_Start(ac);
707     ok(hr == S_OK, "Start failed: %08x\n", hr);
708
709     Sleep(100);
710
711     hr = IAudioClock_GetPosition(acl, &pos, NULL);
712     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
713     ok(pos > last, "Position should have been further along...\n");
714
715     hr = IAudioClient_Stop(ac);
716     ok(hr == S_OK, "Stop failed: %08x\n", hr);
717
718     hr = IAudioClock_GetPosition(acl, &pos, NULL);
719     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
720     ok(pos >= last, "Position should have been further along...\n");
721
722     CoTaskMemFree(pwfx);
723
724     IAudioClock_Release(acl);
725     IAudioRenderClient_Release(arc);
726     IAudioClient_Release(ac);
727 }
728
729 static void test_session(void)
730 {
731     IAudioClient *ses1_ac1, *ses1_ac2, *cap_ac;
732     IAudioSessionControl2 *ses1_ctl, *ses1_ctl2, *cap_ctl = NULL;
733     IMMDevice *cap_dev;
734     GUID ses1_guid;
735     AudioSessionState state;
736     WAVEFORMATEX *pwfx;
737     ULONG ref;
738     HRESULT hr;
739
740     hr = CoCreateGuid(&ses1_guid);
741     ok(hr == S_OK, "CoCreateGuid failed: %08x\n", hr);
742
743     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
744             NULL, (void**)&ses1_ac1);
745     ok(hr == S_OK, "Activation failed with %08x\n", hr);
746     if (FAILED(hr)) return;
747
748     hr = IAudioClient_GetMixFormat(ses1_ac1, &pwfx);
749     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
750
751     hr = IAudioClient_Initialize(ses1_ac1, AUDCLNT_SHAREMODE_SHARED,
752             0, 5000000, 0, pwfx, &ses1_guid);
753     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
754
755     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
756             NULL, (void**)&ses1_ac2);
757     ok(hr == S_OK, "Activation failed with %08x\n", hr);
758     if(FAILED(hr)){
759         skip("Unable to open the same device twice. Skipping session tests\n");
760
761         ref = IAudioClient_Release(ses1_ac1);
762         ok(ref == 0, "AudioClient wasn't released: %u\n", ref);
763         return;
764     }
765
766     hr = IAudioClient_Initialize(ses1_ac2, AUDCLNT_SHAREMODE_SHARED,
767             0, 5000000, 0, pwfx, &ses1_guid);
768     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
769
770     hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme, eCapture,
771             eMultimedia, &cap_dev);
772     if(hr == S_OK){
773         hr = IMMDevice_Activate(cap_dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
774                 NULL, (void**)&cap_ac);
775         ok((hr == S_OK)^(cap_ac == NULL), "Activate %08x &out pointer\n", hr);
776         ok(hr == S_OK, "Activate failed: %08x\n", hr);
777         IMMDevice_Release(cap_dev);
778     }
779     if(hr == S_OK){
780         WAVEFORMATEX *cap_pwfx;
781
782         hr = IAudioClient_GetMixFormat(cap_ac, &cap_pwfx);
783         ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
784
785         hr = IAudioClient_Initialize(cap_ac, AUDCLNT_SHAREMODE_SHARED,
786                 0, 5000000, 0, cap_pwfx, &ses1_guid);
787         ok(hr == S_OK, "Initialize failed for capture in rendering session: %08x\n", hr);
788         CoTaskMemFree(cap_pwfx);
789     }
790     if(hr == S_OK){
791         hr = IAudioClient_GetService(cap_ac, &IID_IAudioSessionControl, (void**)&cap_ctl);
792         ok(hr == S_OK, "GetService failed: %08x\n", hr);
793         if(FAILED(hr))
794             cap_ctl = NULL;
795     }else
796         skip("No capture session: %08x; skipping capture device in render session tests\n", hr);
797
798     hr = IAudioClient_GetService(ses1_ac1, &IID_IAudioSessionControl2, (void**)&ses1_ctl);
799     ok(hr == E_NOINTERFACE, "GetService gave wrong error: %08x\n", hr);
800
801     hr = IAudioClient_GetService(ses1_ac1, &IID_IAudioSessionControl, (void**)&ses1_ctl);
802     ok(hr == S_OK, "GetService failed: %08x\n", hr);
803
804     hr = IAudioClient_GetService(ses1_ac1, &IID_IAudioSessionControl, (void**)&ses1_ctl2);
805     ok(hr == S_OK, "GetService failed: %08x\n", hr);
806     ok(ses1_ctl == ses1_ctl2, "Got different controls: %p %p\n", ses1_ctl, ses1_ctl2);
807     ref = IAudioSessionControl_Release(ses1_ctl2);
808     ok(ref != 0, "AudioSessionControl was destroyed\n");
809
810     hr = IAudioClient_GetService(ses1_ac2, &IID_IAudioSessionControl, (void**)&ses1_ctl2);
811     ok(hr == S_OK, "GetService failed: %08x\n", hr);
812
813     hr = IAudioSessionControl_GetState(ses1_ctl, NULL);
814     ok(hr == NULL_PTR_ERR, "GetState gave wrong error: %08x\n", hr);
815
816     hr = IAudioSessionControl_GetState(ses1_ctl, &state);
817     ok(hr == S_OK, "GetState failed: %08x\n", hr);
818     ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
819
820     hr = IAudioSessionControl_GetState(ses1_ctl2, &state);
821     ok(hr == S_OK, "GetState failed: %08x\n", hr);
822     ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
823
824     if(cap_ctl){
825         hr = IAudioSessionControl_GetState(cap_ctl, &state);
826         ok(hr == S_OK, "GetState failed: %08x\n", hr);
827         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
828     }
829
830     hr = IAudioClient_Start(ses1_ac1);
831     ok(hr == S_OK, "Start failed: %08x\n", hr);
832
833     hr = IAudioSessionControl_GetState(ses1_ctl, &state);
834     ok(hr == S_OK, "GetState failed: %08x\n", hr);
835     ok(state == AudioSessionStateActive, "Got wrong state: %d\n", state);
836
837     hr = IAudioSessionControl_GetState(ses1_ctl2, &state);
838     ok(hr == S_OK, "GetState failed: %08x\n", hr);
839     ok(state == AudioSessionStateActive, "Got wrong state: %d\n", state);
840
841     if(cap_ctl){
842         hr = IAudioSessionControl_GetState(cap_ctl, &state);
843         ok(hr == S_OK, "GetState failed: %08x\n", hr);
844         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
845     }
846
847     hr = IAudioClient_Stop(ses1_ac1);
848     ok(hr == S_OK, "Start failed: %08x\n", hr);
849
850     hr = IAudioSessionControl_GetState(ses1_ctl, &state);
851     ok(hr == S_OK, "GetState failed: %08x\n", hr);
852     ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
853
854     hr = IAudioSessionControl_GetState(ses1_ctl2, &state);
855     ok(hr == S_OK, "GetState failed: %08x\n", hr);
856     ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
857
858     if(cap_ctl){
859         hr = IAudioSessionControl_GetState(cap_ctl, &state);
860         ok(hr == S_OK, "GetState failed: %08x\n", hr);
861         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
862
863         hr = IAudioClient_Start(cap_ac);
864         ok(hr == S_OK, "Start failed: %08x\n", hr);
865
866         hr = IAudioSessionControl_GetState(ses1_ctl, &state);
867         ok(hr == S_OK, "GetState failed: %08x\n", hr);
868         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
869
870         hr = IAudioSessionControl_GetState(ses1_ctl2, &state);
871         ok(hr == S_OK, "GetState failed: %08x\n", hr);
872         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
873
874         hr = IAudioSessionControl_GetState(cap_ctl, &state);
875         ok(hr == S_OK, "GetState failed: %08x\n", hr);
876         ok(state == AudioSessionStateActive, "Got wrong state: %d\n", state);
877
878         hr = IAudioClient_Stop(cap_ac);
879         ok(hr == S_OK, "Stop failed: %08x\n", hr);
880
881         hr = IAudioSessionControl_GetState(ses1_ctl, &state);
882         ok(hr == S_OK, "GetState failed: %08x\n", hr);
883         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
884
885         hr = IAudioSessionControl_GetState(ses1_ctl2, &state);
886         ok(hr == S_OK, "GetState failed: %08x\n", hr);
887         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
888
889         hr = IAudioSessionControl_GetState(cap_ctl, &state);
890         ok(hr == S_OK, "GetState failed: %08x\n", hr);
891         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
892
893         ref = IAudioSessionControl_Release(cap_ctl);
894         ok(ref == 0, "AudioSessionControl wasn't released: %u\n", ref);
895
896         ref = IAudioClient_Release(cap_ac);
897         ok(ref == 0, "AudioClient wasn't released: %u\n", ref);
898     }
899
900     ref = IAudioSessionControl_Release(ses1_ctl);
901     ok(ref == 0, "AudioSessionControl wasn't released: %u\n", ref);
902
903     ref = IAudioClient_Release(ses1_ac1);
904     ok(ref == 0, "AudioClient wasn't released: %u\n", ref);
905
906     ref = IAudioClient_Release(ses1_ac2);
907     ok(ref == 1, "AudioClient had wrong refcount: %u\n", ref);
908
909     /* we've released all of our IAudioClient references, so check GetState */
910     hr = IAudioSessionControl_GetState(ses1_ctl2, &state);
911     ok(hr == S_OK, "GetState failed: %08x\n", hr);
912     ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
913
914     ref = IAudioSessionControl_Release(ses1_ctl2);
915     ok(ref == 0, "AudioSessionControl wasn't released: %u\n", ref);
916
917     CoTaskMemFree(pwfx);
918 }
919
920 static void test_streamvolume(void)
921 {
922     IAudioClient *ac;
923     IAudioStreamVolume *asv;
924     WAVEFORMATEX *fmt;
925     UINT32 chans, i;
926     HRESULT hr;
927     float vol, *vols;
928
929     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
930             NULL, (void**)&ac);
931     ok(hr == S_OK, "Activation failed with %08x\n", hr);
932     if(hr != S_OK)
933         return;
934
935     hr = IAudioClient_GetMixFormat(ac, &fmt);
936     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
937
938     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
939             0, fmt, NULL);
940     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
941
942     hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&asv);
943     ok(hr == S_OK, "GetService failed: %08x\n", hr);
944
945     hr = IAudioStreamVolume_GetChannelCount(asv, NULL);
946     ok(hr == E_POINTER, "GetChannelCount gave wrong error: %08x\n", hr);
947
948     hr = IAudioStreamVolume_GetChannelCount(asv, &chans);
949     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
950     ok(chans == fmt->nChannels, "GetChannelCount gave wrong number of channels: %d\n", chans);
951
952     hr = IAudioStreamVolume_GetChannelVolume(asv, fmt->nChannels, NULL);
953     ok(hr == E_POINTER, "GetChannelCount gave wrong error: %08x\n", hr);
954
955     hr = IAudioStreamVolume_GetChannelVolume(asv, fmt->nChannels, &vol);
956     ok(hr == E_INVALIDARG, "GetChannelCount gave wrong error: %08x\n", hr);
957
958     hr = IAudioStreamVolume_GetChannelVolume(asv, 0, NULL);
959     ok(hr == E_POINTER, "GetChannelCount gave wrong error: %08x\n", hr);
960
961     hr = IAudioStreamVolume_GetChannelVolume(asv, 0, &vol);
962     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
963     ok(vol == 1.f, "Channel volume was not 1: %f\n", vol);
964
965     hr = IAudioStreamVolume_SetChannelVolume(asv, fmt->nChannels, -1.f);
966     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
967
968     hr = IAudioStreamVolume_SetChannelVolume(asv, 0, -1.f);
969     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
970
971     hr = IAudioStreamVolume_SetChannelVolume(asv, 0, 2.f);
972     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
973
974     hr = IAudioStreamVolume_SetChannelVolume(asv, 0, 0.2f);
975     ok(hr == S_OK, "SetChannelVolume failed: %08x\n", hr);
976
977     hr = IAudioStreamVolume_GetChannelVolume(asv, 0, &vol);
978     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
979     ok(fabsf(vol - 0.2f) < 0.05f, "Channel volume wasn't 0.2: %f\n", vol);
980
981     hr = IAudioStreamVolume_GetAllVolumes(asv, 0, NULL);
982     ok(hr == E_POINTER, "GetAllVolumes gave wrong error: %08x\n", hr);
983
984     hr = IAudioStreamVolume_GetAllVolumes(asv, fmt->nChannels, NULL);
985     ok(hr == E_POINTER, "GetAllVolumes gave wrong error: %08x\n", hr);
986
987     vols = HeapAlloc(GetProcessHeap(), 0, fmt->nChannels * sizeof(float));
988     ok(vols != NULL, "HeapAlloc failed\n");
989
990     hr = IAudioStreamVolume_GetAllVolumes(asv, fmt->nChannels - 1, vols);
991     ok(hr == E_INVALIDARG, "GetAllVolumes gave wrong error: %08x\n", hr);
992
993     hr = IAudioStreamVolume_GetAllVolumes(asv, fmt->nChannels, vols);
994     ok(hr == S_OK, "GetAllVolumes failed: %08x\n", hr);
995     ok(fabsf(vols[0] - 0.2f) < 0.05f, "Channel 0 volume wasn't 0.2: %f\n", vol);
996     for(i = 1; i < fmt->nChannels; ++i)
997         ok(vols[i] == 1.f, "Channel %d volume is not 1: %f\n", i, vols[i]);
998
999     hr = IAudioStreamVolume_SetAllVolumes(asv, 0, NULL);
1000     ok(hr == E_POINTER, "SetAllVolumes gave wrong error: %08x\n", hr);
1001
1002     hr = IAudioStreamVolume_SetAllVolumes(asv, fmt->nChannels, NULL);
1003     ok(hr == E_POINTER, "SetAllVolumes gave wrong error: %08x\n", hr);
1004
1005     hr = IAudioStreamVolume_SetAllVolumes(asv, fmt->nChannels - 1, vols);
1006     ok(hr == E_INVALIDARG, "SetAllVolumes gave wrong error: %08x\n", hr);
1007
1008     hr = IAudioStreamVolume_SetAllVolumes(asv, fmt->nChannels, vols);
1009     ok(hr == S_OK, "SetAllVolumes failed: %08x\n", hr);
1010
1011     HeapFree(GetProcessHeap(), 0, vols);
1012     IAudioStreamVolume_Release(asv);
1013     IAudioClient_Release(ac);
1014     CoTaskMemFree(fmt);
1015 }
1016
1017 static void test_channelvolume(void)
1018 {
1019     IAudioClient *ac;
1020     IChannelAudioVolume *acv;
1021     WAVEFORMATEX *fmt;
1022     UINT32 chans, i;
1023     HRESULT hr;
1024     float vol, *vols;
1025
1026     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1027             NULL, (void**)&ac);
1028     ok(hr == S_OK, "Activation failed with %08x\n", hr);
1029     if(hr != S_OK)
1030         return;
1031
1032     hr = IAudioClient_GetMixFormat(ac, &fmt);
1033     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1034
1035     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
1036             AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, NULL);
1037     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1038
1039     hr = IAudioClient_GetService(ac, &IID_IChannelAudioVolume, (void**)&acv);
1040     ok(hr == S_OK, "GetService failed: %08x\n", hr);
1041
1042     hr = IChannelAudioVolume_GetChannelCount(acv, NULL);
1043     ok(hr == NULL_PTR_ERR, "GetChannelCount gave wrong error: %08x\n", hr);
1044
1045     hr = IChannelAudioVolume_GetChannelCount(acv, &chans);
1046     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1047     ok(chans == fmt->nChannels, "GetChannelCount gave wrong number of channels: %d\n", chans);
1048
1049     hr = IChannelAudioVolume_GetChannelVolume(acv, fmt->nChannels, NULL);
1050     ok(hr == NULL_PTR_ERR, "GetChannelCount gave wrong error: %08x\n", hr);
1051
1052     hr = IChannelAudioVolume_GetChannelVolume(acv, fmt->nChannels, &vol);
1053     ok(hr == E_INVALIDARG, "GetChannelCount gave wrong error: %08x\n", hr);
1054
1055     hr = IChannelAudioVolume_GetChannelVolume(acv, 0, NULL);
1056     ok(hr == NULL_PTR_ERR, "GetChannelCount gave wrong error: %08x\n", hr);
1057
1058     hr = IChannelAudioVolume_GetChannelVolume(acv, 0, &vol);
1059     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1060     ok(vol == 1.f, "Channel volume was not 1: %f\n", vol);
1061
1062     hr = IChannelAudioVolume_SetChannelVolume(acv, fmt->nChannels, -1.f, NULL);
1063     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
1064
1065     hr = IChannelAudioVolume_SetChannelVolume(acv, 0, -1.f, NULL);
1066     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
1067
1068     hr = IChannelAudioVolume_SetChannelVolume(acv, 0, 2.f, NULL);
1069     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
1070
1071     hr = IChannelAudioVolume_SetChannelVolume(acv, 0, 0.2f, NULL);
1072     ok(hr == S_OK, "SetChannelVolume failed: %08x\n", hr);
1073
1074     hr = IChannelAudioVolume_GetChannelVolume(acv, 0, &vol);
1075     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1076     ok(fabsf(vol - 0.2f) < 0.05f, "Channel volume wasn't 0.2: %f\n", vol);
1077
1078     hr = IChannelAudioVolume_GetAllVolumes(acv, 0, NULL);
1079     ok(hr == NULL_PTR_ERR, "GetAllVolumes gave wrong error: %08x\n", hr);
1080
1081     hr = IChannelAudioVolume_GetAllVolumes(acv, fmt->nChannels, NULL);
1082     ok(hr == NULL_PTR_ERR, "GetAllVolumes gave wrong error: %08x\n", hr);
1083
1084     vols = HeapAlloc(GetProcessHeap(), 0, fmt->nChannels * sizeof(float));
1085     ok(vols != NULL, "HeapAlloc failed\n");
1086
1087     hr = IChannelAudioVolume_GetAllVolumes(acv, fmt->nChannels - 1, vols);
1088     ok(hr == E_INVALIDARG, "GetAllVolumes gave wrong error: %08x\n", hr);
1089
1090     hr = IChannelAudioVolume_GetAllVolumes(acv, fmt->nChannels, vols);
1091     ok(hr == S_OK, "GetAllVolumes failed: %08x\n", hr);
1092     ok(fabsf(vols[0] - 0.2f) < 0.05f, "Channel 0 volume wasn't 0.2: %f\n", vol);
1093     for(i = 1; i < fmt->nChannels; ++i)
1094         ok(vols[i] == 1.f, "Channel %d volume is not 1: %f\n", i, vols[i]);
1095
1096     hr = IChannelAudioVolume_SetAllVolumes(acv, 0, NULL, NULL);
1097     ok(hr == NULL_PTR_ERR, "SetAllVolumes gave wrong error: %08x\n", hr);
1098
1099     hr = IChannelAudioVolume_SetAllVolumes(acv, fmt->nChannels, NULL, NULL);
1100     ok(hr == NULL_PTR_ERR, "SetAllVolumes gave wrong error: %08x\n", hr);
1101
1102     hr = IChannelAudioVolume_SetAllVolumes(acv, fmt->nChannels - 1, vols, NULL);
1103     ok(hr == E_INVALIDARG, "SetAllVolumes gave wrong error: %08x\n", hr);
1104
1105     hr = IChannelAudioVolume_SetAllVolumes(acv, fmt->nChannels, vols, NULL);
1106     ok(hr == S_OK, "SetAllVolumes failed: %08x\n", hr);
1107
1108     hr = IChannelAudioVolume_SetChannelVolume(acv, 0, 1.0f, NULL);
1109     ok(hr == S_OK, "SetChannelVolume failed: %08x\n", hr);
1110
1111     HeapFree(GetProcessHeap(), 0, vols);
1112     IChannelAudioVolume_Release(acv);
1113     IAudioClient_Release(ac);
1114     CoTaskMemFree(fmt);
1115 }
1116
1117 static void test_simplevolume(void)
1118 {
1119     IAudioClient *ac;
1120     ISimpleAudioVolume *sav;
1121     WAVEFORMATEX *fmt;
1122     HRESULT hr;
1123     float vol;
1124     BOOL mute;
1125
1126     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1127             NULL, (void**)&ac);
1128     ok(hr == S_OK, "Activation failed with %08x\n", hr);
1129     if(hr != S_OK)
1130         return;
1131
1132     hr = IAudioClient_GetMixFormat(ac, &fmt);
1133     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1134
1135     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
1136             AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, NULL);
1137     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1138
1139     hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
1140     ok(hr == S_OK, "GetService failed: %08x\n", hr);
1141
1142     hr = ISimpleAudioVolume_GetMasterVolume(sav, NULL);
1143     ok(hr == NULL_PTR_ERR, "GetMasterVolume gave wrong error: %08x\n", hr);
1144
1145     hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
1146     ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1147     ok(vol == 1.f, "Master volume wasn't 1: %f\n", vol);
1148
1149     hr = ISimpleAudioVolume_SetMasterVolume(sav, -1.f, NULL);
1150     ok(hr == E_INVALIDARG, "SetMasterVolume gave wrong error: %08x\n", hr);
1151
1152     hr = ISimpleAudioVolume_SetMasterVolume(sav, 2.f, NULL);
1153     ok(hr == E_INVALIDARG, "SetMasterVolume gave wrong error: %08x\n", hr);
1154
1155     hr = ISimpleAudioVolume_SetMasterVolume(sav, 0.2f, NULL);
1156     ok(hr == S_OK, "SetMasterVolume failed: %08x\n", hr);
1157
1158     hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
1159     ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1160     ok(fabsf(vol - 0.2f) < 0.05f, "Master volume wasn't 0.2: %f\n", vol);
1161
1162     hr = ISimpleAudioVolume_GetMute(sav, NULL);
1163     ok(hr == NULL_PTR_ERR, "GetMute gave wrong error: %08x\n", hr);
1164
1165     mute = TRUE;
1166     hr = ISimpleAudioVolume_GetMute(sav, &mute);
1167     ok(hr == S_OK, "GetMute failed: %08x\n", hr);
1168     ok(mute == FALSE, "Session is already muted\n");
1169
1170     hr = ISimpleAudioVolume_SetMute(sav, TRUE, NULL);
1171     ok(hr == S_OK, "SetMute failed: %08x\n", hr);
1172
1173     mute = FALSE;
1174     hr = ISimpleAudioVolume_GetMute(sav, &mute);
1175     ok(hr == S_OK, "GetMute failed: %08x\n", hr);
1176     ok(mute == TRUE, "Session should have been muted\n");
1177
1178     hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
1179     ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1180     ok(fabsf(vol - 0.2f) < 0.05f, "Master volume wasn't 0.2: %f\n", vol);
1181
1182     hr = ISimpleAudioVolume_SetMasterVolume(sav, 1.f, NULL);
1183     ok(hr == S_OK, "SetMasterVolume failed: %08x\n", hr);
1184
1185     mute = FALSE;
1186     hr = ISimpleAudioVolume_GetMute(sav, &mute);
1187     ok(hr == S_OK, "GetMute failed: %08x\n", hr);
1188     ok(mute == TRUE, "Session should have been muted\n");
1189
1190     hr = ISimpleAudioVolume_SetMute(sav, FALSE, NULL);
1191     ok(hr == S_OK, "SetMute failed: %08x\n", hr);
1192
1193     ISimpleAudioVolume_Release(sav);
1194     IAudioClient_Release(ac);
1195     CoTaskMemFree(fmt);
1196 }
1197
1198 static void test_volume_dependence(void)
1199 {
1200     IAudioClient *ac, *ac2;
1201     ISimpleAudioVolume *sav;
1202     IChannelAudioVolume *cav;
1203     IAudioStreamVolume *asv;
1204     WAVEFORMATEX *fmt;
1205     HRESULT hr;
1206     float vol;
1207     GUID session;
1208     UINT32 nch;
1209
1210     hr = CoCreateGuid(&session);
1211     ok(hr == S_OK, "CoCreateGuid failed: %08x\n", hr);
1212
1213     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1214             NULL, (void**)&ac);
1215     ok(hr == S_OK, "Activation failed with %08x\n", hr);
1216     if(hr != S_OK)
1217         return;
1218
1219     hr = IAudioClient_GetMixFormat(ac, &fmt);
1220     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1221
1222     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
1223             AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, &session);
1224     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1225
1226     hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
1227     ok(hr == S_OK, "GetService (SimpleAudioVolume) failed: %08x\n", hr);
1228
1229     hr = IAudioClient_GetService(ac, &IID_IChannelAudioVolume, (void**)&cav);
1230     ok(hr == S_OK, "GetService (ChannelAudioVolme) failed: %08x\n", hr);
1231
1232     hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&asv);
1233     ok(hr == S_OK, "GetService (AudioStreamVolume) failed: %08x\n", hr);
1234
1235     hr = IAudioStreamVolume_SetChannelVolume(asv, 0, 0.2f);
1236     ok(hr == S_OK, "ASV_SetChannelVolume failed: %08x\n", hr);
1237
1238     hr = IChannelAudioVolume_SetChannelVolume(cav, 0, 0.4f, NULL);
1239     ok(hr == S_OK, "CAV_SetChannelVolume failed: %08x\n", hr);
1240
1241     hr = ISimpleAudioVolume_SetMasterVolume(sav, 0.6f, NULL);
1242     ok(hr == S_OK, "SAV_SetMasterVolume failed: %08x\n", hr);
1243
1244     hr = IAudioStreamVolume_GetChannelVolume(asv, 0, &vol);
1245     ok(hr == S_OK, "ASV_GetChannelVolume failed: %08x\n", hr);
1246     ok(fabsf(vol - 0.2) < 0.05f, "ASV_GetChannelVolume gave wrong volume: %f\n", vol);
1247
1248     hr = IChannelAudioVolume_GetChannelVolume(cav, 0, &vol);
1249     ok(hr == S_OK, "CAV_GetChannelVolume failed: %08x\n", hr);
1250     ok(fabsf(vol - 0.4) < 0.05f, "CAV_GetChannelVolume gave wrong volume: %f\n", vol);
1251
1252     hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
1253     ok(hr == S_OK, "SAV_GetMasterVolume failed: %08x\n", hr);
1254     ok(fabsf(vol - 0.6) < 0.05f, "SAV_GetMasterVolume gave wrong volume: %f\n", vol);
1255
1256     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1257             NULL, (void**)&ac2);
1258     if(SUCCEEDED(hr)){
1259         IChannelAudioVolume *cav2;
1260         IAudioStreamVolume *asv2;
1261
1262         hr = IAudioClient_Initialize(ac2, AUDCLNT_SHAREMODE_SHARED,
1263                 AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, &session);
1264         ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1265
1266         hr = IAudioClient_GetService(ac2, &IID_IChannelAudioVolume, (void**)&cav2);
1267         ok(hr == S_OK, "GetService failed: %08x\n", hr);
1268
1269         hr = IAudioClient_GetService(ac2, &IID_IAudioStreamVolume, (void**)&asv2);
1270         ok(hr == S_OK, "GetService failed: %08x\n", hr);
1271
1272         hr = IChannelAudioVolume_GetChannelVolume(cav2, 0, &vol);
1273         ok(hr == S_OK, "CAV_GetChannelVolume failed: %08x\n", hr);
1274         ok(fabsf(vol - 0.4) < 0.05f, "CAV_GetChannelVolume gave wrong volume: %f\n", vol);
1275
1276         hr = IAudioStreamVolume_GetChannelVolume(asv2, 0, &vol);
1277         ok(hr == S_OK, "ASV_GetChannelVolume failed: %08x\n", hr);
1278         ok(vol == 1.f, "ASV_GetChannelVolume gave wrong volume: %f\n", vol);
1279
1280         hr = IChannelAudioVolume_GetChannelCount(cav2, &nch);
1281         ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1282         ok(nch == fmt->nChannels, "Got wrong channel count, expected %u: %u\n", fmt->nChannels, nch);
1283
1284         hr = IAudioStreamVolume_GetChannelCount(asv2, &nch);
1285         ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1286         ok(nch == fmt->nChannels, "Got wrong channel count, expected %u: %u\n", fmt->nChannels, nch);
1287
1288         IAudioStreamVolume_Release(asv2);
1289         IChannelAudioVolume_Release(cav2);
1290         IAudioClient_Release(ac2);
1291     }else
1292         skip("Unable to open the same device twice. Skipping session volume control tests\n");
1293
1294     hr = IChannelAudioVolume_SetChannelVolume(cav, 0, 1.f, NULL);
1295     ok(hr == S_OK, "CAV_SetChannelVolume failed: %08x\n", hr);
1296
1297     hr = ISimpleAudioVolume_SetMasterVolume(sav, 1.f, NULL);
1298     ok(hr == S_OK, "SAV_SetMasterVolume failed: %08x\n", hr);
1299
1300     CoTaskMemFree(fmt);
1301     ISimpleAudioVolume_Release(sav);
1302     IChannelAudioVolume_Release(cav);
1303     IAudioStreamVolume_Release(asv);
1304     IAudioClient_Release(ac);
1305 }
1306
1307 static void test_session_creation(void)
1308 {
1309     IMMDevice *cap_dev;
1310     IAudioClient *ac;
1311     IAudioSessionManager *sesm;
1312     ISimpleAudioVolume *sav;
1313     GUID session_guid;
1314     float vol;
1315     HRESULT hr;
1316     WAVEFORMATEX *fmt;
1317
1318     CoCreateGuid(&session_guid);
1319
1320     hr = IMMDevice_Activate(dev, &IID_IAudioSessionManager,
1321             CLSCTX_INPROC_SERVER, NULL, (void**)&sesm);
1322     ok((hr == S_OK)^(sesm == NULL), "Activate %08x &out pointer\n", hr);
1323     ok(hr == S_OK, "Activate failed: %08x\n", hr);
1324
1325     hr = IAudioSessionManager_GetSimpleAudioVolume(sesm, &session_guid,
1326             FALSE, &sav);
1327     ok(hr == S_OK, "GetSimpleAudioVolume failed: %08x\n", hr);
1328
1329     hr = ISimpleAudioVolume_SetMasterVolume(sav, 0.6f, NULL);
1330     ok(hr == S_OK, "SetMasterVolume failed: %08x\n", hr);
1331
1332     /* Release completely to show session persistence */
1333     ISimpleAudioVolume_Release(sav);
1334     IAudioSessionManager_Release(sesm);
1335
1336     /* test if we can create a capture audioclient in the session we just
1337      * created from a SessionManager derived from a render device */
1338     hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme, eCapture,
1339             eMultimedia, &cap_dev);
1340     if(hr == S_OK){
1341         WAVEFORMATEX *cap_pwfx;
1342         IAudioClient *cap_ac;
1343         ISimpleAudioVolume *cap_sav;
1344         IAudioSessionManager *cap_sesm;
1345
1346         hr = IMMDevice_Activate(cap_dev, &IID_IAudioSessionManager,
1347                 CLSCTX_INPROC_SERVER, NULL, (void**)&cap_sesm);
1348         ok((hr == S_OK)^(cap_sesm == NULL), "Activate %08x &out pointer\n", hr);
1349         ok(hr == S_OK, "Activate failed: %08x\n", hr);
1350
1351         hr = IAudioSessionManager_GetSimpleAudioVolume(cap_sesm, &session_guid,
1352                 FALSE, &cap_sav);
1353         ok(hr == S_OK, "GetSimpleAudioVolume failed: %08x\n", hr);
1354
1355         vol = 0.5f;
1356         hr = ISimpleAudioVolume_GetMasterVolume(cap_sav, &vol);
1357         ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1358         ok(vol == 1.f, "Got wrong volume: %f\n", vol);
1359
1360         ISimpleAudioVolume_Release(cap_sav);
1361         IAudioSessionManager_Release(cap_sesm);
1362
1363         hr = IMMDevice_Activate(cap_dev, &IID_IAudioClient,
1364                 CLSCTX_INPROC_SERVER, NULL, (void**)&cap_ac);
1365         ok(hr == S_OK, "Activate failed: %08x\n", hr);
1366
1367         IMMDevice_Release(cap_dev);
1368
1369         hr = IAudioClient_GetMixFormat(cap_ac, &cap_pwfx);
1370         ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1371
1372         hr = IAudioClient_Initialize(cap_ac, AUDCLNT_SHAREMODE_SHARED,
1373                 0, 5000000, 0, cap_pwfx, &session_guid);
1374         ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1375
1376         CoTaskMemFree(cap_pwfx);
1377
1378         if(hr == S_OK){
1379             hr = IAudioClient_GetService(cap_ac, &IID_ISimpleAudioVolume,
1380                     (void**)&cap_sav);
1381             ok(hr == S_OK, "GetService failed: %08x\n", hr);
1382         }
1383         if(hr == S_OK){
1384             vol = 0.5f;
1385             hr = ISimpleAudioVolume_GetMasterVolume(cap_sav, &vol);
1386             ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1387             ok(vol == 1.f, "Got wrong volume: %f\n", vol);
1388
1389             ISimpleAudioVolume_Release(cap_sav);
1390         }
1391
1392         IAudioClient_Release(cap_ac);
1393     }
1394
1395     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1396             NULL, (void**)&ac);
1397     ok((hr == S_OK)^(ac == NULL), "Activate %08x &out pointer\n", hr);
1398     ok(hr == S_OK, "Activation failed with %08x\n", hr);
1399
1400     hr = IAudioClient_GetMixFormat(ac, &fmt);
1401     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1402
1403     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
1404             AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, &session_guid);
1405     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1406
1407     hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
1408     ok(hr == S_OK, "GetService failed: %08x\n", hr);
1409     if(hr == S_OK){
1410         vol = 0.5f;
1411         hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
1412         ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1413         ok(fabs(vol - 0.6f) < 0.05f, "Got wrong volume: %f\n", vol);
1414
1415         ISimpleAudioVolume_Release(sav);
1416     }
1417
1418     CoTaskMemFree(fmt);
1419     IAudioClient_Release(ac);
1420 }
1421
1422 START_TEST(render)
1423 {
1424     HRESULT hr;
1425
1426     CoInitializeEx(NULL, COINIT_MULTITHREADED);
1427     hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme);
1428     if (FAILED(hr))
1429     {
1430         skip("mmdevapi not available: 0x%08x\n", hr);
1431         goto cleanup;
1432     }
1433
1434     hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme, eRender, eMultimedia, &dev);
1435     ok(hr == S_OK || hr == E_NOTFOUND, "GetDefaultAudioEndpoint failed: 0x%08x\n", hr);
1436     if (hr != S_OK || !dev)
1437     {
1438         if (hr == E_NOTFOUND)
1439             skip("No sound card available\n");
1440         else
1441             skip("GetDefaultAudioEndpoint returns 0x%08x\n", hr);
1442         goto cleanup;
1443     }
1444
1445     test_audioclient();
1446     test_references();
1447     test_event();
1448     test_padding();
1449     test_clock();
1450     test_session();
1451     test_streamvolume();
1452     test_channelvolume();
1453     test_simplevolume();
1454     test_volume_dependence();
1455     test_session_creation();
1456
1457     IMMDevice_Release(dev);
1458
1459 cleanup:
1460     if (mme)
1461         IMMDeviceEnumerator_Release(mme);
1462     CoUninitialize();
1463 }