mshtml: Reinitialize list entry in detach_plugin_host.
[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     if(hr != S_OK)
534         return;
535
536     hr = IAudioClient_GetDevicePeriod(ac, &defp, &minp);
537     ok(hr == S_OK, "GetDevicePeriod failed: %08x\n", hr);
538     ok(defp != 0, "Default period is 0\n");
539     ok(minp != 0, "Minimum period is 0\n");
540     ok(minp <= defp, "Mininum period is greater than default period\n");
541
542     hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&arc);
543     ok(hr == S_OK, "GetService failed: %08x\n", hr);
544
545     psize = (defp / 10000000.) * pwfx->nSamplesPerSec * 10;
546
547     written = 0;
548     hr = IAudioClient_GetCurrentPadding(ac, &pad);
549     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
550     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
551
552     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
553     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
554     ok(buf != NULL, "NULL buffer returned\n");
555
556     hr = IAudioClient_Reset(ac);
557     ok(hr == AUDCLNT_E_BUFFER_OPERATION_PENDING, "Reset failed: %08x\n", hr);
558
559     hr = IAudioRenderClient_ReleaseBuffer(arc, psize,
560             AUDCLNT_BUFFERFLAGS_SILENT);
561     ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
562     written += psize;
563
564     hr = IAudioClient_GetCurrentPadding(ac, &pad);
565     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
566     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
567
568     psize = (minp / 10000000.) * pwfx->nSamplesPerSec * 10;
569
570     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
571     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
572     ok(buf != NULL, "NULL buffer returned\n");
573
574     hr = IAudioRenderClient_ReleaseBuffer(arc, psize,
575             AUDCLNT_BUFFERFLAGS_SILENT);
576     ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
577     written += psize;
578
579     hr = IAudioClient_GetCurrentPadding(ac, &pad);
580     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
581     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
582
583     /* overfull buffer. requested 1/2s buffer size, so try
584      * to get a 1/2s buffer, which should fail */
585     psize = pwfx->nSamplesPerSec / 2.;
586     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
587     ok(hr == AUDCLNT_E_BUFFER_TOO_LARGE, "GetBuffer gave wrong error: %08x\n", hr);
588
589     hr = IAudioRenderClient_ReleaseBuffer(arc, psize, 0);
590     ok(hr == AUDCLNT_E_OUT_OF_ORDER, "ReleaseBuffer gave wrong error: %08x\n", hr);
591
592     hr = IAudioClient_GetCurrentPadding(ac, &pad);
593     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
594     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
595
596     CoTaskMemFree(pwfx);
597
598     IAudioRenderClient_Release(arc);
599     IAudioClient_Release(ac);
600 }
601
602 static void test_clock(void)
603 {
604     HRESULT hr;
605     IAudioClient *ac;
606     IAudioClock *acl;
607     IAudioRenderClient *arc;
608     UINT64 freq, pos, pcpos, last;
609     BYTE *data;
610     WAVEFORMATEX *pwfx;
611
612     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
613             NULL, (void**)&ac);
614     ok(hr == S_OK, "Activation failed with %08x\n", hr);
615     if(hr != S_OK)
616         return;
617
618     hr = IAudioClient_GetMixFormat(ac, &pwfx);
619     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
620     if(hr != S_OK)
621         return;
622
623     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
624             0, 5000000, 0, pwfx, NULL);
625     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
626
627     hr = IAudioClient_GetService(ac, &IID_IAudioClock, (void**)&acl);
628     ok(hr == S_OK, "GetService(IAudioClock) failed: %08x\n", hr);
629
630     hr = IAudioClock_GetFrequency(acl, &freq);
631     ok(hr == S_OK, "GetFrequency failed: %08x\n", hr);
632
633     hr = IAudioClock_GetPosition(acl, NULL, NULL);
634     ok(hr == E_POINTER, "GetPosition wrong error: %08x\n", hr);
635
636     pcpos = 0;
637     hr = IAudioClock_GetPosition(acl, &pos, &pcpos);
638     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
639     ok(pos == 0, "GetPosition returned non-zero pos before being started\n");
640     ok(pcpos != 0, "GetPosition returned zero pcpos\n");
641
642     hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&arc);
643     ok(hr == S_OK, "GetService(IAudioRenderClient) failed: %08x\n", hr);
644
645     hr = IAudioRenderClient_GetBuffer(arc, pwfx->nSamplesPerSec / 2., &data);
646     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
647
648     hr = IAudioRenderClient_ReleaseBuffer(arc, pwfx->nSamplesPerSec / 2., AUDCLNT_BUFFERFLAGS_SILENT);
649     ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
650
651     hr = IAudioClock_GetPosition(acl, &pos, NULL);
652     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
653     ok(pos == 0, "GetPosition returned non-zero pos before being started\n");
654
655     hr = IAudioClient_Start(ac);
656     ok(hr == S_OK, "Start failed: %08x\n", hr);
657
658     Sleep(100);
659
660     hr = IAudioClock_GetPosition(acl, &pos, NULL);
661     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
662     ok(pos > 0, "Position should have been further along...\n");
663     last = pos;
664
665     hr = IAudioClient_Stop(ac);
666     ok(hr == S_OK, "Stop failed: %08x\n", hr);
667
668     hr = IAudioClock_GetPosition(acl, &pos, NULL);
669     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
670     ok(pos >= last, "Position should have been further along...\n");
671     last = pos;
672
673     hr = IAudioClient_Start(ac);
674     ok(hr == S_OK, "Start failed: %08x\n", hr);
675
676     Sleep(100);
677
678     hr = IAudioClient_Stop(ac);
679     ok(hr == S_OK, "Stop failed: %08x\n", hr);
680
681     hr = IAudioClock_GetPosition(acl, &pos, NULL);
682     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
683     ok(pos >= last, "Position should have been further along...\n");
684     last = pos;
685
686     hr = IAudioClock_GetPosition(acl, &pos, NULL);
687     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
688     ok(pos == last, "Position should have been further along...\n");
689
690     hr = IAudioClient_Reset(ac);
691     ok(hr == S_OK, "Reset failed: %08x\n", hr);
692
693     hr = IAudioClock_GetPosition(acl, &pos, NULL);
694     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
695     ok(pos == 0, "GetPosition returned non-zero pos after Reset\n");
696
697     hr = IAudioRenderClient_GetBuffer(arc, pwfx->nSamplesPerSec / 2., &data);
698     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
699
700     hr = IAudioRenderClient_ReleaseBuffer(arc, pwfx->nSamplesPerSec / 2., AUDCLNT_BUFFERFLAGS_SILENT);
701     ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
702
703     hr = IAudioClock_GetPosition(acl, &pos, NULL);
704     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
705     ok(pos == 0, "GetPosition returned non-zero pos after Reset\n");
706     last = pos;
707
708     hr = IAudioClient_Start(ac);
709     ok(hr == S_OK, "Start failed: %08x\n", hr);
710
711     Sleep(100);
712
713     hr = IAudioClock_GetPosition(acl, &pos, NULL);
714     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
715     ok(pos > last, "Position should have been further along...\n");
716
717     hr = IAudioClient_Stop(ac);
718     ok(hr == S_OK, "Stop failed: %08x\n", hr);
719
720     hr = IAudioClock_GetPosition(acl, &pos, NULL);
721     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
722     ok(pos >= last, "Position should have been further along...\n");
723
724     CoTaskMemFree(pwfx);
725
726     IAudioClock_Release(acl);
727     IAudioRenderClient_Release(arc);
728     IAudioClient_Release(ac);
729 }
730
731 static void test_session(void)
732 {
733     IAudioClient *ses1_ac1, *ses1_ac2, *cap_ac;
734     IAudioSessionControl2 *ses1_ctl, *ses1_ctl2, *cap_ctl = NULL;
735     IMMDevice *cap_dev;
736     GUID ses1_guid;
737     AudioSessionState state;
738     WAVEFORMATEX *pwfx;
739     ULONG ref;
740     HRESULT hr;
741
742     hr = CoCreateGuid(&ses1_guid);
743     ok(hr == S_OK, "CoCreateGuid failed: %08x\n", hr);
744
745     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
746             NULL, (void**)&ses1_ac1);
747     ok(hr == S_OK, "Activation failed with %08x\n", hr);
748     if (FAILED(hr)) return;
749
750     hr = IAudioClient_GetMixFormat(ses1_ac1, &pwfx);
751     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
752
753     hr = IAudioClient_Initialize(ses1_ac1, AUDCLNT_SHAREMODE_SHARED,
754             0, 5000000, 0, pwfx, &ses1_guid);
755     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
756
757     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
758             NULL, (void**)&ses1_ac2);
759     ok(hr == S_OK, "Activation failed with %08x\n", hr);
760     if(FAILED(hr)){
761         skip("Unable to open the same device twice. Skipping session tests\n");
762
763         ref = IAudioClient_Release(ses1_ac1);
764         ok(ref == 0, "AudioClient wasn't released: %u\n", ref);
765         return;
766     }
767
768     hr = IAudioClient_Initialize(ses1_ac2, AUDCLNT_SHAREMODE_SHARED,
769             0, 5000000, 0, pwfx, &ses1_guid);
770     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
771
772     hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme, eCapture,
773             eMultimedia, &cap_dev);
774     if(hr == S_OK){
775         hr = IMMDevice_Activate(cap_dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
776                 NULL, (void**)&cap_ac);
777         ok((hr == S_OK)^(cap_ac == NULL), "Activate %08x &out pointer\n", hr);
778         ok(hr == S_OK, "Activate failed: %08x\n", hr);
779         IMMDevice_Release(cap_dev);
780     }
781     if(hr == S_OK){
782         WAVEFORMATEX *cap_pwfx;
783
784         hr = IAudioClient_GetMixFormat(cap_ac, &cap_pwfx);
785         ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
786
787         hr = IAudioClient_Initialize(cap_ac, AUDCLNT_SHAREMODE_SHARED,
788                 0, 5000000, 0, cap_pwfx, &ses1_guid);
789         ok(hr == S_OK, "Initialize failed for capture in rendering session: %08x\n", hr);
790         CoTaskMemFree(cap_pwfx);
791     }
792     if(hr == S_OK){
793         hr = IAudioClient_GetService(cap_ac, &IID_IAudioSessionControl, (void**)&cap_ctl);
794         ok(hr == S_OK, "GetService failed: %08x\n", hr);
795         if(FAILED(hr))
796             cap_ctl = NULL;
797     }else
798         skip("No capture session: %08x; skipping capture device in render session tests\n", hr);
799
800     hr = IAudioClient_GetService(ses1_ac1, &IID_IAudioSessionControl2, (void**)&ses1_ctl);
801     ok(hr == E_NOINTERFACE, "GetService gave wrong error: %08x\n", hr);
802
803     hr = IAudioClient_GetService(ses1_ac1, &IID_IAudioSessionControl, (void**)&ses1_ctl);
804     ok(hr == S_OK, "GetService failed: %08x\n", hr);
805
806     hr = IAudioClient_GetService(ses1_ac1, &IID_IAudioSessionControl, (void**)&ses1_ctl2);
807     ok(hr == S_OK, "GetService failed: %08x\n", hr);
808     ok(ses1_ctl == ses1_ctl2, "Got different controls: %p %p\n", ses1_ctl, ses1_ctl2);
809     ref = IAudioSessionControl_Release(ses1_ctl2);
810     ok(ref != 0, "AudioSessionControl was destroyed\n");
811
812     hr = IAudioClient_GetService(ses1_ac2, &IID_IAudioSessionControl, (void**)&ses1_ctl2);
813     ok(hr == S_OK, "GetService failed: %08x\n", hr);
814
815     hr = IAudioSessionControl_GetState(ses1_ctl, NULL);
816     ok(hr == NULL_PTR_ERR, "GetState gave wrong error: %08x\n", hr);
817
818     hr = IAudioSessionControl_GetState(ses1_ctl, &state);
819     ok(hr == S_OK, "GetState failed: %08x\n", hr);
820     ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
821
822     hr = IAudioSessionControl_GetState(ses1_ctl2, &state);
823     ok(hr == S_OK, "GetState failed: %08x\n", hr);
824     ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
825
826     if(cap_ctl){
827         hr = IAudioSessionControl_GetState(cap_ctl, &state);
828         ok(hr == S_OK, "GetState failed: %08x\n", hr);
829         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
830     }
831
832     hr = IAudioClient_Start(ses1_ac1);
833     ok(hr == S_OK, "Start failed: %08x\n", hr);
834
835     hr = IAudioSessionControl_GetState(ses1_ctl, &state);
836     ok(hr == S_OK, "GetState failed: %08x\n", hr);
837     ok(state == AudioSessionStateActive, "Got wrong state: %d\n", state);
838
839     hr = IAudioSessionControl_GetState(ses1_ctl2, &state);
840     ok(hr == S_OK, "GetState failed: %08x\n", hr);
841     ok(state == AudioSessionStateActive, "Got wrong state: %d\n", state);
842
843     if(cap_ctl){
844         hr = IAudioSessionControl_GetState(cap_ctl, &state);
845         ok(hr == S_OK, "GetState failed: %08x\n", hr);
846         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
847     }
848
849     hr = IAudioClient_Stop(ses1_ac1);
850     ok(hr == S_OK, "Start failed: %08x\n", hr);
851
852     hr = IAudioSessionControl_GetState(ses1_ctl, &state);
853     ok(hr == S_OK, "GetState failed: %08x\n", hr);
854     ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
855
856     hr = IAudioSessionControl_GetState(ses1_ctl2, &state);
857     ok(hr == S_OK, "GetState failed: %08x\n", hr);
858     ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
859
860     if(cap_ctl){
861         hr = IAudioSessionControl_GetState(cap_ctl, &state);
862         ok(hr == S_OK, "GetState failed: %08x\n", hr);
863         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
864
865         hr = IAudioClient_Start(cap_ac);
866         ok(hr == S_OK, "Start failed: %08x\n", hr);
867
868         hr = IAudioSessionControl_GetState(ses1_ctl, &state);
869         ok(hr == S_OK, "GetState failed: %08x\n", hr);
870         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
871
872         hr = IAudioSessionControl_GetState(ses1_ctl2, &state);
873         ok(hr == S_OK, "GetState failed: %08x\n", hr);
874         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
875
876         hr = IAudioSessionControl_GetState(cap_ctl, &state);
877         ok(hr == S_OK, "GetState failed: %08x\n", hr);
878         ok(state == AudioSessionStateActive, "Got wrong state: %d\n", state);
879
880         hr = IAudioClient_Stop(cap_ac);
881         ok(hr == S_OK, "Stop failed: %08x\n", hr);
882
883         hr = IAudioSessionControl_GetState(ses1_ctl, &state);
884         ok(hr == S_OK, "GetState failed: %08x\n", hr);
885         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
886
887         hr = IAudioSessionControl_GetState(ses1_ctl2, &state);
888         ok(hr == S_OK, "GetState failed: %08x\n", hr);
889         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
890
891         hr = IAudioSessionControl_GetState(cap_ctl, &state);
892         ok(hr == S_OK, "GetState failed: %08x\n", hr);
893         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
894
895         ref = IAudioSessionControl_Release(cap_ctl);
896         ok(ref == 0, "AudioSessionControl wasn't released: %u\n", ref);
897
898         ref = IAudioClient_Release(cap_ac);
899         ok(ref == 0, "AudioClient wasn't released: %u\n", ref);
900     }
901
902     ref = IAudioSessionControl_Release(ses1_ctl);
903     ok(ref == 0, "AudioSessionControl wasn't released: %u\n", ref);
904
905     ref = IAudioClient_Release(ses1_ac1);
906     ok(ref == 0, "AudioClient wasn't released: %u\n", ref);
907
908     ref = IAudioClient_Release(ses1_ac2);
909     ok(ref == 1, "AudioClient had wrong refcount: %u\n", ref);
910
911     /* we've released all of our IAudioClient references, so check GetState */
912     hr = IAudioSessionControl_GetState(ses1_ctl2, &state);
913     ok(hr == S_OK, "GetState failed: %08x\n", hr);
914     ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
915
916     ref = IAudioSessionControl_Release(ses1_ctl2);
917     ok(ref == 0, "AudioSessionControl wasn't released: %u\n", ref);
918
919     CoTaskMemFree(pwfx);
920 }
921
922 static void test_streamvolume(void)
923 {
924     IAudioClient *ac;
925     IAudioStreamVolume *asv;
926     WAVEFORMATEX *fmt;
927     UINT32 chans, i;
928     HRESULT hr;
929     float vol, *vols;
930
931     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
932             NULL, (void**)&ac);
933     ok(hr == S_OK, "Activation failed with %08x\n", hr);
934     if(hr != S_OK)
935         return;
936
937     hr = IAudioClient_GetMixFormat(ac, &fmt);
938     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
939
940     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
941             0, fmt, NULL);
942     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
943
944     hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&asv);
945     ok(hr == S_OK, "GetService failed: %08x\n", hr);
946
947     hr = IAudioStreamVolume_GetChannelCount(asv, NULL);
948     ok(hr == E_POINTER, "GetChannelCount gave wrong error: %08x\n", hr);
949
950     hr = IAudioStreamVolume_GetChannelCount(asv, &chans);
951     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
952     ok(chans == fmt->nChannels, "GetChannelCount gave wrong number of channels: %d\n", chans);
953
954     hr = IAudioStreamVolume_GetChannelVolume(asv, fmt->nChannels, NULL);
955     ok(hr == E_POINTER, "GetChannelCount gave wrong error: %08x\n", hr);
956
957     hr = IAudioStreamVolume_GetChannelVolume(asv, fmt->nChannels, &vol);
958     ok(hr == E_INVALIDARG, "GetChannelCount gave wrong error: %08x\n", hr);
959
960     hr = IAudioStreamVolume_GetChannelVolume(asv, 0, NULL);
961     ok(hr == E_POINTER, "GetChannelCount gave wrong error: %08x\n", hr);
962
963     hr = IAudioStreamVolume_GetChannelVolume(asv, 0, &vol);
964     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
965     ok(vol == 1.f, "Channel volume was not 1: %f\n", vol);
966
967     hr = IAudioStreamVolume_SetChannelVolume(asv, fmt->nChannels, -1.f);
968     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
969
970     hr = IAudioStreamVolume_SetChannelVolume(asv, 0, -1.f);
971     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
972
973     hr = IAudioStreamVolume_SetChannelVolume(asv, 0, 2.f);
974     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
975
976     hr = IAudioStreamVolume_SetChannelVolume(asv, 0, 0.2f);
977     ok(hr == S_OK, "SetChannelVolume failed: %08x\n", hr);
978
979     hr = IAudioStreamVolume_GetChannelVolume(asv, 0, &vol);
980     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
981     ok(fabsf(vol - 0.2f) < 0.05f, "Channel volume wasn't 0.2: %f\n", vol);
982
983     hr = IAudioStreamVolume_GetAllVolumes(asv, 0, NULL);
984     ok(hr == E_POINTER, "GetAllVolumes gave wrong error: %08x\n", hr);
985
986     hr = IAudioStreamVolume_GetAllVolumes(asv, fmt->nChannels, NULL);
987     ok(hr == E_POINTER, "GetAllVolumes gave wrong error: %08x\n", hr);
988
989     vols = HeapAlloc(GetProcessHeap(), 0, fmt->nChannels * sizeof(float));
990     ok(vols != NULL, "HeapAlloc failed\n");
991
992     hr = IAudioStreamVolume_GetAllVolumes(asv, fmt->nChannels - 1, vols);
993     ok(hr == E_INVALIDARG, "GetAllVolumes gave wrong error: %08x\n", hr);
994
995     hr = IAudioStreamVolume_GetAllVolumes(asv, fmt->nChannels, vols);
996     ok(hr == S_OK, "GetAllVolumes failed: %08x\n", hr);
997     ok(fabsf(vols[0] - 0.2f) < 0.05f, "Channel 0 volume wasn't 0.2: %f\n", vol);
998     for(i = 1; i < fmt->nChannels; ++i)
999         ok(vols[i] == 1.f, "Channel %d volume is not 1: %f\n", i, vols[i]);
1000
1001     hr = IAudioStreamVolume_SetAllVolumes(asv, 0, NULL);
1002     ok(hr == E_POINTER, "SetAllVolumes gave wrong error: %08x\n", hr);
1003
1004     hr = IAudioStreamVolume_SetAllVolumes(asv, fmt->nChannels, NULL);
1005     ok(hr == E_POINTER, "SetAllVolumes gave wrong error: %08x\n", hr);
1006
1007     hr = IAudioStreamVolume_SetAllVolumes(asv, fmt->nChannels - 1, vols);
1008     ok(hr == E_INVALIDARG, "SetAllVolumes gave wrong error: %08x\n", hr);
1009
1010     hr = IAudioStreamVolume_SetAllVolumes(asv, fmt->nChannels, vols);
1011     ok(hr == S_OK, "SetAllVolumes failed: %08x\n", hr);
1012
1013     HeapFree(GetProcessHeap(), 0, vols);
1014     IAudioStreamVolume_Release(asv);
1015     IAudioClient_Release(ac);
1016     CoTaskMemFree(fmt);
1017 }
1018
1019 static void test_channelvolume(void)
1020 {
1021     IAudioClient *ac;
1022     IChannelAudioVolume *acv;
1023     WAVEFORMATEX *fmt;
1024     UINT32 chans, i;
1025     HRESULT hr;
1026     float vol, *vols;
1027
1028     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1029             NULL, (void**)&ac);
1030     ok(hr == S_OK, "Activation failed with %08x\n", hr);
1031     if(hr != S_OK)
1032         return;
1033
1034     hr = IAudioClient_GetMixFormat(ac, &fmt);
1035     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1036
1037     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
1038             AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, NULL);
1039     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1040
1041     hr = IAudioClient_GetService(ac, &IID_IChannelAudioVolume, (void**)&acv);
1042     ok(hr == S_OK, "GetService failed: %08x\n", hr);
1043
1044     hr = IChannelAudioVolume_GetChannelCount(acv, NULL);
1045     ok(hr == NULL_PTR_ERR, "GetChannelCount gave wrong error: %08x\n", hr);
1046
1047     hr = IChannelAudioVolume_GetChannelCount(acv, &chans);
1048     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1049     ok(chans == fmt->nChannels, "GetChannelCount gave wrong number of channels: %d\n", chans);
1050
1051     hr = IChannelAudioVolume_GetChannelVolume(acv, fmt->nChannels, NULL);
1052     ok(hr == NULL_PTR_ERR, "GetChannelCount gave wrong error: %08x\n", hr);
1053
1054     hr = IChannelAudioVolume_GetChannelVolume(acv, fmt->nChannels, &vol);
1055     ok(hr == E_INVALIDARG, "GetChannelCount gave wrong error: %08x\n", hr);
1056
1057     hr = IChannelAudioVolume_GetChannelVolume(acv, 0, NULL);
1058     ok(hr == NULL_PTR_ERR, "GetChannelCount gave wrong error: %08x\n", hr);
1059
1060     hr = IChannelAudioVolume_GetChannelVolume(acv, 0, &vol);
1061     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1062     ok(vol == 1.f, "Channel volume was not 1: %f\n", vol);
1063
1064     hr = IChannelAudioVolume_SetChannelVolume(acv, fmt->nChannels, -1.f, NULL);
1065     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
1066
1067     hr = IChannelAudioVolume_SetChannelVolume(acv, 0, -1.f, NULL);
1068     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
1069
1070     hr = IChannelAudioVolume_SetChannelVolume(acv, 0, 2.f, NULL);
1071     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
1072
1073     hr = IChannelAudioVolume_SetChannelVolume(acv, 0, 0.2f, NULL);
1074     ok(hr == S_OK, "SetChannelVolume failed: %08x\n", hr);
1075
1076     hr = IChannelAudioVolume_GetChannelVolume(acv, 0, &vol);
1077     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1078     ok(fabsf(vol - 0.2f) < 0.05f, "Channel volume wasn't 0.2: %f\n", vol);
1079
1080     hr = IChannelAudioVolume_GetAllVolumes(acv, 0, NULL);
1081     ok(hr == NULL_PTR_ERR, "GetAllVolumes gave wrong error: %08x\n", hr);
1082
1083     hr = IChannelAudioVolume_GetAllVolumes(acv, fmt->nChannels, NULL);
1084     ok(hr == NULL_PTR_ERR, "GetAllVolumes gave wrong error: %08x\n", hr);
1085
1086     vols = HeapAlloc(GetProcessHeap(), 0, fmt->nChannels * sizeof(float));
1087     ok(vols != NULL, "HeapAlloc failed\n");
1088
1089     hr = IChannelAudioVolume_GetAllVolumes(acv, fmt->nChannels - 1, vols);
1090     ok(hr == E_INVALIDARG, "GetAllVolumes gave wrong error: %08x\n", hr);
1091
1092     hr = IChannelAudioVolume_GetAllVolumes(acv, fmt->nChannels, vols);
1093     ok(hr == S_OK, "GetAllVolumes failed: %08x\n", hr);
1094     ok(fabsf(vols[0] - 0.2f) < 0.05f, "Channel 0 volume wasn't 0.2: %f\n", vol);
1095     for(i = 1; i < fmt->nChannels; ++i)
1096         ok(vols[i] == 1.f, "Channel %d volume is not 1: %f\n", i, vols[i]);
1097
1098     hr = IChannelAudioVolume_SetAllVolumes(acv, 0, NULL, NULL);
1099     ok(hr == NULL_PTR_ERR, "SetAllVolumes gave wrong error: %08x\n", hr);
1100
1101     hr = IChannelAudioVolume_SetAllVolumes(acv, fmt->nChannels, NULL, NULL);
1102     ok(hr == NULL_PTR_ERR, "SetAllVolumes gave wrong error: %08x\n", hr);
1103
1104     hr = IChannelAudioVolume_SetAllVolumes(acv, fmt->nChannels - 1, vols, NULL);
1105     ok(hr == E_INVALIDARG, "SetAllVolumes gave wrong error: %08x\n", hr);
1106
1107     hr = IChannelAudioVolume_SetAllVolumes(acv, fmt->nChannels, vols, NULL);
1108     ok(hr == S_OK, "SetAllVolumes failed: %08x\n", hr);
1109
1110     hr = IChannelAudioVolume_SetChannelVolume(acv, 0, 1.0f, NULL);
1111     ok(hr == S_OK, "SetChannelVolume failed: %08x\n", hr);
1112
1113     HeapFree(GetProcessHeap(), 0, vols);
1114     IChannelAudioVolume_Release(acv);
1115     IAudioClient_Release(ac);
1116     CoTaskMemFree(fmt);
1117 }
1118
1119 static void test_simplevolume(void)
1120 {
1121     IAudioClient *ac;
1122     ISimpleAudioVolume *sav;
1123     WAVEFORMATEX *fmt;
1124     HRESULT hr;
1125     float vol;
1126     BOOL mute;
1127
1128     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1129             NULL, (void**)&ac);
1130     ok(hr == S_OK, "Activation failed with %08x\n", hr);
1131     if(hr != S_OK)
1132         return;
1133
1134     hr = IAudioClient_GetMixFormat(ac, &fmt);
1135     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1136
1137     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
1138             AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, NULL);
1139     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1140
1141     hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
1142     ok(hr == S_OK, "GetService failed: %08x\n", hr);
1143
1144     hr = ISimpleAudioVolume_GetMasterVolume(sav, NULL);
1145     ok(hr == NULL_PTR_ERR, "GetMasterVolume gave wrong error: %08x\n", hr);
1146
1147     hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
1148     ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1149     ok(vol == 1.f, "Master volume wasn't 1: %f\n", vol);
1150
1151     hr = ISimpleAudioVolume_SetMasterVolume(sav, -1.f, NULL);
1152     ok(hr == E_INVALIDARG, "SetMasterVolume gave wrong error: %08x\n", hr);
1153
1154     hr = ISimpleAudioVolume_SetMasterVolume(sav, 2.f, NULL);
1155     ok(hr == E_INVALIDARG, "SetMasterVolume gave wrong error: %08x\n", hr);
1156
1157     hr = ISimpleAudioVolume_SetMasterVolume(sav, 0.2f, NULL);
1158     ok(hr == S_OK, "SetMasterVolume failed: %08x\n", hr);
1159
1160     hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
1161     ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1162     ok(fabsf(vol - 0.2f) < 0.05f, "Master volume wasn't 0.2: %f\n", vol);
1163
1164     hr = ISimpleAudioVolume_GetMute(sav, NULL);
1165     ok(hr == NULL_PTR_ERR, "GetMute gave wrong error: %08x\n", hr);
1166
1167     mute = TRUE;
1168     hr = ISimpleAudioVolume_GetMute(sav, &mute);
1169     ok(hr == S_OK, "GetMute failed: %08x\n", hr);
1170     ok(mute == FALSE, "Session is already muted\n");
1171
1172     hr = ISimpleAudioVolume_SetMute(sav, TRUE, NULL);
1173     ok(hr == S_OK, "SetMute failed: %08x\n", hr);
1174
1175     mute = FALSE;
1176     hr = ISimpleAudioVolume_GetMute(sav, &mute);
1177     ok(hr == S_OK, "GetMute failed: %08x\n", hr);
1178     ok(mute == TRUE, "Session should have been muted\n");
1179
1180     hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
1181     ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1182     ok(fabsf(vol - 0.2f) < 0.05f, "Master volume wasn't 0.2: %f\n", vol);
1183
1184     hr = ISimpleAudioVolume_SetMasterVolume(sav, 1.f, NULL);
1185     ok(hr == S_OK, "SetMasterVolume failed: %08x\n", hr);
1186
1187     mute = FALSE;
1188     hr = ISimpleAudioVolume_GetMute(sav, &mute);
1189     ok(hr == S_OK, "GetMute failed: %08x\n", hr);
1190     ok(mute == TRUE, "Session should have been muted\n");
1191
1192     hr = ISimpleAudioVolume_SetMute(sav, FALSE, NULL);
1193     ok(hr == S_OK, "SetMute failed: %08x\n", hr);
1194
1195     ISimpleAudioVolume_Release(sav);
1196     IAudioClient_Release(ac);
1197     CoTaskMemFree(fmt);
1198 }
1199
1200 static void test_volume_dependence(void)
1201 {
1202     IAudioClient *ac, *ac2;
1203     ISimpleAudioVolume *sav;
1204     IChannelAudioVolume *cav;
1205     IAudioStreamVolume *asv;
1206     WAVEFORMATEX *fmt;
1207     HRESULT hr;
1208     float vol;
1209     GUID session;
1210     UINT32 nch;
1211
1212     hr = CoCreateGuid(&session);
1213     ok(hr == S_OK, "CoCreateGuid failed: %08x\n", hr);
1214
1215     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1216             NULL, (void**)&ac);
1217     ok(hr == S_OK, "Activation failed with %08x\n", hr);
1218     if(hr != S_OK)
1219         return;
1220
1221     hr = IAudioClient_GetMixFormat(ac, &fmt);
1222     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1223
1224     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
1225             AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, &session);
1226     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1227
1228     hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
1229     ok(hr == S_OK, "GetService (SimpleAudioVolume) failed: %08x\n", hr);
1230
1231     hr = IAudioClient_GetService(ac, &IID_IChannelAudioVolume, (void**)&cav);
1232     ok(hr == S_OK, "GetService (ChannelAudioVolme) failed: %08x\n", hr);
1233
1234     hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&asv);
1235     ok(hr == S_OK, "GetService (AudioStreamVolume) failed: %08x\n", hr);
1236
1237     hr = IAudioStreamVolume_SetChannelVolume(asv, 0, 0.2f);
1238     ok(hr == S_OK, "ASV_SetChannelVolume failed: %08x\n", hr);
1239
1240     hr = IChannelAudioVolume_SetChannelVolume(cav, 0, 0.4f, NULL);
1241     ok(hr == S_OK, "CAV_SetChannelVolume failed: %08x\n", hr);
1242
1243     hr = ISimpleAudioVolume_SetMasterVolume(sav, 0.6f, NULL);
1244     ok(hr == S_OK, "SAV_SetMasterVolume failed: %08x\n", hr);
1245
1246     hr = IAudioStreamVolume_GetChannelVolume(asv, 0, &vol);
1247     ok(hr == S_OK, "ASV_GetChannelVolume failed: %08x\n", hr);
1248     ok(fabsf(vol - 0.2) < 0.05f, "ASV_GetChannelVolume gave wrong volume: %f\n", vol);
1249
1250     hr = IChannelAudioVolume_GetChannelVolume(cav, 0, &vol);
1251     ok(hr == S_OK, "CAV_GetChannelVolume failed: %08x\n", hr);
1252     ok(fabsf(vol - 0.4) < 0.05f, "CAV_GetChannelVolume gave wrong volume: %f\n", vol);
1253
1254     hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
1255     ok(hr == S_OK, "SAV_GetMasterVolume failed: %08x\n", hr);
1256     ok(fabsf(vol - 0.6) < 0.05f, "SAV_GetMasterVolume gave wrong volume: %f\n", vol);
1257
1258     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1259             NULL, (void**)&ac2);
1260     if(SUCCEEDED(hr)){
1261         IChannelAudioVolume *cav2;
1262         IAudioStreamVolume *asv2;
1263
1264         hr = IAudioClient_Initialize(ac2, AUDCLNT_SHAREMODE_SHARED,
1265                 AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, &session);
1266         ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1267
1268         hr = IAudioClient_GetService(ac2, &IID_IChannelAudioVolume, (void**)&cav2);
1269         ok(hr == S_OK, "GetService failed: %08x\n", hr);
1270
1271         hr = IAudioClient_GetService(ac2, &IID_IAudioStreamVolume, (void**)&asv2);
1272         ok(hr == S_OK, "GetService failed: %08x\n", hr);
1273
1274         hr = IChannelAudioVolume_GetChannelVolume(cav2, 0, &vol);
1275         ok(hr == S_OK, "CAV_GetChannelVolume failed: %08x\n", hr);
1276         ok(fabsf(vol - 0.4) < 0.05f, "CAV_GetChannelVolume gave wrong volume: %f\n", vol);
1277
1278         hr = IAudioStreamVolume_GetChannelVolume(asv2, 0, &vol);
1279         ok(hr == S_OK, "ASV_GetChannelVolume failed: %08x\n", hr);
1280         ok(vol == 1.f, "ASV_GetChannelVolume gave wrong volume: %f\n", vol);
1281
1282         hr = IChannelAudioVolume_GetChannelCount(cav2, &nch);
1283         ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1284         ok(nch == fmt->nChannels, "Got wrong channel count, expected %u: %u\n", fmt->nChannels, nch);
1285
1286         hr = IAudioStreamVolume_GetChannelCount(asv2, &nch);
1287         ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1288         ok(nch == fmt->nChannels, "Got wrong channel count, expected %u: %u\n", fmt->nChannels, nch);
1289
1290         IAudioStreamVolume_Release(asv2);
1291         IChannelAudioVolume_Release(cav2);
1292         IAudioClient_Release(ac2);
1293     }else
1294         skip("Unable to open the same device twice. Skipping session volume control tests\n");
1295
1296     hr = IChannelAudioVolume_SetChannelVolume(cav, 0, 1.f, NULL);
1297     ok(hr == S_OK, "CAV_SetChannelVolume failed: %08x\n", hr);
1298
1299     hr = ISimpleAudioVolume_SetMasterVolume(sav, 1.f, NULL);
1300     ok(hr == S_OK, "SAV_SetMasterVolume failed: %08x\n", hr);
1301
1302     CoTaskMemFree(fmt);
1303     ISimpleAudioVolume_Release(sav);
1304     IChannelAudioVolume_Release(cav);
1305     IAudioStreamVolume_Release(asv);
1306     IAudioClient_Release(ac);
1307 }
1308
1309 static void test_session_creation(void)
1310 {
1311     IMMDevice *cap_dev;
1312     IAudioClient *ac;
1313     IAudioSessionManager *sesm;
1314     ISimpleAudioVolume *sav;
1315     GUID session_guid;
1316     float vol;
1317     HRESULT hr;
1318     WAVEFORMATEX *fmt;
1319
1320     CoCreateGuid(&session_guid);
1321
1322     hr = IMMDevice_Activate(dev, &IID_IAudioSessionManager,
1323             CLSCTX_INPROC_SERVER, NULL, (void**)&sesm);
1324     ok((hr == S_OK)^(sesm == NULL), "Activate %08x &out pointer\n", hr);
1325     ok(hr == S_OK, "Activate failed: %08x\n", hr);
1326
1327     hr = IAudioSessionManager_GetSimpleAudioVolume(sesm, &session_guid,
1328             FALSE, &sav);
1329     ok(hr == S_OK, "GetSimpleAudioVolume failed: %08x\n", hr);
1330
1331     hr = ISimpleAudioVolume_SetMasterVolume(sav, 0.6f, NULL);
1332     ok(hr == S_OK, "SetMasterVolume failed: %08x\n", hr);
1333
1334     /* Release completely to show session persistence */
1335     ISimpleAudioVolume_Release(sav);
1336     IAudioSessionManager_Release(sesm);
1337
1338     /* test if we can create a capture audioclient in the session we just
1339      * created from a SessionManager derived from a render device */
1340     hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme, eCapture,
1341             eMultimedia, &cap_dev);
1342     if(hr == S_OK){
1343         WAVEFORMATEX *cap_pwfx;
1344         IAudioClient *cap_ac;
1345         ISimpleAudioVolume *cap_sav;
1346         IAudioSessionManager *cap_sesm;
1347
1348         hr = IMMDevice_Activate(cap_dev, &IID_IAudioSessionManager,
1349                 CLSCTX_INPROC_SERVER, NULL, (void**)&cap_sesm);
1350         ok((hr == S_OK)^(cap_sesm == NULL), "Activate %08x &out pointer\n", hr);
1351         ok(hr == S_OK, "Activate failed: %08x\n", hr);
1352
1353         hr = IAudioSessionManager_GetSimpleAudioVolume(cap_sesm, &session_guid,
1354                 FALSE, &cap_sav);
1355         ok(hr == S_OK, "GetSimpleAudioVolume failed: %08x\n", hr);
1356
1357         vol = 0.5f;
1358         hr = ISimpleAudioVolume_GetMasterVolume(cap_sav, &vol);
1359         ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1360         ok(vol == 1.f, "Got wrong volume: %f\n", vol);
1361
1362         ISimpleAudioVolume_Release(cap_sav);
1363         IAudioSessionManager_Release(cap_sesm);
1364
1365         hr = IMMDevice_Activate(cap_dev, &IID_IAudioClient,
1366                 CLSCTX_INPROC_SERVER, NULL, (void**)&cap_ac);
1367         ok(hr == S_OK, "Activate failed: %08x\n", hr);
1368
1369         IMMDevice_Release(cap_dev);
1370
1371         hr = IAudioClient_GetMixFormat(cap_ac, &cap_pwfx);
1372         ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1373
1374         hr = IAudioClient_Initialize(cap_ac, AUDCLNT_SHAREMODE_SHARED,
1375                 0, 5000000, 0, cap_pwfx, &session_guid);
1376         ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1377
1378         CoTaskMemFree(cap_pwfx);
1379
1380         if(hr == S_OK){
1381             hr = IAudioClient_GetService(cap_ac, &IID_ISimpleAudioVolume,
1382                     (void**)&cap_sav);
1383             ok(hr == S_OK, "GetService failed: %08x\n", hr);
1384         }
1385         if(hr == S_OK){
1386             vol = 0.5f;
1387             hr = ISimpleAudioVolume_GetMasterVolume(cap_sav, &vol);
1388             ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1389             ok(vol == 1.f, "Got wrong volume: %f\n", vol);
1390
1391             ISimpleAudioVolume_Release(cap_sav);
1392         }
1393
1394         IAudioClient_Release(cap_ac);
1395     }
1396
1397     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1398             NULL, (void**)&ac);
1399     ok((hr == S_OK)^(ac == NULL), "Activate %08x &out pointer\n", hr);
1400     ok(hr == S_OK, "Activation failed with %08x\n", hr);
1401     if(hr != S_OK)
1402         return;
1403
1404     hr = IAudioClient_GetMixFormat(ac, &fmt);
1405     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1406
1407     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
1408             AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, &session_guid);
1409     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1410
1411     hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
1412     ok(hr == S_OK, "GetService failed: %08x\n", hr);
1413     if(hr == S_OK){
1414         vol = 0.5f;
1415         hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
1416         ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1417         ok(fabs(vol - 0.6f) < 0.05f, "Got wrong volume: %f\n", vol);
1418
1419         ISimpleAudioVolume_Release(sav);
1420     }
1421
1422     CoTaskMemFree(fmt);
1423     IAudioClient_Release(ac);
1424 }
1425
1426 START_TEST(render)
1427 {
1428     HRESULT hr;
1429
1430     CoInitializeEx(NULL, COINIT_MULTITHREADED);
1431     hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme);
1432     if (FAILED(hr))
1433     {
1434         skip("mmdevapi not available: 0x%08x\n", hr);
1435         goto cleanup;
1436     }
1437
1438     hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme, eRender, eMultimedia, &dev);
1439     ok(hr == S_OK || hr == E_NOTFOUND, "GetDefaultAudioEndpoint failed: 0x%08x\n", hr);
1440     if (hr != S_OK || !dev)
1441     {
1442         if (hr == E_NOTFOUND)
1443             skip("No sound card available\n");
1444         else
1445             skip("GetDefaultAudioEndpoint returns 0x%08x\n", hr);
1446         goto cleanup;
1447     }
1448
1449     test_audioclient();
1450     test_references();
1451     test_event();
1452     test_padding();
1453     test_clock();
1454     test_session();
1455     test_streamvolume();
1456     test_channelvolume();
1457     test_simplevolume();
1458     test_volume_dependence();
1459     test_session_creation();
1460
1461     IMMDevice_Release(dev);
1462
1463 cleanup:
1464     if (mme)
1465         IMMDeviceEnumerator_Release(mme);
1466     CoUninitialize();
1467 }