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