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