1 /*
2  * Copyright 2010 Maarten Lankhorst for CodeWeavers
3  *      2011-2012 Jörg Höhle
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 /* This test is for audio playback specific mechanisms
21  * Tests:
22  * - IAudioClient with eRender and IAudioRenderClient
23  */
24 
25 #include <math.h>
26 #include <stdio.h>
27 
28 #include "wine/test.h"
29 
30 #define COBJMACROS
31 
32 #ifdef STANDALONE
33 #include "initguid.h"
34 #endif
35 
36 #include "unknwn.h"
37 #include "uuids.h"
38 #include "mmdeviceapi.h"
39 #include "mmsystem.h"
40 #include "audioclient.h"
41 #include "audiopolicy.h"
42 #ifdef __REACTOS__
43 #include <initguid.h>
44 #endif
45 #include "endpointvolume.h"
46 
47 static const unsigned int win_formats[][4] = {
48     { 8000,  8, 1},   { 8000,  8, 2},   { 8000, 16, 1},   { 8000, 16, 2},
49     {11025,  8, 1},   {11025,  8, 2},   {11025, 16, 1},   {11025, 16, 2},
50     {12000,  8, 1},   {12000,  8, 2},   {12000, 16, 1},   {12000, 16, 2},
51     {16000,  8, 1},   {16000,  8, 2},   {16000, 16, 1},   {16000, 16, 2},
52     {22050,  8, 1},   {22050,  8, 2},   {22050, 16, 1},   {22050, 16, 2},
53     {44100,  8, 1},   {44100,  8, 2},   {44100, 16, 1},   {44100, 16, 2},
54     {48000,  8, 1},   {48000,  8, 2},   {48000, 16, 1},   {48000, 16, 2},
55     {96000,  8, 1},   {96000,  8, 2},   {96000, 16, 1},   {96000, 16, 2}
56 };
57 
58 #define NULL_PTR_ERR MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, RPC_X_NULL_REF_POINTER)
59 
60 /* undocumented error code */
61 #define D3D11_ERROR_4E MAKE_HRESULT(SEVERITY_ERROR, FACILITY_DIRECT3D11, 0x4e)
62 
63 static IMMDeviceEnumerator *mme = NULL;
64 static IMMDevice *dev = NULL;
65 static HRESULT hexcl = S_OK; /* or AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED */
66 static BOOL win10 = FALSE;
67 
68 static const LARGE_INTEGER ullZero;
69 
70 #define PI 3.14159265358979323846L
71 static DWORD wave_generate_tone(PWAVEFORMATEX pwfx, BYTE* data, UINT32 frames)
72 {
73     static double phase = 0.; /* normalized to unit, not 2*PI */
74     PWAVEFORMATEXTENSIBLE wfxe = (PWAVEFORMATEXTENSIBLE)pwfx;
75     DWORD cn, i;
76     double delta, y;
77 
78     if(!winetest_interactive)
79         return AUDCLNT_BUFFERFLAGS_SILENT;
80     if(wfxe->Format.wBitsPerSample != ((wfxe->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
81        IsEqualGUID(&wfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) ? 8 * sizeof(float) : 16))
82         return AUDCLNT_BUFFERFLAGS_SILENT;
83 
84     for(delta = phase, cn = 0; cn < wfxe->Format.nChannels;
85         delta += .5/wfxe->Format.nChannels, cn++){
86         for(i = 0; i < frames; i++){
87             y = sin(2*PI*(440.* i / wfxe->Format.nSamplesPerSec + delta));
88             /* assume alignment is granted */
89             if(wfxe->Format.wBitsPerSample == 16)
90                 ((short*)data)[cn+i*wfxe->Format.nChannels] = y * 32767.9;
91             else
92                 ((float*)data)[cn+i*wfxe->Format.nChannels] = y;
93         }
94     }
95     phase += 440.* frames / wfxe->Format.nSamplesPerSec;
96     phase -= floor(phase);
97     return 0;
98 }
99 
100 static void test_uninitialized(IAudioClient *ac)
101 {
102     HRESULT hr;
103     UINT32 num;
104     REFERENCE_TIME t1;
105 
106     HANDLE handle = CreateEventW(NULL, FALSE, FALSE, NULL);
107     IUnknown *unk;
108 
109     hr = IAudioClient_GetBufferSize(ac, &num);
110     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetBufferSize call returns %08x\n", hr);
111 
112     hr = IAudioClient_GetStreamLatency(ac, &t1);
113     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetStreamLatency call returns %08x\n", hr);
114 
115     hr = IAudioClient_GetCurrentPadding(ac, &num);
116     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetCurrentPadding call returns %08x\n", hr);
117 
118     hr = IAudioClient_Start(ac);
119     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized Start call returns %08x\n", hr);
120 
121     hr = IAudioClient_Stop(ac);
122     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized Stop call returns %08x\n", hr);
123 
124     hr = IAudioClient_Reset(ac);
125     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized Reset call returns %08x\n", hr);
126 
127     hr = IAudioClient_SetEventHandle(ac, handle);
128     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized SetEventHandle call returns %08x\n", hr);
129 
130     hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&unk);
131     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetService call returns %08x\n", hr);
132 
133     CloseHandle(handle);
134 }
135 
136 static void test_audioclient(void)
137 {
138     IAudioClient *ac;
139     IUnknown *unk;
140     HRESULT hr;
141     ULONG ref;
142     WAVEFORMATEX *pwfx, *pwfx2;
143     REFERENCE_TIME t1, t2;
144     HANDLE handle;
145 
146     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
147             NULL, (void**)&ac);
148     ok(hr == S_OK, "Activation failed with %08x\n", hr);
149     if(hr != S_OK)
150         return;
151 
152     handle = CreateEventW(NULL, FALSE, FALSE, NULL);
153 
154     hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, NULL);
155     ok(hr == E_POINTER, "QueryInterface(NULL) returned %08x\n", hr);
156 
157     unk = (void*)(LONG_PTR)0x12345678;
158     hr = IAudioClient_QueryInterface(ac, &IID_NULL, (void**)&unk);
159     ok(hr == E_NOINTERFACE, "QueryInterface(IID_NULL) returned %08x\n", hr);
160     ok(!unk, "QueryInterface(IID_NULL) returned non-null pointer %p\n", unk);
161 
162     hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, (void**)&unk);
163     ok(hr == S_OK, "QueryInterface(IID_IUnknown) returned %08x\n", hr);
164     if (unk)
165     {
166         ref = IUnknown_Release(unk);
167         ok(ref == 1, "Released count is %u\n", ref);
168     }
169 
170     hr = IAudioClient_QueryInterface(ac, &IID_IAudioClient, (void**)&unk);
171     ok(hr == S_OK, "QueryInterface(IID_IAudioClient) returned %08x\n", hr);
172     if (unk)
173     {
174         ref = IUnknown_Release(unk);
175         ok(ref == 1, "Released count is %u\n", ref);
176     }
177 
178     hr = IAudioClient_GetDevicePeriod(ac, NULL, NULL);
179     ok(hr == E_POINTER, "Invalid GetDevicePeriod call returns %08x\n", hr);
180 
181     hr = IAudioClient_GetDevicePeriod(ac, &t1, NULL);
182     ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr);
183 
184     hr = IAudioClient_GetDevicePeriod(ac, NULL, &t2);
185     ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr);
186 
187     hr = IAudioClient_GetDevicePeriod(ac, &t1, &t2);
188     ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr);
189     trace("Returned periods: %u.%04u ms %u.%04u ms\n",
190           (UINT)(t1/10000), (UINT)(t1 % 10000),
191           (UINT)(t2/10000), (UINT)(t2 % 10000));
192 
193     hr = IAudioClient_GetMixFormat(ac, NULL);
194     ok(hr == E_POINTER, "GetMixFormat returns %08x\n", hr);
195 
196     hr = IAudioClient_GetMixFormat(ac, &pwfx);
197     ok(hr == S_OK, "Valid GetMixFormat returns %08x\n", hr);
198 
199     if (hr == S_OK)
200     {
201         trace("pwfx: %p\n", pwfx);
202         trace("Tag: %04x\n", pwfx->wFormatTag);
203         trace("bits: %u\n", pwfx->wBitsPerSample);
204         trace("chan: %u\n", pwfx->nChannels);
205         trace("rate: %u\n", pwfx->nSamplesPerSec);
206         trace("align: %u\n", pwfx->nBlockAlign);
207         trace("extra: %u\n", pwfx->cbSize);
208         ok(pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE, "wFormatTag is %x\n", pwfx->wFormatTag);
209         if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
210         {
211             WAVEFORMATEXTENSIBLE *pwfxe = (void*)pwfx;
212             trace("Res: %u\n", pwfxe->Samples.wReserved);
213             trace("Mask: %x\n", pwfxe->dwChannelMask);
214             trace("Alg: %s\n",
215                   IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)?"PCM":
216                   (IsEqualGUID(&pwfxe->SubFormat,
217                                &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)?"FLOAT":"Other"));
218         }
219 
220         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
221         ok(hr == S_OK, "Valid IsFormatSupported(Shared) call returns %08x\n", hr);
222         ok(pwfx2 == NULL, "pwfx2 is non-null\n");
223         CoTaskMemFree(pwfx2);
224 
225         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, NULL, NULL);
226         ok(hr == E_POINTER, "IsFormatSupported(NULL) call returns %08x\n", hr);
227 
228         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, NULL);
229         ok(hr == E_POINTER, "IsFormatSupported(Shared,NULL) call returns %08x\n", hr);
230 
231         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
232         ok(hr == S_OK || hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED,
233            "IsFormatSupported(Exclusive) call returns %08x\n", hr);
234         hexcl = hr;
235 
236         pwfx2 = (WAVEFORMATEX*)0xDEADF00D;
237         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, &pwfx2);
238         ok(hr == hexcl, "IsFormatSupported(Exclusive) call returns %08x\n", hr);
239         ok(pwfx2 == NULL, "pwfx2 non-null on exclusive IsFormatSupported\n");
240 
241         if (hexcl != AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED)
242             hexcl = S_OK;
243 
244         hr = IAudioClient_IsFormatSupported(ac, 0xffffffff, pwfx, NULL);
245         ok(hr == E_INVALIDARG/*w32*/ ||
246            broken(hr == AUDCLNT_E_UNSUPPORTED_FORMAT/*w64 response from exclusive mode driver */),
247            "IsFormatSupported(0xffffffff) call returns %08x\n", hr);
248     }
249 
250     test_uninitialized(ac);
251 
252     hr = IAudioClient_Initialize(ac, 3, 0, 5000000, 0, pwfx, NULL);
253     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Initialize with invalid sharemode returns %08x\n", hr);
254 
255     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0xffffffff, 5000000, 0, pwfx, NULL);
256     ok(hr == E_INVALIDARG ||
257             hr == AUDCLNT_E_INVALID_STREAM_FLAG, "Initialize with invalid flags returns %08x\n", hr);
258 
259     /* A period != 0 is ignored and the call succeeds.
260      * Since we can only initialize successfully once, skip those tests.
261      */
262     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, NULL, NULL);
263     ok(hr == E_POINTER, "Initialize with null format returns %08x\n", hr);
264 
265     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 0, 0, pwfx, NULL);
266     ok(hr == S_OK, "Initialize with 0 buffer size returns %08x\n", hr);
267     if(hr == S_OK){
268         UINT32 num;
269 
270         hr = IAudioClient_GetBufferSize(ac, &num);
271         ok(hr == S_OK, "GetBufferSize from duration 0 returns %08x\n", hr);
272         if(hr == S_OK)
273             trace("Initialize(duration=0) GetBufferSize is %u\n", num);
274     }
275 
276     IAudioClient_Release(ac);
277 
278     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
279             NULL, (void**)&ac);
280     ok(hr == S_OK, "Activation failed with %08x\n", hr);
281 
282     if(pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE){
283         WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE*)pwfx;
284         WAVEFORMATEX *fmt2 = NULL;
285 
286         ok(fmtex->dwChannelMask != 0, "Got empty dwChannelMask\n");
287 
288         fmtex->dwChannelMask = 0xffff;
289 
290         hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL);
291         ok(hr == S_OK ||
292                 hr == AUDCLNT_E_UNSUPPORTED_FORMAT /* win10 */, "Initialize(dwChannelMask = 0xffff) returns %08x\n", hr);
293 
294         IAudioClient_Release(ac);
295 
296         hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
297                 NULL, (void**)&ac);
298         ok(hr == S_OK, "Activation failed with %08x\n", hr);
299 
300         fmtex->dwChannelMask = 0;
301 
302         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &fmt2);
303         ok(hr == S_OK || broken(hr == S_FALSE /* w7 Realtek HDA */),
304            "IsFormatSupported(dwChannelMask = 0) call returns %08x\n", hr);
305         ok(fmtex->dwChannelMask == 0, "Passed format was modified\n");
306 
307         CoTaskMemFree(fmt2);
308 
309         hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL);
310         ok(hr == S_OK, "Initialize(dwChannelMask = 0) returns %08x\n", hr);
311 
312         IAudioClient_Release(ac);
313 
314         hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
315                 NULL, (void**)&ac);
316         ok(hr == S_OK, "Activation failed with %08x\n", hr);
317 
318         CoTaskMemFree(pwfx);
319 
320         hr = IAudioClient_GetMixFormat(ac, &pwfx);
321         ok(hr == S_OK, "Valid GetMixFormat returns %08x\n", hr);
322     }else
323         skip("Skipping dwChannelMask tests\n");
324 
325     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL);
326     ok(hr == S_OK, "Valid Initialize returns %08x\n", hr);
327     if (hr != S_OK)
328         goto cleanup;
329 
330     hr = IAudioClient_GetStreamLatency(ac, NULL);
331     ok(hr == E_POINTER, "GetStreamLatency(NULL) call returns %08x\n", hr);
332 
333     hr = IAudioClient_GetStreamLatency(ac, &t2);
334     ok(hr == S_OK, "Valid GetStreamLatency call returns %08x\n", hr);
335     trace("Returned latency: %u.%04u ms\n",
336           (UINT)(t2/10000), (UINT)(t2 % 10000));
337     ok(t2 >= t1 || broken(t2 >= t1/2 && pwfx->nSamplesPerSec > 48000) ||
338             broken(t2 == 0) /* (!) win10 */,
339        "Latency < default period, delta %dus (%s vs %s)\n",
340        (LONG)((t2-t1)/10), wine_dbgstr_longlong(t2), wine_dbgstr_longlong(t1));
341     /* Native appears to add the engine period to the HW latency in shared mode */
342     if(t2 == 0)
343         win10 = TRUE;
344 
345     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL);
346     ok(hr == AUDCLNT_E_ALREADY_INITIALIZED, "Calling Initialize twice returns %08x\n", hr);
347 
348     hr = IAudioClient_SetEventHandle(ac, NULL);
349     ok(hr == E_INVALIDARG, "SetEventHandle(NULL) returns %08x\n", hr);
350 
351     hr = IAudioClient_SetEventHandle(ac, handle);
352     ok(hr == AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED ||
353        broken(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME)) ||
354        broken(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) /* Some 2k8 */ ||
355        broken(hr == HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME)) /* Some Vista */
356        , "SetEventHandle returns %08x\n", hr);
357 
358     hr = IAudioClient_Reset(ac);
359     ok(hr == S_OK, "Reset on an initialized stream returns %08x\n", hr);
360 
361     hr = IAudioClient_Reset(ac);
362     ok(hr == S_OK, "Reset on an already reset stream returns %08x\n", hr);
363 
364     hr = IAudioClient_Stop(ac);
365     ok(hr == S_FALSE, "Stop on a stopped stream returns %08x\n", hr);
366 
367     hr = IAudioClient_Start(ac);
368     ok(hr == S_OK, "Start on a stopped stream returns %08x\n", hr);
369 
370     hr = IAudioClient_Start(ac);
371     ok(hr == AUDCLNT_E_NOT_STOPPED, "Start twice returns %08x\n", hr);
372 
373 cleanup:
374     IAudioClient_Release(ac);
375     CloseHandle(handle);
376     CoTaskMemFree(pwfx);
377 }
378 
379 static void test_formats(AUDCLNT_SHAREMODE mode)
380 {
381     IAudioClient *ac;
382     HRESULT hr, hrs;
383     WAVEFORMATEX fmt, *pwfx, *pwfx2;
384     int i;
385 
386     fmt.wFormatTag = WAVE_FORMAT_PCM;
387     fmt.cbSize = 0;
388 
389     for(i = 0; i < ARRAY_SIZE(win_formats); i++) {
390         hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
391                 NULL, (void**)&ac);
392         ok(hr == S_OK, "Activation failed with %08x\n", hr);
393         if(hr != S_OK)
394             continue;
395 
396         hr = IAudioClient_GetMixFormat(ac, &pwfx);
397         ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
398 
399         fmt.nSamplesPerSec = win_formats[i][0];
400         fmt.wBitsPerSample = win_formats[i][1];
401         fmt.nChannels      = win_formats[i][2];
402         fmt.nBlockAlign    = fmt.nChannels * fmt.wBitsPerSample / 8;
403         fmt.nAvgBytesPerSec= fmt.nBlockAlign * fmt.nSamplesPerSec;
404 
405         pwfx2 = (WAVEFORMATEX*)0xDEADF00D;
406         hr = IAudioClient_IsFormatSupported(ac, mode, &fmt, &pwfx2);
407         hrs = hr;
408         /* Only shared mode suggests something ... GetMixFormat! */
409         ok(hr == S_OK || (mode == AUDCLNT_SHAREMODE_SHARED
410            ? hr == S_FALSE || broken(hr == AUDCLNT_E_UNSUPPORTED_FORMAT &&
411                /* 5:1 card exception when asked for 1 channel at mixer rate */
412                pwfx->nChannels > 2 && fmt.nSamplesPerSec == pwfx->nSamplesPerSec)
413            : (hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == hexcl)),
414            "IsFormatSupported(%d, %ux%2ux%u) returns %08x\n", mode,
415            fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr);
416         if (hr == S_OK)
417             trace("IsSupported(%s, %ux%2ux%u)\n",
418                   mode == AUDCLNT_SHAREMODE_SHARED ? "shared " : "exclus.",
419                   fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels);
420 
421         /* Change GetMixFormat wBitsPerSample only => S_OK */
422         if (mode == AUDCLNT_SHAREMODE_SHARED
423             && fmt.nSamplesPerSec == pwfx->nSamplesPerSec
424             && fmt.nChannels == pwfx->nChannels)
425             ok(hr == S_OK, "Varying BitsPerSample %u\n", fmt.wBitsPerSample);
426 
427         ok((hr == S_FALSE)^(pwfx2 == NULL), "hr %x<->suggest %p\n", hr, pwfx2);
428         if (pwfx2 == (WAVEFORMATEX*)0xDEADF00D)
429             pwfx2 = NULL; /* broken in Wine < 1.3.28 */
430         if (pwfx2) {
431             ok(pwfx2->nSamplesPerSec == pwfx->nSamplesPerSec &&
432                pwfx2->nChannels      == pwfx->nChannels &&
433                pwfx2->wBitsPerSample == pwfx->wBitsPerSample,
434                "Suggestion %ux%2ux%u differs from GetMixFormat\n",
435                pwfx2->nSamplesPerSec, pwfx2->wBitsPerSample, pwfx2->nChannels);
436         }
437 
438         /* Vista returns E_INVALIDARG upon AUDCLNT_STREAMFLAGS_RATEADJUST */
439         hr = IAudioClient_Initialize(ac, mode, 0, 5000000, 0, &fmt, NULL);
440         if ((hrs == S_OK) ^ (hr == S_OK))
441             trace("Initialize (%s, %ux%2ux%u) returns %08x unlike IsFormatSupported\n",
442                   mode == AUDCLNT_SHAREMODE_SHARED ? "shared " : "exclus.",
443                   fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr);
444         if (mode == AUDCLNT_SHAREMODE_SHARED)
445             ok(hrs == S_OK ? hr == S_OK : hr == AUDCLNT_E_UNSUPPORTED_FORMAT,
446                "Initialize(shared,  %ux%2ux%u) returns %08x\n",
447                fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr);
448         else if (hrs == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED)
449             /* Unsupported format implies "create failed" and shadows "not allowed" */
450             ok(hrs == hexcl && (hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == hrs),
451                "Initialize(noexcl., %ux%2ux%u) returns %08x(%08x)\n",
452                fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr, hrs);
453         else
454             /* On testbot 48000x16x1 claims support, but does not Initialize.
455              * Some cards Initialize 44100|48000x16x1 yet claim no support;
456              * F. Gouget's w7 bots do that for 12000|96000x8|16x1|2 */
457             ok(hrs == S_OK ? hr == S_OK || broken(hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED)
458                : hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == AUDCLNT_E_UNSUPPORTED_FORMAT ||
459                  broken(hr == S_OK &&
460                      ((fmt.nChannels == 1 && fmt.wBitsPerSample == 16) ||
461                       (fmt.nSamplesPerSec == 12000 || fmt.nSamplesPerSec == 96000))),
462                "Initialize(exclus., %ux%2ux%u) returns %08x\n",
463                fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr);
464 
465         /* Bug in native (Vista/w2k8/w7): after Initialize failed, better
466          * Release this ac and Activate a new one.
467          * A second call (with a known working format) would yield
468          * ALREADY_INITIALIZED in shared mode yet be unusable, and in exclusive
469          * mode some entity keeps a lock on the device, causing DEVICE_IN_USE to
470          * all subsequent calls until the audio engine service is restarted. */
471 
472         CoTaskMemFree(pwfx2);
473         CoTaskMemFree(pwfx);
474         IAudioClient_Release(ac);
475     }
476 }
477 
478 static void test_references(void)
479 {
480     IAudioClient *ac;
481     IAudioRenderClient *rc;
482     ISimpleAudioVolume *sav;
483     IAudioStreamVolume *asv;
484     IAudioClock *acl;
485     WAVEFORMATEX *pwfx;
486     HRESULT hr;
487     ULONG ref;
488 
489     /* IAudioRenderClient */
490     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
491             NULL, (void**)&ac);
492     ok(hr == S_OK, "Activation failed with %08x\n", hr);
493     if(hr != S_OK)
494         return;
495 
496     hr = IAudioClient_GetMixFormat(ac, &pwfx);
497     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
498 
499     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
500             0, pwfx, NULL);
501     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
502 
503     CoTaskMemFree(pwfx);
504 
505     hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&rc);
506     ok(hr == S_OK, "GetService failed: %08x\n", hr);
507     if(hr != S_OK) {
508         IAudioClient_Release(ac);
509         return;
510     }
511 
512     IAudioRenderClient_AddRef(rc);
513     ref = IAudioRenderClient_Release(rc);
514     ok(ref != 0, "RenderClient_Release gave wrong refcount: %u\n", ref);
515 
516     ref = IAudioClient_Release(ac);
517     ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
518 
519     ref = IAudioRenderClient_Release(rc);
520     ok(ref == 0, "RenderClient_Release gave wrong refcount: %u\n", ref);
521 
522     /* ISimpleAudioVolume */
523     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
524             NULL, (void**)&ac);
525     ok(hr == S_OK, "Activation failed with %08x\n", hr);
526     if(hr != S_OK)
527         return;
528 
529     hr = IAudioClient_GetMixFormat(ac, &pwfx);
530     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
531 
532     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
533             0, pwfx, NULL);
534     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
535 
536     CoTaskMemFree(pwfx);
537 
538     hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
539     ok(hr == S_OK, "GetService failed: %08x\n", hr);
540 
541     ISimpleAudioVolume_AddRef(sav);
542     ref = ISimpleAudioVolume_Release(sav);
543     ok(ref != 0, "SimpleAudioVolume_Release gave wrong refcount: %u\n", ref);
544 
545     ref = IAudioClient_Release(ac);
546     ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
547 
548     ref = ISimpleAudioVolume_Release(sav);
549     ok(ref == 0, "SimpleAudioVolume_Release gave wrong refcount: %u\n", ref);
550 
551     /* IAudioClock */
552     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
553             NULL, (void**)&ac);
554     ok(hr == S_OK, "Activation failed with %08x\n", hr);
555     if(hr != S_OK)
556         return;
557 
558     hr = IAudioClient_GetMixFormat(ac, &pwfx);
559     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
560 
561     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
562             0, pwfx, NULL);
563     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
564 
565     CoTaskMemFree(pwfx);
566 
567     hr = IAudioClient_GetService(ac, &IID_IAudioClock, (void**)&acl);
568     ok(hr == S_OK, "GetService failed: %08x\n", hr);
569 
570     IAudioClock_AddRef(acl);
571     ref = IAudioClock_Release(acl);
572     ok(ref != 0, "AudioClock_Release gave wrong refcount: %u\n", ref);
573 
574     ref = IAudioClient_Release(ac);
575     ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
576 
577     ref = IAudioClock_Release(acl);
578     ok(ref == 0, "AudioClock_Release gave wrong refcount: %u\n", ref);
579 
580     /* IAudioStreamVolume */
581     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
582             NULL, (void**)&ac);
583     ok(hr == S_OK, "Activation failed with %08x\n", hr);
584     if(hr != S_OK)
585         return;
586 
587     hr = IAudioClient_GetMixFormat(ac, &pwfx);
588     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
589 
590     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
591             0, pwfx, NULL);
592     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
593 
594     CoTaskMemFree(pwfx);
595 
596     hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&asv);
597     ok(hr == S_OK, "GetService failed: %08x\n", hr);
598 
599     IAudioStreamVolume_AddRef(asv);
600     ref = IAudioStreamVolume_Release(asv);
601     ok(ref != 0, "AudioStreamVolume_Release gave wrong refcount: %u\n", ref);
602 
603     ref = IAudioClient_Release(ac);
604     ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
605 
606     ref = IAudioStreamVolume_Release(asv);
607     ok(ref == 0, "AudioStreamVolume_Release gave wrong refcount: %u\n", ref);
608 }
609 
610 static void test_event(void)
611 {
612     HANDLE event;
613     HRESULT hr;
614     DWORD r;
615     IAudioClient *ac;
616     WAVEFORMATEX *pwfx;
617 
618     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
619             NULL, (void**)&ac);
620     ok(hr == S_OK, "Activation failed with %08x\n", hr);
621     if(hr != S_OK)
622         return;
623 
624     hr = IAudioClient_GetMixFormat(ac, &pwfx);
625     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
626 
627     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
628             AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 5000000,
629             0, pwfx, NULL);
630     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
631 
632     CoTaskMemFree(pwfx);
633 
634     event = CreateEventW(NULL, FALSE, FALSE, NULL);
635     ok(event != NULL, "CreateEvent failed\n");
636 
637     hr = IAudioClient_Start(ac);
638     ok(hr == AUDCLNT_E_EVENTHANDLE_NOT_SET ||
639             hr == D3D11_ERROR_4E /* win10 */, "Start failed: %08x\n", hr);
640 
641     hr = IAudioClient_SetEventHandle(ac, event);
642     ok(hr == S_OK, "SetEventHandle failed: %08x\n", hr);
643 
644     hr = IAudioClient_SetEventHandle(ac, event);
645     ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME) ||
646             hr == E_UNEXPECTED /* win10 */, "SetEventHandle returns %08x\n", hr);
647 
648     r = WaitForSingleObject(event, 40);
649     ok(r == WAIT_TIMEOUT, "Wait(event) before Start gave %x\n", r);
650 
651     hr = IAudioClient_Start(ac);
652     ok(hr == S_OK, "Start failed: %08x\n", hr);
653 
654     r = WaitForSingleObject(event, 20);
655     ok(r == WAIT_OBJECT_0, "Wait(event) after Start gave %x\n", r);
656 
657     hr = IAudioClient_Stop(ac);
658     ok(hr == S_OK, "Stop failed: %08x\n", hr);
659 
660     ok(ResetEvent(event), "ResetEvent\n");
661 
662     /* Still receiving events! */
663     r = WaitForSingleObject(event, 20);
664     ok(r == WAIT_OBJECT_0, "Wait(event) after Stop gave %x\n", r);
665 
666     hr = IAudioClient_Reset(ac);
667     ok(hr == S_OK, "Reset failed: %08x\n", hr);
668 
669     ok(ResetEvent(event), "ResetEvent\n");
670 
671     r = WaitForSingleObject(event, 120);
672     ok(r == WAIT_OBJECT_0, "Wait(event) after Reset gave %x\n", r);
673 
674     hr = IAudioClient_SetEventHandle(ac, NULL);
675     ok(hr == E_INVALIDARG, "SetEventHandle(NULL) returns %08x\n", hr);
676 
677     r = WaitForSingleObject(event, 70);
678     ok(r == WAIT_OBJECT_0, "Wait(NULL event) gave %x\n", r);
679 
680     /* test releasing a playing stream */
681     hr = IAudioClient_Start(ac);
682     ok(hr == S_OK, "Start failed: %08x\n", hr);
683     IAudioClient_Release(ac);
684 
685     CloseHandle(event);
686 }
687 
688 static void test_padding(void)
689 {
690     HRESULT hr;
691     IAudioClient *ac;
692     IAudioRenderClient *arc;
693     WAVEFORMATEX *pwfx;
694     REFERENCE_TIME minp, defp;
695     BYTE *buf, silence;
696     UINT32 psize, pad, written, i;
697 
698     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
699             NULL, (void**)&ac);
700     ok(hr == S_OK, "Activation failed with %08x\n", hr);
701     if(hr != S_OK)
702         return;
703 
704     hr = IAudioClient_GetMixFormat(ac, &pwfx);
705     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
706     if(hr != S_OK)
707         return;
708 
709     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
710             0, 5000000, 0, pwfx, NULL);
711     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
712     if(hr != S_OK)
713         return;
714 
715     if(pwfx->wBitsPerSample == 8)
716         silence = 128;
717     else
718         silence = 0;
719 
720     /** GetDevicePeriod
721      * Default (= shared) device period is 10ms (e.g. 441 frames at 44100),
722      * except when the HW/OS forces a particular alignment,
723      * e.g. 10.1587ms is 28 * 16 = 448 frames at 44100 with HDA.
724      * 441 observed with Vista, 448 with w7 on the same HW! */
725     hr = IAudioClient_GetDevicePeriod(ac, &defp, &minp);
726     ok(hr == S_OK, "GetDevicePeriod failed: %08x\n", hr);
727     /* some wineXYZ.drv use 20ms, not seen on native */
728     ok(defp == 100000 || broken(defp == 101587) || defp == 200000,
729        "Expected 10ms default period: %u\n", (ULONG)defp);
730     ok(minp != 0, "Minimum period is 0\n");
731     ok(minp <= defp, "Minimum period is greater than default period\n");
732 
733     hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&arc);
734     ok(hr == S_OK, "GetService failed: %08x\n", hr);
735 
736     psize = MulDiv(defp, pwfx->nSamplesPerSec, 10000000) * 10;
737 
738     written = 0;
739     hr = IAudioClient_GetCurrentPadding(ac, &pad);
740     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
741     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
742 
743     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
744     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
745     ok(buf != NULL, "NULL buffer returned\n");
746     if(!win10){
747         /* win10 appears not to clear the buffer */
748         for(i = 0; i < psize * pwfx->nBlockAlign; ++i){
749             if(buf[i] != silence){
750                 ok(0, "buffer has data in it already, i: %u, value: %f\n", i, *((float*)buf));
751                 break;
752             }
753         }
754     }
755 
756     hr = IAudioRenderClient_GetBuffer(arc, 0, &buf);
757     ok(hr == AUDCLNT_E_OUT_OF_ORDER, "GetBuffer 0 size failed: %08x\n", hr);
758     ok(buf == NULL, "GetBuffer 0 gave %p\n", buf);
759     /* MSDN instead documents buf remains untouched */
760 
761     hr = IAudioClient_Reset(ac);
762     ok(hr == AUDCLNT_E_BUFFER_OPERATION_PENDING, "Reset failed: %08x\n", hr);
763 
764     hr = IAudioRenderClient_ReleaseBuffer(arc, psize,
765             AUDCLNT_BUFFERFLAGS_SILENT);
766     ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
767     if(hr == S_OK) written += psize;
768 
769     hr = IAudioClient_GetCurrentPadding(ac, &pad);
770     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
771     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
772 
773     psize = MulDiv(minp, pwfx->nSamplesPerSec, 10000000) * 10;
774 
775     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
776     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
777     ok(buf != NULL, "NULL buffer returned\n");
778 
779     hr = IAudioRenderClient_ReleaseBuffer(arc, psize,
780             AUDCLNT_BUFFERFLAGS_SILENT);
781     ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
782     written += psize;
783 
784     hr = IAudioClient_GetCurrentPadding(ac, &pad);
785     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
786     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
787 
788     /* overfull buffer. requested 1/2s buffer size, so try
789      * to get a 1/2s buffer, which should fail */
790     psize = pwfx->nSamplesPerSec / 2;
791     buf = (void*)0xDEADF00D;
792     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
793     ok(hr == AUDCLNT_E_BUFFER_TOO_LARGE, "GetBuffer gave wrong error: %08x\n", hr);
794     ok(buf == NULL, "NULL expected %p\n", buf);
795 
796     hr = IAudioRenderClient_ReleaseBuffer(arc, psize, 0);
797     ok(hr == AUDCLNT_E_OUT_OF_ORDER, "ReleaseBuffer gave wrong error: %08x\n", hr);
798 
799     psize = MulDiv(minp, pwfx->nSamplesPerSec, 10000000) * 2;
800 
801     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
802     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
803     ok(buf != NULL, "NULL buffer returned\n");
804 
805     hr = IAudioRenderClient_ReleaseBuffer(arc, 0, 0);
806     ok(hr == S_OK, "ReleaseBuffer 0 gave wrong error: %08x\n", hr);
807 
808     buf = (void*)0xDEADF00D;
809     hr = IAudioRenderClient_GetBuffer(arc, 0, &buf);
810     ok(hr == S_OK, "GetBuffer 0 size failed: %08x\n", hr);
811     ok(buf == NULL, "GetBuffer 0 gave %p\n", buf);
812     /* MSDN instead documents buf remains untouched */
813 
814     buf = (void*)0xDEADF00D;
815     hr = IAudioRenderClient_GetBuffer(arc, 0, &buf);
816     ok(hr == S_OK, "GetBuffer 0 size #2 failed: %08x\n", hr);
817     ok(buf == NULL, "GetBuffer 0 #2 gave %p\n", buf);
818 
819     hr = IAudioRenderClient_ReleaseBuffer(arc, psize, 0);
820     ok(hr == AUDCLNT_E_OUT_OF_ORDER, "ReleaseBuffer not size 0 gave %08x\n", hr);
821 
822     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
823     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
824     ok(buf != NULL, "NULL buffer returned\n");
825 
826     hr = IAudioRenderClient_ReleaseBuffer(arc, 0, 0);
827     ok(hr == S_OK, "ReleaseBuffer 0 gave wrong error: %08x\n", hr);
828 
829     hr = IAudioClient_GetCurrentPadding(ac, &pad);
830     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
831     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
832 
833     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
834     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
835     ok(buf != NULL, "NULL buffer returned\n");
836 
837     hr = IAudioRenderClient_ReleaseBuffer(arc, psize+1, AUDCLNT_BUFFERFLAGS_SILENT);
838     ok(hr == AUDCLNT_E_INVALID_SIZE, "ReleaseBuffer too large error: %08x\n", hr);
839     /* todo_wine means Wine may overwrite memory */
840     if(hr == S_OK) written += psize+1;
841 
842     /* Buffer still hold */
843     hr = IAudioRenderClient_ReleaseBuffer(arc, psize/2, AUDCLNT_BUFFERFLAGS_SILENT);
844     ok(hr == S_OK, "ReleaseBuffer after error: %08x\n", hr);
845     if(hr == S_OK) written += psize/2;
846 
847     hr = IAudioRenderClient_ReleaseBuffer(arc, 0, 0);
848     ok(hr == S_OK, "ReleaseBuffer 0 gave wrong error: %08x\n", hr);
849 
850     hr = IAudioClient_GetCurrentPadding(ac, &pad);
851     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
852     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
853 
854     CoTaskMemFree(pwfx);
855 
856     IAudioRenderClient_Release(arc);
857     IAudioClient_Release(ac);
858 }
859 
860 static void test_clock(int share)
861 {
862     HRESULT hr;
863     IAudioClient *ac;
864     IAudioClock *acl;
865     IAudioRenderClient *arc;
866     UINT64 freq, pos, pcpos0, pcpos, last;
867     UINT32 pad, gbsize, bufsize, fragment, parts, avail, slept = 0, sum = 0;
868     BYTE *data;
869     WAVEFORMATEX *pwfx;
870     LARGE_INTEGER hpctime, hpctime0, hpcfreq;
871     REFERENCE_TIME minp, defp, t1, t2;
872     REFERENCE_TIME duration = 5000000, period = 150000;
873     int i;
874 
875     ok(QueryPerformanceFrequency(&hpcfreq), "PerfFrequency failed\n");
876 
877     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
878             NULL, (void**)&ac);
879     ok(hr == S_OK, "Activation failed with %08x\n", hr);
880     if(hr != S_OK)
881         return;
882 
883     hr = IAudioClient_GetMixFormat(ac, &pwfx);
884     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
885     if(hr != S_OK)
886         return;
887 
888     hr = IAudioClient_GetDevicePeriod(ac, &defp, &minp);
889     ok(hr == S_OK, "GetDevicePeriod failed: %08x\n", hr);
890     ok(minp <= period, "desired period %u too small for %u\n", (ULONG)period, (ULONG)minp);
891 
892     if (share) {
893         trace("Testing shared mode\n");
894         /* period is ignored */
895         hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
896                 0, duration, period, pwfx, NULL);
897         period = defp;
898     } else {
899         pwfx->wFormatTag = WAVE_FORMAT_PCM;
900         pwfx->nChannels = 2;
901         pwfx->cbSize = 0;
902         pwfx->wBitsPerSample = 16; /* no floating point */
903         pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;
904         pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign;
905         trace("Testing exclusive mode at %u\n", pwfx->nSamplesPerSec);
906 
907         hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_EXCLUSIVE,
908                 0, duration, period, pwfx, NULL);
909     }
910     ok(share ? hr == S_OK : hr == hexcl || hr == AUDCLNT_E_DEVICE_IN_USE, "Initialize failed: %08x\n", hr);
911     if (hr != S_OK) {
912         CoTaskMemFree(pwfx);
913         IAudioClient_Release(ac);
914         if(hr == AUDCLNT_E_DEVICE_IN_USE)
915             skip("Device in use, no %s access\n", share ? "shared" : "exclusive");
916         return;
917     }
918 
919     /** GetStreamLatency
920      * Shared mode: 1x period + a little, but some 192000 devices return 5.3334ms.
921      * Exclusive mode: testbot returns 2x period + a little, but
922      * some HDA drivers return 1x period, some + a little. */
923     hr = IAudioClient_GetStreamLatency(ac, &t2);
924     ok(hr == S_OK, "GetStreamLatency failed: %08x\n", hr);
925     trace("Latency: %u.%04u ms\n", (UINT)(t2/10000), (UINT)(t2 % 10000));
926     ok(t2 >= period || broken(t2 >= period/2 && share && pwfx->nSamplesPerSec > 48000) ||
927             broken(t2 == 0) /* win10 */,
928        "Latency < default period, delta %ldus\n", (long)((t2-period)/10));
929 
930     /** GetBufferSize
931      * BufferSize must be rounded up, maximum 2s says MSDN.
932      * Both is wrong.  Rounding may lead to size a little smaller than duration;
933      * duration > 2s is accepted in shared mode.
934      * Shared mode: round solely w.r.t. mixer rate,
935      *              duration is no multiple of period.
936      * Exclusive mode: size appears as a multiple of some fragment that
937      * is either the rounded period or a fixed constant like 1024,
938      * whatever the driver implements. */
939     hr = IAudioClient_GetBufferSize(ac, &gbsize);
940     ok(hr == S_OK, "GetBufferSize failed: %08x\n", hr);
941 
942     bufsize   =  MulDiv(duration, pwfx->nSamplesPerSec, 10000000);
943     fragment  =  MulDiv(period,   pwfx->nSamplesPerSec, 10000000);
944     parts     =  MulDiv(bufsize, 1, fragment); /* instead of (duration, 1, period) */
945     trace("BufferSize %u estimated fragment %u x %u = %u\n", gbsize, fragment, parts, fragment * parts);
946     /* fragment size (= period in frames) is rounded up.
947      * BufferSize must be rounded up, maximum 2s says MSDN
948      * but it is rounded down modulo fragment ! */
949     if (share)
950     ok(gbsize == bufsize,
951        "BufferSize %u at rate %u\n", gbsize, pwfx->nSamplesPerSec);
952     else
953     ok(gbsize == parts * fragment || gbsize == MulDiv(bufsize, 1, 1024) * 1024,
954        "BufferSize %u misfits fragment size %u at rate %u\n", gbsize, fragment, pwfx->nSamplesPerSec);
955 
956     /* In shared mode, GetCurrentPadding decreases in multiples of
957      * fragment size (i.e. updated only at period ticks), whereas
958      * GetPosition appears to be reporting continuous positions.
959      * In exclusive mode, testbot behaves likewise, but native's Intel
960      * HDA driver shows no such deltas, GetCurrentPadding closely
961      * matches GetPosition, as in
962      * GetCurrentPadding = GetPosition - frames held in mmdevapi */
963 
964     hr = IAudioClient_GetService(ac, &IID_IAudioClock, (void**)&acl);
965     ok(hr == S_OK, "GetService(IAudioClock) failed: %08x\n", hr);
966 
967     hr = IAudioClock_GetFrequency(acl, &freq);
968     ok(hr == S_OK, "GetFrequency failed: %08x\n", hr);
969     trace("Clock Frequency %u\n", (UINT)freq);
970 
971     /* MSDN says it's arbitrary units, but shared mode is unlikely to change */
972     if (share)
973         ok(freq == pwfx->nSamplesPerSec * pwfx->nBlockAlign,
974            "Clock Frequency %u\n", (UINT)freq);
975     else
976         ok(freq == pwfx->nSamplesPerSec,
977            "Clock Frequency %u\n", (UINT)freq);
978 
979     hr = IAudioClock_GetPosition(acl, NULL, NULL);
980     ok(hr == E_POINTER, "GetPosition wrong error: %08x\n", hr);
981 
982     pcpos0 = 0;
983     hr = IAudioClock_GetPosition(acl, &pos, &pcpos0);
984     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
985     ok(pos == 0, "GetPosition returned non-zero pos before being started\n");
986     ok(pcpos0 != 0, "GetPosition returned zero pcpos\n");
987 
988     hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&arc);
989     ok(hr == S_OK, "GetService(IAudioRenderClient) failed: %08x\n", hr);
990 
991     hr = IAudioRenderClient_GetBuffer(arc, gbsize+1, &data);
992     ok(hr == AUDCLNT_E_BUFFER_TOO_LARGE, "GetBuffer too large failed: %08x\n", hr);
993 
994     avail = gbsize;
995     data = NULL;
996     hr = IAudioRenderClient_GetBuffer(arc, avail, &data);
997     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
998     trace("data at %p\n", data);
999 
1000     hr = IAudioRenderClient_ReleaseBuffer(arc, avail, winetest_debug>2 ?
1001         wave_generate_tone(pwfx, data, avail) : AUDCLNT_BUFFERFLAGS_SILENT);
1002     ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
1003     if(hr == S_OK) sum += avail;
1004 
1005     hr = IAudioClient_GetCurrentPadding(ac, &pad);
1006     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
1007     ok(pad == sum, "padding %u prior to start\n", pad);
1008 
1009     hr = IAudioClock_GetPosition(acl, &pos, NULL);
1010     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
1011     ok(pos == 0, "GetPosition returned non-zero pos before being started\n");
1012 
1013     hr = IAudioClient_Start(ac); /* #1 */
1014     ok(hr == S_OK, "Start failed: %08x\n", hr);
1015 
1016     Sleep(100);
1017     slept += 100;
1018 
1019     hr = IAudioClient_GetStreamLatency(ac, &t1);
1020     ok(hr == S_OK, "GetStreamLatency failed: %08x\n", hr);
1021     ok(t1 == t2, "Latency not constant, delta %ld\n", (long)(t1-t2));
1022 
1023     hr = IAudioClock_GetPosition(acl, &pos, NULL);
1024     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
1025     ok(pos > 0, "Position %u vs. last %u\n", (UINT)pos,0);
1026     /* in rare cases is slept*1.1 not enough with dmix */
1027     ok(pos*1000/freq <= slept*1.4, "Position %u too far after playing %ums\n", (UINT)pos, slept);
1028     last = pos;
1029 
1030     hr = IAudioClient_Stop(ac);
1031     ok(hr == S_OK, "Stop failed: %08x\n", hr);
1032 
1033     hr = IAudioClock_GetPosition(acl, &pos, NULL);
1034     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
1035     ok(pos >= last, "Position %u vs. last %u\n", (UINT)pos,(UINT)last);
1036     last = pos;
1037     if(/*share &&*/ winetest_debug>1)
1038         ok(pos*1000/freq <= slept*1.1, "Position %u too far after stop %ums\n", (UINT)pos, slept);
1039 
1040     hr = IAudioClient_Start(ac); /* #2 */
1041     ok(hr == S_OK, "Start failed: %08x\n", hr);
1042 
1043     Sleep(100);
1044     slept += 100;
1045 
1046     hr = IAudioClient_GetCurrentPadding(ac, &pad);
1047     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
1048     trace("padding %u past sleep #2\n", pad);
1049 
1050     /** IAudioClient_Stop
1051      * Exclusive mode: the audio engine appears to drop frames,
1052      * bumping GetPosition to a higher value than time allows, even
1053      * allowing GetPosition > sum Released - GetCurrentPadding (testbot)
1054      * Shared mode: no drop observed (or too small to be visible).
1055      * GetPosition = sum Released - GetCurrentPadding
1056      * Bugs: Some USB headset system drained the whole buffer, leaving
1057      *       padding 0 and bumping pos to sum minus 17 frames! */
1058 
1059     hr = IAudioClient_Stop(ac);
1060     ok(hr == S_OK, "Stop failed: %08x\n", hr);
1061 
1062     hr = IAudioClient_GetCurrentPadding(ac, &pad);
1063     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
1064 
1065     hr = IAudioClock_GetPosition(acl, &pos, NULL);
1066     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
1067     trace("padding %u position %u past stop #2\n", pad, (UINT)pos);
1068     ok(pos * pwfx->nSamplesPerSec <= sum * freq, "Position %u > written %u\n", (UINT)pos, sum);
1069     /* Prove that Stop must not drop frames (in shared mode). */
1070     ok(pad ? pos > last : pos >= last, "Position %u vs. last %u\n", (UINT)pos,(UINT)last);
1071     if (share && pad > 0 && winetest_debug>1)
1072         ok(pos*1000/freq <= slept*1.1, "Position %u too far after playing %ums\n", (UINT)pos, slept);
1073     /* in exclusive mode, testbot's w7 machines yield pos > sum-pad */
1074     if(/*share &&*/ winetest_debug>1)
1075         ok(pos * pwfx->nSamplesPerSec == (sum-pad) * freq,
1076            "Position %u after stop vs. %u padding\n", (UINT)pos, pad);
1077     last = pos;
1078 
1079     Sleep(100);
1080 
1081     hr = IAudioClock_GetPosition(acl, &pos, NULL);
1082     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
1083     ok(pos == last, "Position %u should stop.\n", (UINT)pos);
1084 
1085     /* Restart from 0 */
1086     hr = IAudioClient_Reset(ac);
1087     ok(hr == S_OK, "Reset failed: %08x\n", hr);
1088     slept = sum = 0;
1089 
1090     hr = IAudioClient_Reset(ac);
1091     ok(hr == S_OK, "Reset on an already reset stream returns %08x\n", hr);
1092 
1093     hr = IAudioClock_GetPosition(acl, &pos, &pcpos);
1094     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
1095     ok(pos == 0, "GetPosition returned non-zero pos after Reset\n");
1096     ok(pcpos > pcpos0, "pcpos should increase\n");
1097 
1098     avail = gbsize; /* implies GetCurrentPadding == 0 */
1099     hr = IAudioRenderClient_GetBuffer(arc, avail, &data);
1100     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
1101     trace("data at %p\n", data);
1102 
1103     hr = IAudioRenderClient_ReleaseBuffer(arc, avail, winetest_debug>2 ?
1104         wave_generate_tone(pwfx, data, avail) : AUDCLNT_BUFFERFLAGS_SILENT);
1105     ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
1106     if(hr == S_OK) sum += avail;
1107 
1108     hr = IAudioClient_GetCurrentPadding(ac, &pad);
1109     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
1110     ok(pad == sum, "padding %u prior to start\n", pad);
1111 
1112     hr = IAudioClock_GetPosition(acl, &pos, NULL);
1113     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
1114     ok(pos == 0, "GetPosition returned non-zero pos after Reset\n");
1115     last = pos;
1116 
1117     hr = IAudioClient_Start(ac); /* #3 */
1118     ok(hr == S_OK, "Start failed: %08x\n", hr);
1119 
1120     Sleep(100);
1121     slept += 100;
1122 
1123     hr = IAudioClock_GetPosition(acl, &pos, NULL);
1124     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
1125     trace("position %u past %ums sleep #3\n", (UINT)pos, slept);
1126     ok(pos > last, "Position %u vs. last %u\n", (UINT)pos,(UINT)last);
1127     ok(pos * pwfx->nSamplesPerSec <= sum * freq, "Position %u > written %u\n", (UINT)pos, sum);
1128     if (winetest_debug>1)
1129         ok(pos*1000/freq <= slept*1.1, "Position %u too far after playing %ums\n", (UINT)pos, slept);
1130     else
1131         skip("Rerun with WINETEST_DEBUG=2 for GetPosition tests.\n");
1132     last = pos;
1133 
1134     hr = IAudioClient_Reset(ac);
1135     ok(hr == AUDCLNT_E_NOT_STOPPED, "Reset while playing: %08x\n", hr);
1136 
1137     hr = IAudioClient_Stop(ac);
1138     ok(hr == S_OK, "Stop failed: %08x\n", hr);
1139 
1140     hr = IAudioClient_GetCurrentPadding(ac, &pad);
1141     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
1142 
1143     hr = IAudioClock_GetPosition(acl, &pos, &pcpos);
1144     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
1145     trace("padding %u position %u past stop #3\n", pad, (UINT)pos);
1146     ok(pos >= last, "Position %u vs. last %u\n", (UINT)pos,(UINT)last);
1147     ok(pcpos > pcpos0, "pcpos should increase\n");
1148     ok(pos * pwfx->nSamplesPerSec <= sum * freq, "Position %u > written %u\n", (UINT)pos, sum);
1149     if (pad > 0 && winetest_debug>1)
1150         ok(pos*1000/freq <= slept*1.1, "Position %u too far after stop %ums\n", (UINT)pos, slept);
1151     if(winetest_debug>1)
1152         ok(pos * pwfx->nSamplesPerSec == (sum-pad) * freq,
1153            "Position %u after stop vs. %u padding\n", (UINT)pos, pad);
1154     last = pos;
1155 
1156     /* Begin the big loop */
1157     hr = IAudioClient_Reset(ac);
1158     ok(hr == S_OK, "Reset failed: %08x\n", hr);
1159     slept = last = sum = 0;
1160     pcpos0 = pcpos;
1161 
1162     ok(QueryPerformanceCounter(&hpctime0), "PerfCounter unavailable\n");
1163 
1164     hr = IAudioClient_Reset(ac);
1165     ok(hr == S_OK, "Reset on an already reset stream returns %08x\n", hr);
1166 
1167     hr = IAudioClient_Start(ac);
1168     ok(hr == S_OK, "Start failed: %08x\n", hr);
1169 
1170     avail = pwfx->nSamplesPerSec * 15 / 16 / 2;
1171     data = NULL;
1172     hr = IAudioRenderClient_GetBuffer(arc, avail, &data);
1173     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
1174     trace("data at %p for prefill %u\n", data, avail);
1175 
1176     if (winetest_debug>2) {
1177         hr = IAudioClient_Stop(ac);
1178         ok(hr == S_OK, "Stop failed: %08x\n", hr);
1179 
1180         Sleep(20);
1181         slept += 20;
1182 
1183         hr = IAudioClient_Reset(ac);
1184         ok(hr == AUDCLNT_E_BUFFER_OPERATION_PENDING, "Reset failed: %08x\n", hr);
1185 
1186         hr = IAudioClient_Start(ac);
1187         ok(hr == S_OK, "Start failed: %08x\n", hr);
1188     }
1189 
1190     /* Despite passed time, data must still point to valid memory... */
1191     hr = IAudioRenderClient_ReleaseBuffer(arc, avail,
1192         wave_generate_tone(pwfx, data, avail));
1193     ok(hr == S_OK, "ReleaseBuffer after stop+start failed: %08x\n", hr);
1194     if(hr == S_OK) sum += avail;
1195 
1196     /* GetCurrentPadding(GCP) == 0 does not mean an underrun happened, as the
1197      * mixer may still have a little data.  We believe an underrun will occur
1198      * when the mixer finds GCP smaller than a period size at the *end* of a
1199      * period cycle, i.e. shortly before calling SetEvent to signal the app
1200      * that it has ~10ms to supply data for the next cycle.  IOW, a zero GCP
1201      * with no data written for over a period causes an underrun. */
1202 
1203     Sleep(350);
1204     slept += 350;
1205     ok(QueryPerformanceCounter(&hpctime), "PerfCounter failed\n");
1206     trace("hpctime %u after %ums\n",
1207         (ULONG)((hpctime.QuadPart-hpctime0.QuadPart)*1000/hpcfreq.QuadPart), slept);
1208 
1209     hr = IAudioClock_GetPosition(acl, &pos, &pcpos);
1210     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
1211     ok(pos > last, "Position %u vs. last %u\n", (UINT)pos,(UINT)last);
1212     last = pos;
1213 
1214     for(i=0; i < 9; i++) {
1215         Sleep(100);
1216         slept += 100;
1217 
1218         hr = IAudioClock_GetPosition(acl, &pos, &pcpos);
1219         ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
1220 
1221         hr = IAudioClient_GetCurrentPadding(ac, &pad);
1222         ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
1223 
1224         ok(QueryPerformanceCounter(&hpctime), "PerfCounter failed\n");
1225         trace("hpctime %u pcpos %u\n",
1226               (ULONG)((hpctime.QuadPart-hpctime0.QuadPart)*1000/hpcfreq.QuadPart),
1227               (ULONG)((pcpos-pcpos0)/10000));
1228 
1229         /* Use sum-pad to see whether position is ahead padding or not. */
1230         trace("padding %u position %u/%u slept %ums iteration %d\n", pad, (UINT)pos, sum-pad, slept, i);
1231         ok(pad ? pos > last : pos >= last, "No position increase at iteration %d\n", i);
1232         ok(pos * pwfx->nSamplesPerSec <= sum * freq, "Position %u > written %u\n", (UINT)pos, sum);
1233         if (winetest_debug>1) {
1234             /* Padding does not lag behind by much */
1235             ok(pos * pwfx->nSamplesPerSec <= (sum-pad+fragment) * freq, "Position %u > written %u\n", (UINT)pos, sum);
1236             ok(pos*1000/freq <= slept*1.1, "Position %u too far after %ums\n", (UINT)pos, slept);
1237             if (pad) /* not in case of underrun */
1238                 ok((pos-last)*1000/freq >= 90 && 110 >= (pos-last)*1000/freq,
1239                    "Position delta %ld not regular: %ld ms\n", (long)(pos-last), (long)((pos-last)*1000/freq));
1240         }
1241         last = pos;
1242 
1243         hr = IAudioClient_GetStreamLatency(ac, &t1);
1244         ok(hr == S_OK, "GetStreamLatency failed: %08x\n", hr);
1245         ok(t1 == t2, "Latency not constant, delta %ld\n", (long)(t1-t2));
1246 
1247         avail = pwfx->nSamplesPerSec * 15 / 16 / 2;
1248         data = NULL;
1249         hr = IAudioRenderClient_GetBuffer(arc, avail, &data);
1250         /* ok(hr == AUDCLNT_E_BUFFER_TOO_LARGE || (hr == S_OK && i==0) without todo_wine */
1251         ok(hr == S_OK || hr == AUDCLNT_E_BUFFER_TOO_LARGE,
1252            "GetBuffer large (%u) failed: %08x\n", avail, hr);
1253         if(hr == S_OK && i) ok(FALSE, "GetBuffer large (%u) at iteration %d\n", avail, i);
1254         /* Only the first iteration should allow that large a buffer
1255          * as prefill was drained during the first 350+100ms sleep.
1256          * Afterwards, only 100ms of data should find room per iteration. */
1257 
1258         if(hr == S_OK) {
1259             trace("data at %p\n", data);
1260         } else {
1261             avail = gbsize - pad;
1262             hr = IAudioRenderClient_GetBuffer(arc, avail, &data);
1263             ok(hr == S_OK, "GetBuffer small %u failed: %08x\n", avail, hr);
1264             trace("data at %p (small %u)\n", data, avail);
1265         }
1266         ok(data != NULL, "NULL buffer returned\n");
1267         if(i % 3 && !winetest_interactive) {
1268             memset(data, 0, avail * pwfx->nBlockAlign);
1269             hr = IAudioRenderClient_ReleaseBuffer(arc, avail, 0);
1270         } else {
1271             hr = IAudioRenderClient_ReleaseBuffer(arc, avail,
1272                 wave_generate_tone(pwfx, data, avail));
1273         }
1274         ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
1275         if(hr == S_OK) sum += avail;
1276     }
1277 
1278     hr = IAudioClock_GetPosition(acl, &pos, NULL);
1279     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
1280     trace("position %u\n", (UINT)pos);
1281 
1282     Sleep(1000); /* 500ms buffer underrun past full buffer */
1283 
1284     hr = IAudioClient_GetCurrentPadding(ac, &pad);
1285     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
1286 
1287     hr = IAudioClock_GetPosition(acl, &pos, NULL);
1288     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
1289     trace("position %u past underrun, %u padding left, %u frames written\n", (UINT)pos, pad, sum);
1290 
1291     if (share) {
1292         /* Following underrun, all samples were played */
1293         ok(pad == 0, "GetCurrentPadding returned %u, should be 0\n", pad);
1294         ok(pos * pwfx->nSamplesPerSec == sum * freq,
1295            "Position %u at end vs. %u submitted frames\n", (UINT)pos, sum);
1296     } else {
1297         /* Vista and w2k8 leave partial fragments behind */
1298         ok(pad == 0 /* w7, w2k8R2 */||
1299            pos * pwfx->nSamplesPerSec == (sum-pad) * freq, "GetCurrentPadding returned %u, should be 0\n", pad);
1300         /* expect at most 5 fragments (75ms) away */
1301         ok(pos * pwfx->nSamplesPerSec <= sum * freq &&
1302            pos * pwfx->nSamplesPerSec + 5 * fragment * freq >= sum * freq,
1303            "Position %u at end vs. %u submitted frames\n", (UINT)pos, sum);
1304     }
1305 
1306     hr = IAudioClient_GetStreamLatency(ac, &t1);
1307     ok(hr == S_OK, "GetStreamLatency failed: %08x\n", hr);
1308     ok(t1 == t2, "Latency not constant, delta %ld\n", (long)(t1-t2));
1309 
1310     ok(QueryPerformanceCounter(&hpctime), "PerfCounter failed\n");
1311     trace("hpctime %u after underrun\n", (ULONG)((hpctime.QuadPart-hpctime0.QuadPart)*1000/hpcfreq.QuadPart));
1312 
1313     hr = IAudioClient_Stop(ac);
1314     ok(hr == S_OK, "Stop failed: %08x\n", hr);
1315 
1316     CoTaskMemFree(pwfx);
1317 
1318     IAudioClock_Release(acl);
1319     IAudioRenderClient_Release(arc);
1320     IAudioClient_Release(ac);
1321 }
1322 
1323 static void test_session(void)
1324 {
1325     IAudioClient *ses1_ac1, *ses1_ac2, *cap_ac;
1326     IAudioSessionControl2 *ses1_ctl, *ses1_ctl2, *cap_ctl = NULL;
1327     IMMDevice *cap_dev;
1328     GUID ses1_guid;
1329     AudioSessionState state;
1330     WAVEFORMATEX *pwfx;
1331     ULONG ref;
1332     HRESULT hr;
1333 
1334     hr = CoCreateGuid(&ses1_guid);
1335     ok(hr == S_OK, "CoCreateGuid failed: %08x\n", hr);
1336 
1337     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1338             NULL, (void**)&ses1_ac1);
1339     ok(hr == S_OK, "Activation failed with %08x\n", hr);
1340     if (FAILED(hr)) return;
1341 
1342     hr = IAudioClient_GetMixFormat(ses1_ac1, &pwfx);
1343     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1344 
1345     hr = IAudioClient_Initialize(ses1_ac1, AUDCLNT_SHAREMODE_SHARED,
1346             0, 5000000, 0, pwfx, &ses1_guid);
1347     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1348 
1349     if(hr == S_OK){
1350         hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1351                 NULL, (void**)&ses1_ac2);
1352         ok(hr == S_OK, "Activation failed with %08x\n", hr);
1353     }
1354     if(hr != S_OK){
1355         skip("Unable to open the same device twice. Skipping session tests\n");
1356 
1357         ref = IAudioClient_Release(ses1_ac1);
1358         ok(ref == 0, "AudioClient wasn't released: %u\n", ref);
1359         CoTaskMemFree(pwfx);
1360         return;
1361     }
1362 
1363     hr = IAudioClient_Initialize(ses1_ac2, AUDCLNT_SHAREMODE_SHARED,
1364             0, 5000000, 0, pwfx, &ses1_guid);
1365     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1366 
1367     hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme, eCapture,
1368             eMultimedia, &cap_dev);
1369     if(hr == S_OK){
1370         hr = IMMDevice_Activate(cap_dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1371                 NULL, (void**)&cap_ac);
1372         ok((hr == S_OK)^(cap_ac == NULL), "Activate %08x &out pointer\n", hr);
1373         ok(hr == S_OK, "Activate failed: %08x\n", hr);
1374         IMMDevice_Release(cap_dev);
1375     }
1376     if(hr == S_OK){
1377         WAVEFORMATEX *cap_pwfx;
1378 
1379         hr = IAudioClient_GetMixFormat(cap_ac, &cap_pwfx);
1380         ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1381 
1382         hr = IAudioClient_Initialize(cap_ac, AUDCLNT_SHAREMODE_SHARED,
1383                 0, 5000000, 0, cap_pwfx, &ses1_guid);
1384         ok(hr == S_OK, "Initialize failed for capture in rendering session: %08x\n", hr);
1385         CoTaskMemFree(cap_pwfx);
1386     }
1387     if(hr == S_OK){
1388         hr = IAudioClient_GetService(cap_ac, &IID_IAudioSessionControl, (void**)&cap_ctl);
1389         ok(hr == S_OK, "GetService failed: %08x\n", hr);
1390         if(FAILED(hr))
1391             cap_ctl = NULL;
1392     }else
1393         skip("No capture session: %08x; skipping capture device in render session tests\n", hr);
1394 
1395     hr = IAudioClient_GetService(ses1_ac1, &IID_IAudioSessionControl2, (void**)&ses1_ctl);
1396     ok(hr == E_NOINTERFACE, "GetService gave wrong error: %08x\n", hr);
1397 
1398     hr = IAudioClient_GetService(ses1_ac1, &IID_IAudioSessionControl, (void**)&ses1_ctl);
1399     ok(hr == S_OK, "GetService failed: %08x\n", hr);
1400 
1401     hr = IAudioClient_GetService(ses1_ac1, &IID_IAudioSessionControl, (void**)&ses1_ctl2);
1402     ok(hr == S_OK, "GetService failed: %08x\n", hr);
1403     ok(ses1_ctl == ses1_ctl2, "Got different controls: %p %p\n", ses1_ctl, ses1_ctl2);
1404     ref = IAudioSessionControl2_Release(ses1_ctl2);
1405     ok(ref != 0, "AudioSessionControl was destroyed\n");
1406 
1407     hr = IAudioClient_GetService(ses1_ac2, &IID_IAudioSessionControl, (void**)&ses1_ctl2);
1408     ok(hr == S_OK, "GetService failed: %08x\n", hr);
1409 
1410     hr = IAudioSessionControl2_GetState(ses1_ctl, NULL);
1411     ok(hr == NULL_PTR_ERR, "GetState gave wrong error: %08x\n", hr);
1412 
1413     hr = IAudioSessionControl2_GetState(ses1_ctl, &state);
1414     ok(hr == S_OK, "GetState failed: %08x\n", hr);
1415     ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
1416 
1417     hr = IAudioSessionControl2_GetState(ses1_ctl2, &state);
1418     ok(hr == S_OK, "GetState failed: %08x\n", hr);
1419     ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
1420 
1421     if(cap_ctl){
1422         hr = IAudioSessionControl2_GetState(cap_ctl, &state);
1423         ok(hr == S_OK, "GetState failed: %08x\n", hr);
1424         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
1425     }
1426 
1427     hr = IAudioClient_Start(ses1_ac1);
1428     ok(hr == S_OK, "Start failed: %08x\n", hr);
1429 
1430     hr = IAudioSessionControl2_GetState(ses1_ctl, &state);
1431     ok(hr == S_OK, "GetState failed: %08x\n", hr);
1432     ok(state == AudioSessionStateActive, "Got wrong state: %d\n", state);
1433 
1434     hr = IAudioSessionControl2_GetState(ses1_ctl2, &state);
1435     ok(hr == S_OK, "GetState failed: %08x\n", hr);
1436     ok(state == AudioSessionStateActive, "Got wrong state: %d\n", state);
1437 
1438     if(cap_ctl){
1439         hr = IAudioSessionControl2_GetState(cap_ctl, &state);
1440         ok(hr == S_OK, "GetState failed: %08x\n", hr);
1441         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
1442     }
1443 
1444     hr = IAudioClient_Stop(ses1_ac1);
1445     ok(hr == S_OK, "Start failed: %08x\n", hr);
1446 
1447     hr = IAudioSessionControl2_GetState(ses1_ctl, &state);
1448     ok(hr == S_OK, "GetState failed: %08x\n", hr);
1449     ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
1450 
1451     hr = IAudioSessionControl2_GetState(ses1_ctl2, &state);
1452     ok(hr == S_OK, "GetState failed: %08x\n", hr);
1453     ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
1454 
1455     if(cap_ctl){
1456         hr = IAudioSessionControl2_GetState(cap_ctl, &state);
1457         ok(hr == S_OK, "GetState failed: %08x\n", hr);
1458         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
1459 
1460         hr = IAudioClient_Start(cap_ac);
1461         ok(hr == S_OK, "Start failed: %08x\n", hr);
1462 
1463         hr = IAudioSessionControl2_GetState(ses1_ctl, &state);
1464         ok(hr == S_OK, "GetState failed: %08x\n", hr);
1465         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
1466 
1467         hr = IAudioSessionControl2_GetState(ses1_ctl2, &state);
1468         ok(hr == S_OK, "GetState failed: %08x\n", hr);
1469         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
1470 
1471         hr = IAudioSessionControl2_GetState(cap_ctl, &state);
1472         ok(hr == S_OK, "GetState failed: %08x\n", hr);
1473         ok(state == AudioSessionStateActive, "Got wrong state: %d\n", state);
1474 
1475         hr = IAudioClient_Stop(cap_ac);
1476         ok(hr == S_OK, "Stop failed: %08x\n", hr);
1477 
1478         hr = IAudioSessionControl2_GetState(ses1_ctl, &state);
1479         ok(hr == S_OK, "GetState failed: %08x\n", hr);
1480         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
1481 
1482         hr = IAudioSessionControl2_GetState(ses1_ctl2, &state);
1483         ok(hr == S_OK, "GetState failed: %08x\n", hr);
1484         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
1485 
1486         hr = IAudioSessionControl2_GetState(cap_ctl, &state);
1487         ok(hr == S_OK, "GetState failed: %08x\n", hr);
1488         ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
1489 
1490         ref = IAudioSessionControl2_Release(cap_ctl);
1491         ok(ref == 0, "AudioSessionControl wasn't released: %u\n", ref);
1492 
1493         ref = IAudioClient_Release(cap_ac);
1494         ok(ref == 0, "AudioClient wasn't released: %u\n", ref);
1495     }
1496 
1497     ref = IAudioSessionControl2_Release(ses1_ctl);
1498     ok(ref == 0, "AudioSessionControl wasn't released: %u\n", ref);
1499 
1500     ref = IAudioClient_Release(ses1_ac1);
1501     ok(ref == 0, "AudioClient wasn't released: %u\n", ref);
1502 
1503     ref = IAudioClient_Release(ses1_ac2);
1504     ok(ref == 1, "AudioClient had wrong refcount: %u\n", ref);
1505 
1506     /* we've released all of our IAudioClient references, so check GetState */
1507     hr = IAudioSessionControl2_GetState(ses1_ctl2, &state);
1508     ok(hr == S_OK, "GetState failed: %08x\n", hr);
1509     ok(state == AudioSessionStateInactive, "Got wrong state: %d\n", state);
1510 
1511     ref = IAudioSessionControl2_Release(ses1_ctl2);
1512     ok(ref == 0, "AudioSessionControl wasn't released: %u\n", ref);
1513 
1514     CoTaskMemFree(pwfx);
1515 }
1516 
1517 static void test_streamvolume(void)
1518 {
1519     IAudioClient *ac;
1520     IAudioStreamVolume *asv;
1521     WAVEFORMATEX *fmt;
1522     UINT32 chans, i;
1523     HRESULT hr;
1524     float vol, *vols;
1525 
1526     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1527             NULL, (void**)&ac);
1528     ok(hr == S_OK, "Activation failed with %08x\n", hr);
1529     if(hr != S_OK)
1530         return;
1531 
1532     hr = IAudioClient_GetMixFormat(ac, &fmt);
1533     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1534 
1535     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
1536             0, fmt, NULL);
1537     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1538 
1539     if(hr == S_OK){
1540         hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&asv);
1541         ok(hr == S_OK, "GetService failed: %08x\n", hr);
1542     }
1543     if(hr != S_OK){
1544         IAudioClient_Release(ac);
1545         CoTaskMemFree(fmt);
1546         return;
1547     }
1548 
1549     hr = IAudioStreamVolume_GetChannelCount(asv, NULL);
1550     ok(hr == E_POINTER, "GetChannelCount gave wrong error: %08x\n", hr);
1551 
1552     hr = IAudioStreamVolume_GetChannelCount(asv, &chans);
1553     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1554     ok(chans == fmt->nChannels, "GetChannelCount gave wrong number of channels: %d\n", chans);
1555 
1556     hr = IAudioStreamVolume_GetChannelVolume(asv, fmt->nChannels, NULL);
1557     ok(hr == E_POINTER, "GetChannelCount gave wrong error: %08x\n", hr);
1558 
1559     hr = IAudioStreamVolume_GetChannelVolume(asv, fmt->nChannels, &vol);
1560     ok(hr == E_INVALIDARG, "GetChannelCount gave wrong error: %08x\n", hr);
1561 
1562     hr = IAudioStreamVolume_GetChannelVolume(asv, 0, NULL);
1563     ok(hr == E_POINTER, "GetChannelCount gave wrong error: %08x\n", hr);
1564 
1565     hr = IAudioStreamVolume_GetChannelVolume(asv, 0, &vol);
1566     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1567     ok(vol == 1.f, "Channel volume was not 1: %f\n", vol);
1568 
1569     hr = IAudioStreamVolume_SetChannelVolume(asv, fmt->nChannels, -1.f);
1570     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
1571 
1572     hr = IAudioStreamVolume_SetChannelVolume(asv, 0, -1.f);
1573     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
1574 
1575     hr = IAudioStreamVolume_SetChannelVolume(asv, 0, 2.f);
1576     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
1577 
1578     hr = IAudioStreamVolume_SetChannelVolume(asv, 0, 0.2f);
1579     ok(hr == S_OK, "SetChannelVolume failed: %08x\n", hr);
1580 
1581     hr = IAudioStreamVolume_GetChannelVolume(asv, 0, &vol);
1582     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1583     ok(fabsf(vol - 0.2f) < 0.05f, "Channel volume wasn't 0.2: %f\n", vol);
1584 
1585     hr = IAudioStreamVolume_GetAllVolumes(asv, 0, NULL);
1586     ok(hr == E_POINTER, "GetAllVolumes gave wrong error: %08x\n", hr);
1587 
1588     hr = IAudioStreamVolume_GetAllVolumes(asv, fmt->nChannels, NULL);
1589     ok(hr == E_POINTER, "GetAllVolumes gave wrong error: %08x\n", hr);
1590 
1591     vols = HeapAlloc(GetProcessHeap(), 0, fmt->nChannels * sizeof(float));
1592     ok(vols != NULL, "HeapAlloc failed\n");
1593 
1594     hr = IAudioStreamVolume_GetAllVolumes(asv, fmt->nChannels - 1, vols);
1595     ok(hr == E_INVALIDARG, "GetAllVolumes gave wrong error: %08x\n", hr);
1596 
1597     hr = IAudioStreamVolume_GetAllVolumes(asv, fmt->nChannels, vols);
1598     ok(hr == S_OK, "GetAllVolumes failed: %08x\n", hr);
1599     ok(fabsf(vols[0] - 0.2f) < 0.05f, "Channel 0 volume wasn't 0.2: %f\n", vol);
1600     for(i = 1; i < fmt->nChannels; ++i)
1601         ok(vols[i] == 1.f, "Channel %d volume is not 1: %f\n", i, vols[i]);
1602 
1603     hr = IAudioStreamVolume_SetAllVolumes(asv, 0, NULL);
1604     ok(hr == E_POINTER, "SetAllVolumes gave wrong error: %08x\n", hr);
1605 
1606     hr = IAudioStreamVolume_SetAllVolumes(asv, fmt->nChannels, NULL);
1607     ok(hr == E_POINTER, "SetAllVolumes gave wrong error: %08x\n", hr);
1608 
1609     hr = IAudioStreamVolume_SetAllVolumes(asv, fmt->nChannels - 1, vols);
1610     ok(hr == E_INVALIDARG, "SetAllVolumes gave wrong error: %08x\n", hr);
1611 
1612     hr = IAudioStreamVolume_SetAllVolumes(asv, fmt->nChannels, vols);
1613     ok(hr == S_OK, "SetAllVolumes failed: %08x\n", hr);
1614 
1615     HeapFree(GetProcessHeap(), 0, vols);
1616     IAudioStreamVolume_Release(asv);
1617     IAudioClient_Release(ac);
1618     CoTaskMemFree(fmt);
1619 }
1620 
1621 static void test_channelvolume(void)
1622 {
1623     IAudioClient *ac;
1624     IChannelAudioVolume *acv;
1625     WAVEFORMATEX *fmt;
1626     UINT32 chans, i;
1627     HRESULT hr;
1628     float vol, *vols;
1629 
1630     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1631             NULL, (void**)&ac);
1632     ok(hr == S_OK, "Activation failed with %08x\n", hr);
1633     if(hr != S_OK)
1634         return;
1635 
1636     hr = IAudioClient_GetMixFormat(ac, &fmt);
1637     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1638 
1639     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
1640             AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, NULL);
1641     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1642 
1643     if(hr == S_OK){
1644         hr = IAudioClient_GetService(ac, &IID_IChannelAudioVolume, (void**)&acv);
1645         ok(hr == S_OK, "GetService failed: %08x\n", hr);
1646     }
1647     if(hr != S_OK){
1648         IAudioClient_Release(ac);
1649         CoTaskMemFree(fmt);
1650         return;
1651     }
1652 
1653     hr = IChannelAudioVolume_GetChannelCount(acv, NULL);
1654     ok(hr == NULL_PTR_ERR, "GetChannelCount gave wrong error: %08x\n", hr);
1655 
1656     hr = IChannelAudioVolume_GetChannelCount(acv, &chans);
1657     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1658     ok(chans == fmt->nChannels, "GetChannelCount gave wrong number of channels: %d\n", chans);
1659 
1660     hr = IChannelAudioVolume_GetChannelVolume(acv, fmt->nChannels, NULL);
1661     ok(hr == NULL_PTR_ERR, "GetChannelCount gave wrong error: %08x\n", hr);
1662 
1663     hr = IChannelAudioVolume_GetChannelVolume(acv, fmt->nChannels, &vol);
1664     ok(hr == E_INVALIDARG, "GetChannelCount gave wrong error: %08x\n", hr);
1665 
1666     hr = IChannelAudioVolume_GetChannelVolume(acv, 0, NULL);
1667     ok(hr == NULL_PTR_ERR, "GetChannelCount gave wrong error: %08x\n", hr);
1668 
1669     hr = IChannelAudioVolume_GetChannelVolume(acv, 0, &vol);
1670     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1671     ok(vol == 1.f, "Channel volume was not 1: %f\n", vol);
1672 
1673     hr = IChannelAudioVolume_SetChannelVolume(acv, fmt->nChannels, -1.f, NULL);
1674     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
1675 
1676     hr = IChannelAudioVolume_SetChannelVolume(acv, 0, -1.f, NULL);
1677     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
1678 
1679     hr = IChannelAudioVolume_SetChannelVolume(acv, 0, 2.f, NULL);
1680     ok(hr == E_INVALIDARG, "SetChannelVolume gave wrong error: %08x\n", hr);
1681 
1682     hr = IChannelAudioVolume_SetChannelVolume(acv, 0, 0.2f, NULL);
1683     ok(hr == S_OK, "SetChannelVolume failed: %08x\n", hr);
1684 
1685     hr = IChannelAudioVolume_GetChannelVolume(acv, 0, &vol);
1686     ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1687     ok(fabsf(vol - 0.2f) < 0.05f, "Channel volume wasn't 0.2: %f\n", vol);
1688 
1689     hr = IChannelAudioVolume_GetAllVolumes(acv, 0, NULL);
1690     ok(hr == NULL_PTR_ERR, "GetAllVolumes gave wrong error: %08x\n", hr);
1691 
1692     hr = IChannelAudioVolume_GetAllVolumes(acv, fmt->nChannels, NULL);
1693     ok(hr == NULL_PTR_ERR, "GetAllVolumes gave wrong error: %08x\n", hr);
1694 
1695     vols = HeapAlloc(GetProcessHeap(), 0, fmt->nChannels * sizeof(float));
1696     ok(vols != NULL, "HeapAlloc failed\n");
1697 
1698     hr = IChannelAudioVolume_GetAllVolumes(acv, fmt->nChannels - 1, vols);
1699     ok(hr == E_INVALIDARG, "GetAllVolumes gave wrong error: %08x\n", hr);
1700 
1701     hr = IChannelAudioVolume_GetAllVolumes(acv, fmt->nChannels, vols);
1702     ok(hr == S_OK, "GetAllVolumes failed: %08x\n", hr);
1703     ok(fabsf(vols[0] - 0.2f) < 0.05f, "Channel 0 volume wasn't 0.2: %f\n", vol);
1704     for(i = 1; i < fmt->nChannels; ++i)
1705         ok(vols[i] == 1.f, "Channel %d volume is not 1: %f\n", i, vols[i]);
1706 
1707     hr = IChannelAudioVolume_SetAllVolumes(acv, 0, NULL, NULL);
1708     ok(hr == NULL_PTR_ERR, "SetAllVolumes gave wrong error: %08x\n", hr);
1709 
1710     hr = IChannelAudioVolume_SetAllVolumes(acv, fmt->nChannels, NULL, NULL);
1711     ok(hr == NULL_PTR_ERR, "SetAllVolumes gave wrong error: %08x\n", hr);
1712 
1713     hr = IChannelAudioVolume_SetAllVolumes(acv, fmt->nChannels - 1, vols, NULL);
1714     ok(hr == E_INVALIDARG, "SetAllVolumes gave wrong error: %08x\n", hr);
1715 
1716     hr = IChannelAudioVolume_SetAllVolumes(acv, fmt->nChannels, vols, NULL);
1717     ok(hr == S_OK, "SetAllVolumes failed: %08x\n", hr);
1718 
1719     hr = IChannelAudioVolume_SetChannelVolume(acv, 0, 1.0f, NULL);
1720     ok(hr == S_OK, "SetChannelVolume failed: %08x\n", hr);
1721 
1722     HeapFree(GetProcessHeap(), 0, vols);
1723     IChannelAudioVolume_Release(acv);
1724     IAudioClient_Release(ac);
1725     CoTaskMemFree(fmt);
1726 }
1727 
1728 static void test_simplevolume(void)
1729 {
1730     IAudioClient *ac;
1731     ISimpleAudioVolume *sav;
1732     WAVEFORMATEX *fmt;
1733     HRESULT hr;
1734     float vol;
1735     BOOL mute;
1736 
1737     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1738             NULL, (void**)&ac);
1739     ok(hr == S_OK, "Activation failed with %08x\n", hr);
1740     if(hr != S_OK)
1741         return;
1742 
1743     hr = IAudioClient_GetMixFormat(ac, &fmt);
1744     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1745 
1746     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
1747             AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, NULL);
1748     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1749 
1750     if(hr == S_OK){
1751         hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
1752         ok(hr == S_OK, "GetService failed: %08x\n", hr);
1753     }
1754     if(hr != S_OK){
1755         IAudioClient_Release(ac);
1756         CoTaskMemFree(fmt);
1757         return;
1758     }
1759 
1760     hr = ISimpleAudioVolume_GetMasterVolume(sav, NULL);
1761     ok(hr == NULL_PTR_ERR, "GetMasterVolume gave wrong error: %08x\n", hr);
1762 
1763     hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
1764     ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1765     ok(vol == 1.f, "Master volume wasn't 1: %f\n", vol);
1766 
1767     hr = ISimpleAudioVolume_SetMasterVolume(sav, -1.f, NULL);
1768     ok(hr == E_INVALIDARG, "SetMasterVolume gave wrong error: %08x\n", hr);
1769 
1770     hr = ISimpleAudioVolume_SetMasterVolume(sav, 2.f, NULL);
1771     ok(hr == E_INVALIDARG, "SetMasterVolume gave wrong error: %08x\n", hr);
1772 
1773     hr = ISimpleAudioVolume_SetMasterVolume(sav, 0.2f, NULL);
1774     ok(hr == S_OK, "SetMasterVolume failed: %08x\n", hr);
1775 
1776     hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
1777     ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1778     ok(fabsf(vol - 0.2f) < 0.05f, "Master volume wasn't 0.2: %f\n", vol);
1779 
1780     hr = ISimpleAudioVolume_GetMute(sav, NULL);
1781     ok(hr == NULL_PTR_ERR, "GetMute gave wrong error: %08x\n", hr);
1782 
1783     mute = TRUE;
1784     hr = ISimpleAudioVolume_GetMute(sav, &mute);
1785     ok(hr == S_OK, "GetMute failed: %08x\n", hr);
1786     ok(mute == FALSE, "Session is already muted\n");
1787 
1788     hr = ISimpleAudioVolume_SetMute(sav, TRUE, NULL);
1789     ok(hr == S_OK, "SetMute failed: %08x\n", hr);
1790 
1791     mute = FALSE;
1792     hr = ISimpleAudioVolume_GetMute(sav, &mute);
1793     ok(hr == S_OK, "GetMute failed: %08x\n", hr);
1794     ok(mute == TRUE, "Session should have been muted\n");
1795 
1796     hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
1797     ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1798     ok(fabsf(vol - 0.2f) < 0.05f, "Master volume wasn't 0.2: %f\n", vol);
1799 
1800     hr = ISimpleAudioVolume_SetMasterVolume(sav, 1.f, NULL);
1801     ok(hr == S_OK, "SetMasterVolume failed: %08x\n", hr);
1802 
1803     mute = FALSE;
1804     hr = ISimpleAudioVolume_GetMute(sav, &mute);
1805     ok(hr == S_OK, "GetMute failed: %08x\n", hr);
1806     ok(mute == TRUE, "Session should have been muted\n");
1807 
1808     hr = ISimpleAudioVolume_SetMute(sav, FALSE, NULL);
1809     ok(hr == S_OK, "SetMute failed: %08x\n", hr);
1810 
1811     ISimpleAudioVolume_Release(sav);
1812     IAudioClient_Release(ac);
1813     CoTaskMemFree(fmt);
1814 }
1815 
1816 static void test_volume_dependence(void)
1817 {
1818     IAudioClient *ac, *ac2;
1819     ISimpleAudioVolume *sav;
1820     IChannelAudioVolume *cav;
1821     IAudioStreamVolume *asv;
1822     WAVEFORMATEX *fmt;
1823     HRESULT hr;
1824     float vol;
1825     GUID session;
1826     UINT32 nch;
1827 
1828     hr = CoCreateGuid(&session);
1829     ok(hr == S_OK, "CoCreateGuid failed: %08x\n", hr);
1830 
1831     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1832             NULL, (void**)&ac);
1833     ok(hr == S_OK, "Activation failed with %08x\n", hr);
1834     if(hr != S_OK)
1835         return;
1836 
1837     hr = IAudioClient_GetMixFormat(ac, &fmt);
1838     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
1839 
1840     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
1841             AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, &session);
1842     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1843 
1844     if(hr == S_OK){
1845         hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
1846         ok(hr == S_OK, "GetService (SimpleAudioVolume) failed: %08x\n", hr);
1847     }
1848     if(hr != S_OK){
1849         IAudioClient_Release(ac);
1850         CoTaskMemFree(fmt);
1851         return;
1852     }
1853 
1854     hr = IAudioClient_GetService(ac, &IID_IChannelAudioVolume, (void**)&cav);
1855     ok(hr == S_OK, "GetService (ChannelAudioVolume) failed: %08x\n", hr);
1856 
1857     hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&asv);
1858     ok(hr == S_OK, "GetService (AudioStreamVolume) failed: %08x\n", hr);
1859 
1860     hr = IAudioStreamVolume_SetChannelVolume(asv, 0, 0.2f);
1861     ok(hr == S_OK, "ASV_SetChannelVolume failed: %08x\n", hr);
1862 
1863     hr = IChannelAudioVolume_SetChannelVolume(cav, 0, 0.4f, NULL);
1864     ok(hr == S_OK, "CAV_SetChannelVolume failed: %08x\n", hr);
1865 
1866     hr = ISimpleAudioVolume_SetMasterVolume(sav, 0.6f, NULL);
1867     ok(hr == S_OK, "SAV_SetMasterVolume failed: %08x\n", hr);
1868 
1869     hr = IAudioStreamVolume_GetChannelVolume(asv, 0, &vol);
1870     ok(hr == S_OK, "ASV_GetChannelVolume failed: %08x\n", hr);
1871     ok(fabsf(vol - 0.2f) < 0.05f, "ASV_GetChannelVolume gave wrong volume: %f\n", vol);
1872 
1873     hr = IChannelAudioVolume_GetChannelVolume(cav, 0, &vol);
1874     ok(hr == S_OK, "CAV_GetChannelVolume failed: %08x\n", hr);
1875     ok(fabsf(vol - 0.4f) < 0.05f, "CAV_GetChannelVolume gave wrong volume: %f\n", vol);
1876 
1877     hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
1878     ok(hr == S_OK, "SAV_GetMasterVolume failed: %08x\n", hr);
1879     ok(fabsf(vol - 0.6f) < 0.05f, "SAV_GetMasterVolume gave wrong volume: %f\n", vol);
1880 
1881     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
1882             NULL, (void**)&ac2);
1883     ok(hr == S_OK, "Activation failed with %08x\n", hr);
1884 
1885     if(hr == S_OK){
1886         hr = IAudioClient_Initialize(ac2, AUDCLNT_SHAREMODE_SHARED,
1887                 AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, &session);
1888         ok(hr == S_OK, "Initialize failed: %08x\n", hr);
1889         if(hr != S_OK)
1890             IAudioClient_Release(ac2);
1891     }
1892 
1893     if(hr == S_OK){
1894         IChannelAudioVolume *cav2;
1895         IAudioStreamVolume *asv2;
1896 
1897         hr = IAudioClient_GetService(ac2, &IID_IChannelAudioVolume, (void**)&cav2);
1898         ok(hr == S_OK, "GetService failed: %08x\n", hr);
1899 
1900         hr = IAudioClient_GetService(ac2, &IID_IAudioStreamVolume, (void**)&asv2);
1901         ok(hr == S_OK, "GetService failed: %08x\n", hr);
1902 
1903         hr = IChannelAudioVolume_GetChannelVolume(cav2, 0, &vol);
1904         ok(hr == S_OK, "CAV_GetChannelVolume failed: %08x\n", hr);
1905         ok(fabsf(vol - 0.4f) < 0.05f, "CAV_GetChannelVolume gave wrong volume: %f\n", vol);
1906 
1907         hr = IAudioStreamVolume_GetChannelVolume(asv2, 0, &vol);
1908         ok(hr == S_OK, "ASV_GetChannelVolume failed: %08x\n", hr);
1909         ok(vol == 1.f, "ASV_GetChannelVolume gave wrong volume: %f\n", vol);
1910 
1911         hr = IChannelAudioVolume_GetChannelCount(cav2, &nch);
1912         ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1913         ok(nch == fmt->nChannels, "Got wrong channel count, expected %u: %u\n", fmt->nChannels, nch);
1914 
1915         hr = IAudioStreamVolume_GetChannelCount(asv2, &nch);
1916         ok(hr == S_OK, "GetChannelCount failed: %08x\n", hr);
1917         ok(nch == fmt->nChannels, "Got wrong channel count, expected %u: %u\n", fmt->nChannels, nch);
1918 
1919         IAudioStreamVolume_Release(asv2);
1920         IChannelAudioVolume_Release(cav2);
1921         IAudioClient_Release(ac2);
1922     }else
1923         skip("Unable to open the same device twice. Skipping session volume control tests\n");
1924 
1925     hr = IChannelAudioVolume_SetChannelVolume(cav, 0, 1.f, NULL);
1926     ok(hr == S_OK, "CAV_SetChannelVolume failed: %08x\n", hr);
1927 
1928     hr = ISimpleAudioVolume_SetMasterVolume(sav, 1.f, NULL);
1929     ok(hr == S_OK, "SAV_SetMasterVolume failed: %08x\n", hr);
1930 
1931     CoTaskMemFree(fmt);
1932     ISimpleAudioVolume_Release(sav);
1933     IChannelAudioVolume_Release(cav);
1934     IAudioStreamVolume_Release(asv);
1935     IAudioClient_Release(ac);
1936 }
1937 
1938 static void test_session_creation(void)
1939 {
1940     IMMDevice *cap_dev;
1941     IAudioClient *ac;
1942     IAudioSessionManager *sesm;
1943     ISimpleAudioVolume *sav;
1944     GUID session_guid;
1945     float vol;
1946     HRESULT hr;
1947     WAVEFORMATEX *fmt;
1948 
1949     CoCreateGuid(&session_guid);
1950 
1951     hr = IMMDevice_Activate(dev, &IID_IAudioSessionManager,
1952             CLSCTX_INPROC_SERVER, NULL, (void**)&sesm);
1953     ok((hr == S_OK)^(sesm == NULL), "Activate %08x &out pointer\n", hr);
1954     ok(hr == S_OK, "Activate failed: %08x\n", hr);
1955 
1956     hr = IAudioSessionManager_GetSimpleAudioVolume(sesm, &session_guid,
1957             FALSE, &sav);
1958     ok(hr == S_OK, "GetSimpleAudioVolume failed: %08x\n", hr);
1959 
1960     hr = ISimpleAudioVolume_SetMasterVolume(sav, 0.6f, NULL);
1961     ok(hr == S_OK, "SetMasterVolume failed: %08x\n", hr);
1962 
1963     /* Release completely to show session persistence */
1964     ISimpleAudioVolume_Release(sav);
1965     IAudioSessionManager_Release(sesm);
1966 
1967     /* test if we can create a capture audioclient in the session we just
1968      * created from a SessionManager derived from a render device */
1969     hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme, eCapture,
1970             eMultimedia, &cap_dev);
1971     if(hr == S_OK){
1972         WAVEFORMATEX *cap_pwfx;
1973         IAudioClient *cap_ac;
1974         ISimpleAudioVolume *cap_sav;
1975         IAudioSessionManager *cap_sesm;
1976 
1977         hr = IMMDevice_Activate(cap_dev, &IID_IAudioSessionManager,
1978                 CLSCTX_INPROC_SERVER, NULL, (void**)&cap_sesm);
1979         ok((hr == S_OK)^(cap_sesm == NULL), "Activate %08x &out pointer\n", hr);
1980         ok(hr == S_OK, "Activate failed: %08x\n", hr);
1981 
1982         hr = IAudioSessionManager_GetSimpleAudioVolume(cap_sesm, &session_guid,
1983                 FALSE, &cap_sav);
1984         ok(hr == S_OK, "GetSimpleAudioVolume failed: %08x\n", hr);
1985 
1986         vol = 0.5f;
1987         hr = ISimpleAudioVolume_GetMasterVolume(cap_sav, &vol);
1988         ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
1989 
1990         ISimpleAudioVolume_Release(cap_sav);
1991         IAudioSessionManager_Release(cap_sesm);
1992 
1993         hr = IMMDevice_Activate(cap_dev, &IID_IAudioClient,
1994                 CLSCTX_INPROC_SERVER, NULL, (void**)&cap_ac);
1995         ok(hr == S_OK, "Activate failed: %08x\n", hr);
1996 
1997         IMMDevice_Release(cap_dev);
1998 
1999         hr = IAudioClient_GetMixFormat(cap_ac, &cap_pwfx);
2000         ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
2001 
2002         hr = IAudioClient_Initialize(cap_ac, AUDCLNT_SHAREMODE_SHARED,
2003                 0, 5000000, 0, cap_pwfx, &session_guid);
2004         ok(hr == S_OK, "Initialize failed: %08x\n", hr);
2005 
2006         CoTaskMemFree(cap_pwfx);
2007 
2008         if(hr == S_OK){
2009             hr = IAudioClient_GetService(cap_ac, &IID_ISimpleAudioVolume,
2010                     (void**)&cap_sav);
2011             ok(hr == S_OK, "GetService failed: %08x\n", hr);
2012         }
2013         if(hr == S_OK){
2014             vol = 0.5f;
2015             hr = ISimpleAudioVolume_GetMasterVolume(cap_sav, &vol);
2016             ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
2017 
2018             ISimpleAudioVolume_Release(cap_sav);
2019         }
2020 
2021         IAudioClient_Release(cap_ac);
2022     }
2023 
2024     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
2025             NULL, (void**)&ac);
2026     ok((hr == S_OK)^(ac == NULL), "Activate %08x &out pointer\n", hr);
2027     ok(hr == S_OK, "Activation failed with %08x\n", hr);
2028     if(hr != S_OK)
2029         return;
2030 
2031     hr = IAudioClient_GetMixFormat(ac, &fmt);
2032     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
2033 
2034     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
2035             AUDCLNT_STREAMFLAGS_NOPERSIST, 5000000, 0, fmt, &session_guid);
2036     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
2037 
2038     hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
2039     ok(hr == S_OK, "GetService failed: %08x\n", hr);
2040     if(hr == S_OK){
2041         vol = 0.5f;
2042         hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol);
2043         ok(hr == S_OK, "GetMasterVolume failed: %08x\n", hr);
2044         ok(fabs(vol - 0.6f) < 0.05f, "Got wrong volume: %f\n", vol);
2045 
2046         ISimpleAudioVolume_Release(sav);
2047     }
2048 
2049     CoTaskMemFree(fmt);
2050     IAudioClient_Release(ac);
2051 }
2052 
2053 static void test_worst_case(void)
2054 {
2055     HANDLE event;
2056     HRESULT hr;
2057     IAudioClient *ac;
2058     IAudioRenderClient *arc;
2059     IAudioClock *acl;
2060     WAVEFORMATEX *pwfx;
2061     REFERENCE_TIME defp;
2062     UINT64 freq, pos, pcpos0, pcpos;
2063     BYTE *data;
2064     DWORD r;
2065     UINT32 pad, fragment, sum;
2066     int i,j;
2067 
2068     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
2069             NULL, (void**)&ac);
2070     ok(hr == S_OK, "Activation failed with %08x\n", hr);
2071     if(hr != S_OK)
2072         return;
2073 
2074     hr = IAudioClient_GetMixFormat(ac, &pwfx);
2075     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
2076 
2077     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
2078             AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 500000, 0, pwfx, NULL);
2079     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
2080     if(hr != S_OK)
2081         return;
2082 
2083     hr = IAudioClient_GetDevicePeriod(ac, &defp, NULL);
2084     ok(hr == S_OK, "GetDevicePeriod failed: %08x\n", hr);
2085 
2086     fragment  =  MulDiv(defp,   pwfx->nSamplesPerSec, 10000000);
2087 
2088     event = CreateEventW(NULL, FALSE, FALSE, NULL);
2089     ok(event != NULL, "CreateEvent failed\n");
2090 
2091     hr = IAudioClient_SetEventHandle(ac, event);
2092     ok(hr == S_OK, "SetEventHandle failed: %08x\n", hr);
2093 
2094     hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&arc);
2095     ok(hr == S_OK, "GetService(IAudioRenderClient) failed: %08x\n", hr);
2096 
2097     hr = IAudioClient_GetService(ac, &IID_IAudioClock, (void**)&acl);
2098     ok(hr == S_OK, "GetService(IAudioClock) failed: %08x\n", hr);
2099 
2100     hr = IAudioClock_GetFrequency(acl, &freq);
2101     ok(hr == S_OK, "GetFrequency failed: %08x\n", hr);
2102 
2103     for(j = 0; j <= (winetest_interactive ? 9 : 2); j++){
2104         sum = 0;
2105         trace("Should play %ums continuous tone with fragment size %u.\n",
2106               (ULONG)(defp/100), fragment);
2107 
2108         hr = IAudioClock_GetPosition(acl, &pos, &pcpos0);
2109         ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
2110 
2111         /* XAudio2 prefills one period, play without it */
2112         if(winetest_debug>2){
2113             hr = IAudioRenderClient_GetBuffer(arc, fragment, &data);
2114             ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
2115 
2116             hr = IAudioRenderClient_ReleaseBuffer(arc, fragment, AUDCLNT_BUFFERFLAGS_SILENT);
2117             ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
2118             if(hr == S_OK)
2119                 sum += fragment;
2120         }
2121 
2122         hr = IAudioClient_Start(ac);
2123         ok(hr == S_OK, "Start failed: %08x\n", hr);
2124 
2125         for(i = 0; i <= 99; i++){ /* 100 x 10ms = 1 second */
2126             r = WaitForSingleObject(event, 60 + defp / 10000);
2127             ok(r == WAIT_OBJECT_0, "Wait iteration %d gave %x\n", i, r);
2128 
2129             /* the app has nearly one period time to feed data */
2130             Sleep((i % 10) * defp / 120000);
2131 
2132             hr = IAudioClient_GetCurrentPadding(ac, &pad);
2133             ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
2134 
2135             /* XAudio2 writes only when there's little data left */
2136             if(pad <= fragment){
2137                 hr = IAudioRenderClient_GetBuffer(arc, fragment, &data);
2138                 ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
2139 
2140                 hr = IAudioRenderClient_ReleaseBuffer(arc, fragment,
2141                        wave_generate_tone(pwfx, data, fragment));
2142                 ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
2143                 if(hr == S_OK)
2144                     sum += fragment;
2145             }
2146         }
2147 
2148         hr = IAudioClient_Stop(ac);
2149         ok(hr == S_OK, "Stop failed: %08x\n", hr);
2150 
2151         hr = IAudioClient_GetCurrentPadding(ac, &pad);
2152         ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
2153 
2154         hr = IAudioClock_GetPosition(acl, &pos, &pcpos);
2155         ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
2156 
2157         Sleep(100);
2158 
2159         trace("Released %u=%ux%u -%u frames at %u worth %ums in %ums\n",
2160               sum, sum/fragment, fragment, pad,
2161               pwfx->nSamplesPerSec, MulDiv(sum-pad, 1000, pwfx->nSamplesPerSec),
2162               (ULONG)((pcpos-pcpos0)/10000));
2163 
2164         ok(pos * pwfx->nSamplesPerSec == (sum-pad) * freq,
2165            "Position %u at end vs. %u-%u submitted frames\n", (UINT)pos, sum, pad);
2166 
2167         hr = IAudioClient_Reset(ac);
2168         ok(hr == S_OK, "Reset failed: %08x\n", hr);
2169 
2170         Sleep(250);
2171     }
2172 
2173     CoTaskMemFree(pwfx);
2174     IAudioClient_Release(ac);
2175     IAudioClock_Release(acl);
2176     IAudioRenderClient_Release(arc);
2177 }
2178 
2179 static void test_marshal(void)
2180 {
2181     IStream *pStream;
2182     IAudioClient *ac, *acDest;
2183     IAudioRenderClient *rc, *rcDest;
2184     WAVEFORMATEX *pwfx;
2185     HRESULT hr;
2186 
2187     /* IAudioRenderClient */
2188     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
2189             NULL, (void**)&ac);
2190     ok(hr == S_OK, "Activation failed with %08x\n", hr);
2191     if(hr != S_OK)
2192         return;
2193 
2194     hr = IAudioClient_GetMixFormat(ac, &pwfx);
2195     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
2196 
2197     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
2198             0, pwfx, NULL);
2199     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
2200 
2201     CoTaskMemFree(pwfx);
2202 
2203     hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&rc);
2204     ok(hr == S_OK, "GetService failed: %08x\n", hr);
2205     if(hr != S_OK) {
2206         IAudioClient_Release(ac);
2207         return;
2208     }
2209 
2210     hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
2211     ok(hr == S_OK, "CreateStreamOnHGlobal failed 0x%08x\n", hr);
2212 
2213     /* marshal IAudioClient */
2214 
2215     hr = CoMarshalInterface(pStream, &IID_IAudioClient, (IUnknown*)ac, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
2216     ok(hr == S_OK, "CoMarshalInterface IAudioClient failed 0x%08x\n", hr);
2217 
2218     IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2219     hr = CoUnmarshalInterface(pStream, &IID_IAudioClient, (void **)&acDest);
2220     ok(hr == S_OK, "CoUnmarshalInterface IAudioClient failed 0x%08x\n", hr);
2221     if (hr == S_OK)
2222         IAudioClient_Release(acDest);
2223 
2224     IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2225     /* marshal IAudioRenderClient */
2226 
2227     hr = CoMarshalInterface(pStream, &IID_IAudioRenderClient, (IUnknown*)rc, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
2228     ok(hr == S_OK, "CoMarshalInterface IAudioRenderClient failed 0x%08x\n", hr);
2229 
2230     IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
2231     hr = CoUnmarshalInterface(pStream, &IID_IAudioRenderClient, (void **)&rcDest);
2232     ok(hr == S_OK, "CoUnmarshalInterface IAudioRenderClient failed 0x%08x\n", hr);
2233     if (hr == S_OK)
2234         IAudioRenderClient_Release(rcDest);
2235 
2236 
2237     IStream_Release(pStream);
2238 
2239     IAudioClient_Release(ac);
2240     IAudioRenderClient_Release(rc);
2241 
2242 }
2243 
2244 static void test_endpointvolume(void)
2245 {
2246     HRESULT hr;
2247     IAudioEndpointVolume *aev;
2248     float mindb, maxdb, increment, volume;
2249     BOOL mute;
2250 
2251     hr = IMMDevice_Activate(dev, &IID_IAudioEndpointVolume,
2252             CLSCTX_INPROC_SERVER, NULL, (void**)&aev);
2253     ok(hr == S_OK, "Activation failed with %08x\n", hr);
2254     if(hr != S_OK)
2255         return;
2256 
2257     hr = IAudioEndpointVolume_GetVolumeRange(aev, &mindb, NULL, NULL);
2258     ok(hr == E_POINTER, "GetVolumeRange should have failed with E_POINTER: 0x%08x\n", hr);
2259 
2260     hr = IAudioEndpointVolume_GetVolumeRange(aev, &mindb, &maxdb, &increment);
2261     ok(hr == S_OK, "GetVolumeRange failed: 0x%08x\n", hr);
2262     trace("got range: [%f,%f]/%f\n", mindb, maxdb, increment);
2263 
2264     hr = IAudioEndpointVolume_SetMasterVolumeLevel(aev, mindb - increment, NULL);
2265     ok(hr == E_INVALIDARG, "SetMasterVolumeLevel failed: 0x%08x\n", hr);
2266 
2267     hr = IAudioEndpointVolume_GetMasterVolumeLevel(aev, &volume);
2268     ok(hr == S_OK, "GetMasterVolumeLevel failed: 0x%08x\n", hr);
2269 
2270     hr = IAudioEndpointVolume_SetMasterVolumeLevel(aev, volume, NULL);
2271     ok(hr == S_OK, "SetMasterVolumeLevel failed: 0x%08x\n", hr);
2272 
2273     hr = IAudioEndpointVolume_GetMute(aev, &mute);
2274     ok(hr == S_OK, "GetMute failed: %08x\n", hr);
2275 
2276     hr = IAudioEndpointVolume_SetMute(aev, mute, NULL);
2277     ok(hr == S_OK || hr == S_FALSE, "SetMute failed: %08x\n", hr);
2278 
2279     IAudioEndpointVolume_Release(aev);
2280 }
2281 
2282 START_TEST(render)
2283 {
2284     HRESULT hr;
2285 
2286     CoInitializeEx(NULL, COINIT_MULTITHREADED);
2287     hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme);
2288     if (FAILED(hr))
2289     {
2290         skip("mmdevapi not available: 0x%08x\n", hr);
2291         goto cleanup;
2292     }
2293 
2294     hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme, eRender, eMultimedia, &dev);
2295     ok(hr == S_OK || hr == E_NOTFOUND, "GetDefaultAudioEndpoint failed: 0x%08x\n", hr);
2296     if (hr != S_OK || !dev)
2297     {
2298         if (hr == E_NOTFOUND)
2299             skip("No sound card available\n");
2300         else
2301             skip("GetDefaultAudioEndpoint returns 0x%08x\n", hr);
2302         goto cleanup;
2303     }
2304 
2305     test_audioclient();
2306     test_formats(AUDCLNT_SHAREMODE_EXCLUSIVE);
2307     test_formats(AUDCLNT_SHAREMODE_SHARED);
2308     test_references();
2309     test_marshal();
2310     trace("Output to a MS-DOS console is particularly slow and disturbs timing.\n");
2311     trace("Please redirect output to a file.\n");
2312     test_event();
2313     test_padding();
2314     test_clock(1);
2315     test_clock(0);
2316     test_session();
2317     test_streamvolume();
2318     test_channelvolume();
2319     test_simplevolume();
2320     test_volume_dependence();
2321     test_session_creation();
2322     test_worst_case();
2323     test_endpointvolume();
2324 
2325     IMMDevice_Release(dev);
2326 
2327 cleanup:
2328     if (mme)
2329         IMMDeviceEnumerator_Release(mme);
2330     CoUninitialize();
2331 }
2332