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 #include "unknwn.h"
33 #include "uuids.h"
34 #include "mmdeviceapi.h"
35 #include "mmsystem.h"
36 #include "audioclient.h"
37 #include "audiopolicy.h"
38 #include "initguid.h"
39 #include "endpointvolume.h"
40 
41 static const unsigned int win_formats[][4] = {
42     { 8000,  8, 1},   { 8000,  8, 2},   { 8000, 16, 1},   { 8000, 16, 2},
43     {11025,  8, 1},   {11025,  8, 2},   {11025, 16, 1},   {11025, 16, 2},
44     {12000,  8, 1},   {12000,  8, 2},   {12000, 16, 1},   {12000, 16, 2},
45     {16000,  8, 1},   {16000,  8, 2},   {16000, 16, 1},   {16000, 16, 2},
46     {22050,  8, 1},   {22050,  8, 2},   {22050, 16, 1},   {22050, 16, 2},
47     {44100,  8, 1},   {44100,  8, 2},   {44100, 16, 1},   {44100, 16, 2},
48     {48000,  8, 1},   {48000,  8, 2},   {48000, 16, 1},   {48000, 16, 2},
49     {96000,  8, 1},   {96000,  8, 2},   {96000, 16, 1},   {96000, 16, 2}
50 };
51 #define NB_WIN_FORMATS (sizeof(win_formats)/sizeof(*win_formats))
52 
53 #define NULL_PTR_ERR MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, RPC_X_NULL_REF_POINTER)
54 
55 /* undocumented error code */
56 #define D3D11_ERROR_4E MAKE_HRESULT(SEVERITY_ERROR, FACILITY_DIRECT3D11, 0x4e)
57 
58 static IMMDeviceEnumerator *mme = NULL;
59 static IMMDevice *dev = NULL;
60 static HRESULT hexcl = S_OK; /* or AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED */
61 static BOOL win10 = FALSE;
62 
63 static const LARGE_INTEGER ullZero;
64 
65 #define PI 3.14159265358979323846L
66 static DWORD wave_generate_tone(PWAVEFORMATEX pwfx, BYTE* data, UINT32 frames)
67 {
68     static double phase = 0.; /* normalized to unit, not 2*PI */
69     PWAVEFORMATEXTENSIBLE wfxe = (PWAVEFORMATEXTENSIBLE)pwfx;
70     DWORD cn, i;
71     double delta, y;
72 
73     if(!winetest_interactive)
74         return AUDCLNT_BUFFERFLAGS_SILENT;
75     if(wfxe->Format.wBitsPerSample != ((wfxe->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
76        IsEqualGUID(&wfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) ? 8 * sizeof(float) : 16))
77         return AUDCLNT_BUFFERFLAGS_SILENT;
78 
79     for(delta = phase, cn = 0; cn < wfxe->Format.nChannels;
80         delta += .5/wfxe->Format.nChannels, cn++){
81         for(i = 0; i < frames; i++){
82             y = sin(2*PI*(440.* i / wfxe->Format.nSamplesPerSec + delta));
83             /* assume alignment is granted */
84             if(wfxe->Format.wBitsPerSample == 16)
85                 ((short*)data)[cn+i*wfxe->Format.nChannels] = y * 32767.9;
86             else
87                 ((float*)data)[cn+i*wfxe->Format.nChannels] = y;
88         }
89     }
90     phase += 440.* frames / wfxe->Format.nSamplesPerSec;
91     phase -= floor(phase);
92     return 0;
93 }
94 
95 static void test_uninitialized(IAudioClient *ac)
96 {
97     HRESULT hr;
98     UINT32 num;
99     REFERENCE_TIME t1;
100 
101     HANDLE handle = CreateEventW(NULL, FALSE, FALSE, NULL);
102     IUnknown *unk;
103 
104     hr = IAudioClient_GetBufferSize(ac, &num);
105     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetBufferSize call returns %08x\n", hr);
106 
107     hr = IAudioClient_GetStreamLatency(ac, &t1);
108     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetStreamLatency call returns %08x\n", hr);
109 
110     hr = IAudioClient_GetCurrentPadding(ac, &num);
111     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetCurrentPadding call returns %08x\n", hr);
112 
113     hr = IAudioClient_Start(ac);
114     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized Start call returns %08x\n", hr);
115 
116     hr = IAudioClient_Stop(ac);
117     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized Stop call returns %08x\n", hr);
118 
119     hr = IAudioClient_Reset(ac);
120     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized Reset call returns %08x\n", hr);
121 
122     hr = IAudioClient_SetEventHandle(ac, handle);
123     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized SetEventHandle call returns %08x\n", hr);
124 
125     hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&unk);
126     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Uninitialized GetService call returns %08x\n", hr);
127 
128     CloseHandle(handle);
129 }
130 
131 static void test_audioclient(void)
132 {
133     IAudioClient *ac;
134     IUnknown *unk;
135     HRESULT hr;
136     ULONG ref;
137     WAVEFORMATEX *pwfx, *pwfx2;
138     REFERENCE_TIME t1, t2;
139     HANDLE handle;
140 
141     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
142             NULL, (void**)&ac);
143     ok(hr == S_OK, "Activation failed with %08x\n", hr);
144     if(hr != S_OK)
145         return;
146 
147     handle = CreateEventW(NULL, FALSE, FALSE, NULL);
148 
149     hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, NULL);
150     ok(hr == E_POINTER, "QueryInterface(NULL) returned %08x\n", hr);
151 
152     unk = (void*)(LONG_PTR)0x12345678;
153     hr = IAudioClient_QueryInterface(ac, &IID_NULL, (void**)&unk);
154     ok(hr == E_NOINTERFACE, "QueryInterface(IID_NULL) returned %08x\n", hr);
155     ok(!unk, "QueryInterface(IID_NULL) returned non-null pointer %p\n", unk);
156 
157     hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, (void**)&unk);
158     ok(hr == S_OK, "QueryInterface(IID_IUnknown) returned %08x\n", hr);
159     if (unk)
160     {
161         ref = IUnknown_Release(unk);
162         ok(ref == 1, "Released count is %u\n", ref);
163     }
164 
165     hr = IAudioClient_QueryInterface(ac, &IID_IAudioClient, (void**)&unk);
166     ok(hr == S_OK, "QueryInterface(IID_IAudioClient) returned %08x\n", hr);
167     if (unk)
168     {
169         ref = IUnknown_Release(unk);
170         ok(ref == 1, "Released count is %u\n", ref);
171     }
172 
173     hr = IAudioClient_GetDevicePeriod(ac, NULL, NULL);
174     ok(hr == E_POINTER, "Invalid GetDevicePeriod call returns %08x\n", hr);
175 
176     hr = IAudioClient_GetDevicePeriod(ac, &t1, NULL);
177     ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr);
178 
179     hr = IAudioClient_GetDevicePeriod(ac, NULL, &t2);
180     ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr);
181 
182     hr = IAudioClient_GetDevicePeriod(ac, &t1, &t2);
183     ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr);
184     trace("Returned periods: %u.%04u ms %u.%04u ms\n",
185           (UINT)(t1/10000), (UINT)(t1 % 10000),
186           (UINT)(t2/10000), (UINT)(t2 % 10000));
187 
188     hr = IAudioClient_GetMixFormat(ac, NULL);
189     ok(hr == E_POINTER, "GetMixFormat returns %08x\n", hr);
190 
191     hr = IAudioClient_GetMixFormat(ac, &pwfx);
192     ok(hr == S_OK, "Valid GetMixFormat returns %08x\n", hr);
193 
194     if (hr == S_OK)
195     {
196         trace("pwfx: %p\n", pwfx);
197         trace("Tag: %04x\n", pwfx->wFormatTag);
198         trace("bits: %u\n", pwfx->wBitsPerSample);
199         trace("chan: %u\n", pwfx->nChannels);
200         trace("rate: %u\n", pwfx->nSamplesPerSec);
201         trace("align: %u\n", pwfx->nBlockAlign);
202         trace("extra: %u\n", pwfx->cbSize);
203         ok(pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE, "wFormatTag is %x\n", pwfx->wFormatTag);
204         if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
205         {
206             WAVEFORMATEXTENSIBLE *pwfxe = (void*)pwfx;
207             trace("Res: %u\n", pwfxe->Samples.wReserved);
208             trace("Mask: %x\n", pwfxe->dwChannelMask);
209             trace("Alg: %s\n",
210                   IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)?"PCM":
211                   (IsEqualGUID(&pwfxe->SubFormat,
212                                &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)?"FLOAT":"Other"));
213         }
214 
215         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
216         ok(hr == S_OK, "Valid IsFormatSupported(Shared) call returns %08x\n", hr);
217         ok(pwfx2 == NULL, "pwfx2 is non-null\n");
218         CoTaskMemFree(pwfx2);
219 
220         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, NULL, NULL);
221         ok(hr == E_POINTER, "IsFormatSupported(NULL) call returns %08x\n", hr);
222 
223         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, NULL);
224         ok(hr == E_POINTER, "IsFormatSupported(Shared,NULL) call returns %08x\n", hr);
225 
226         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
227         ok(hr == S_OK || hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED,
228            "IsFormatSupported(Exclusive) call returns %08x\n", hr);
229         hexcl = hr;
230 
231         pwfx2 = (WAVEFORMATEX*)0xDEADF00D;
232         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, &pwfx2);
233         ok(hr == hexcl, "IsFormatSupported(Exclusive) call returns %08x\n", hr);
234         ok(pwfx2 == NULL, "pwfx2 non-null on exclusive IsFormatSupported\n");
235 
236         if (hexcl != AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED)
237             hexcl = S_OK;
238 
239         hr = IAudioClient_IsFormatSupported(ac, 0xffffffff, pwfx, NULL);
240         ok(hr == E_INVALIDARG/*w32*/ ||
241            broken(hr == AUDCLNT_E_UNSUPPORTED_FORMAT/*w64 response from exclusive mode driver */),
242            "IsFormatSupported(0xffffffff) call returns %08x\n", hr);
243     }
244 
245     test_uninitialized(ac);
246 
247     hr = IAudioClient_Initialize(ac, 3, 0, 5000000, 0, pwfx, NULL);
248     ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Initialize with invalid sharemode returns %08x\n", hr);
249 
250     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0xffffffff, 5000000, 0, pwfx, NULL);
251     ok(hr == E_INVALIDARG ||
252             hr == AUDCLNT_E_INVALID_STREAM_FLAG, "Initialize with invalid flags returns %08x\n", hr);
253 
254     /* A period != 0 is ignored and the call succeeds.
255      * Since we can only initialize successfully once, skip those tests.
256      */
257     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, NULL, NULL);
258     ok(hr == E_POINTER, "Initialize with null format returns %08x\n", hr);
259 
260     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 0, 0, pwfx, NULL);
261     ok(hr == S_OK, "Initialize with 0 buffer size returns %08x\n", hr);
262     if(hr == S_OK){
263         UINT32 num;
264 
265         hr = IAudioClient_GetBufferSize(ac, &num);
266         ok(hr == S_OK, "GetBufferSize from duration 0 returns %08x\n", hr);
267         if(hr == S_OK)
268             trace("Initialize(duration=0) GetBufferSize is %u\n", num);
269     }
270 
271     IAudioClient_Release(ac);
272 
273     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
274             NULL, (void**)&ac);
275     ok(hr == S_OK, "Activation failed with %08x\n", hr);
276 
277     if(pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE){
278         WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE*)pwfx;
279         WAVEFORMATEX *fmt2 = NULL;
280 
281         ok(fmtex->dwChannelMask != 0, "Got empty dwChannelMask\n");
282 
283         fmtex->dwChannelMask = 0xffff;
284 
285         hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL);
286         ok(hr == S_OK ||
287                 hr == AUDCLNT_E_UNSUPPORTED_FORMAT /* win10 */, "Initialize(dwChannelMask = 0xffff) returns %08x\n", hr);
288 
289         IAudioClient_Release(ac);
290 
291         hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
292                 NULL, (void**)&ac);
293         ok(hr == S_OK, "Activation failed with %08x\n", hr);
294 
295         fmtex->dwChannelMask = 0;
296 
297         hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &fmt2);
298         ok(hr == S_OK || broken(hr == S_FALSE /* w7 Realtek HDA */),
299            "IsFormatSupported(dwChannelMask = 0) call returns %08x\n", hr);
300         ok(fmtex->dwChannelMask == 0, "Passed format was modified\n");
301 
302         CoTaskMemFree(fmt2);
303 
304         hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL);
305         ok(hr == S_OK, "Initialize(dwChannelMask = 0) returns %08x\n", hr);
306 
307         IAudioClient_Release(ac);
308 
309         hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
310                 NULL, (void**)&ac);
311         ok(hr == S_OK, "Activation failed with %08x\n", hr);
312 
313         CoTaskMemFree(pwfx);
314 
315         hr = IAudioClient_GetMixFormat(ac, &pwfx);
316         ok(hr == S_OK, "Valid GetMixFormat returns %08x\n", hr);
317     }else
318         skip("Skipping dwChannelMask tests\n");
319 
320     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL);
321     ok(hr == S_OK, "Valid Initialize returns %08x\n", hr);
322     if (hr != S_OK)
323     {
324         IAudioClient_Release(ac);
325         CoTaskMemFree(pwfx);
326         return;
327     }
328 
329     hr = IAudioClient_GetStreamLatency(ac, NULL);
330     ok(hr == E_POINTER, "GetStreamLatency(NULL) call returns %08x\n", hr);
331 
332     hr = IAudioClient_GetStreamLatency(ac, &t2);
333     ok(hr == S_OK, "Valid GetStreamLatency call returns %08x\n", hr);
334     trace("Returned latency: %u.%04u ms\n",
335           (UINT)(t2/10000), (UINT)(t2 % 10000));
336     ok(t2 >= t1 || broken(t2 >= t1/2 && pwfx->nSamplesPerSec > 48000) ||
337             broken(t2 == 0) /* (!) win10 */,
338        "Latency < default period, delta %dus (%x%08x vs %x%08x)\n",
339        (LONG)((t2-t1)/10), (DWORD)(t2 >> 32), (DWORD)t2, (DWORD)(t1 >> 32), (DWORD)t1);
340     /* Native appears to add the engine period to the HW latency in shared mode */
341     if(t2 == 0)
342         win10 = TRUE;
343 
344     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL);
345     ok(hr == AUDCLNT_E_ALREADY_INITIALIZED, "Calling Initialize twice returns %08x\n", hr);
346 
347     hr = IAudioClient_SetEventHandle(ac, NULL);
348     ok(hr == E_INVALIDARG, "SetEventHandle(NULL) returns %08x\n", hr);
349 
350     hr = IAudioClient_SetEventHandle(ac, handle);
351     ok(hr == AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED ||
352        broken(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME)) ||
353        broken(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) /* Some 2k8 */ ||
354        broken(hr == HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME)) /* Some Vista */
355        , "SetEventHandle returns %08x\n", hr);
356 
357     hr = IAudioClient_Reset(ac);
358     ok(hr == S_OK, "Reset on an initialized stream returns %08x\n", hr);
359 
360     hr = IAudioClient_Reset(ac);
361     ok(hr == S_OK, "Reset on an already reset stream returns %08x\n", hr);
362 
363     hr = IAudioClient_Stop(ac);
364     ok(hr == S_FALSE, "Stop on a stopped stream returns %08x\n", hr);
365 
366     hr = IAudioClient_Start(ac);
367     ok(hr == S_OK, "Start on a stopped stream returns %08x\n", hr);
368 
369     hr = IAudioClient_Start(ac);
370     ok(hr == AUDCLNT_E_NOT_STOPPED, "Start twice returns %08x\n", hr);
371 
372     IAudioClient_Release(ac);
373 
374     CloseHandle(handle);
375     CoTaskMemFree(pwfx);
376 }
377 
378 static void test_formats(AUDCLNT_SHAREMODE mode)
379 {
380     IAudioClient *ac;
381     HRESULT hr, hrs;
382     WAVEFORMATEX fmt, *pwfx, *pwfx2;
383     int i;
384 
385     fmt.wFormatTag = WAVE_FORMAT_PCM;
386     fmt.cbSize = 0;
387 
388     for(i = 0; i < NB_WIN_FORMATS; i++) {
389         hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
390                 NULL, (void**)&ac);
391         ok(hr == S_OK, "Activation failed with %08x\n", hr);
392         if(hr != S_OK)
393             continue;
394 
395         hr = IAudioClient_GetMixFormat(ac, &pwfx);
396         ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
397 
398         fmt.nSamplesPerSec = win_formats[i][0];
399         fmt.wBitsPerSample = win_formats[i][1];
400         fmt.nChannels      = win_formats[i][2];
401         fmt.nBlockAlign    = fmt.nChannels * fmt.wBitsPerSample / 8;
402         fmt.nAvgBytesPerSec= fmt.nBlockAlign * fmt.nSamplesPerSec;
403 
404         pwfx2 = (WAVEFORMATEX*)0xDEADF00D;
405         hr = IAudioClient_IsFormatSupported(ac, mode, &fmt, &pwfx2);
406         hrs = hr;
407         /* Only shared mode suggests something ... GetMixFormat! */
408         ok(hr == S_OK || (mode == AUDCLNT_SHAREMODE_SHARED
409            ? hr == S_FALSE || broken(hr == AUDCLNT_E_UNSUPPORTED_FORMAT &&
410                /* 5:1 card exception when asked for 1 channel at mixer rate */
411                pwfx->nChannels > 2 && fmt.nSamplesPerSec == pwfx->nSamplesPerSec)
412            : (hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == hexcl)),
413            "IsFormatSupported(%d, %ux%2ux%u) returns %08x\n", mode,
414            fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr);
415         if (hr == S_OK)
416             trace("IsSupported(%s, %ux%2ux%u)\n",
417                   mode == AUDCLNT_SHAREMODE_SHARED ? "shared " : "exclus.",
418                   fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels);
419 
420         /* Change GetMixFormat wBitsPerSample only => S_OK */
421         if (mode == AUDCLNT_SHAREMODE_SHARED
422             && fmt.nSamplesPerSec == pwfx->nSamplesPerSec
423             && fmt.nChannels == pwfx->nChannels)
424             ok(hr == S_OK, "Varying BitsPerSample %u\n", fmt.wBitsPerSample);
425 
426         ok((hr == S_FALSE)^(pwfx2 == NULL), "hr %x<->suggest %p\n", hr, pwfx2);
427         if (pwfx2 == (WAVEFORMATEX*)0xDEADF00D)
428             pwfx2 = NULL; /* broken in Wine < 1.3.28 */
429         if (pwfx2) {
430             ok(pwfx2->nSamplesPerSec == pwfx->nSamplesPerSec &&
431                pwfx2->nChannels      == pwfx->nChannels &&
432                pwfx2->wBitsPerSample == pwfx->wBitsPerSample,
433                "Suggestion %ux%2ux%u differs from GetMixFormat\n",
434                pwfx2->nSamplesPerSec, pwfx2->wBitsPerSample, pwfx2->nChannels);
435         }
436 
437         /* Vista returns E_INVALIDARG upon AUDCLNT_STREAMFLAGS_RATEADJUST */
438         hr = IAudioClient_Initialize(ac, mode, 0, 5000000, 0, &fmt, NULL);
439         if ((hrs == S_OK) ^ (hr == S_OK))
440             trace("Initialize (%s, %ux%2ux%u) returns %08x unlike IsFormatSupported\n",
441                   mode == AUDCLNT_SHAREMODE_SHARED ? "shared " : "exclus.",
442                   fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr);
443         if (mode == AUDCLNT_SHAREMODE_SHARED)
444             ok(hrs == S_OK ? hr == S_OK : hr == AUDCLNT_E_UNSUPPORTED_FORMAT,
445                "Initialize(shared,  %ux%2ux%u) returns %08x\n",
446                fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr);
447         else if (hrs == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED)
448             /* Unsupported format implies "create failed" and shadows "not allowed" */
449             ok(hrs == hexcl && (hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == hrs),
450                "Initialize(noexcl., %ux%2ux%u) returns %08x(%08x)\n",
451                fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr, hrs);
452         else
453             /* On testbot 48000x16x1 claims support, but does not Initialize.
454              * Some cards Initialize 44100|48000x16x1 yet claim no support;
455              * F. Gouget's w7 bots do that for 12000|96000x8|16x1|2 */
456             ok(hrs == S_OK ? hr == S_OK || broken(hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED)
457                : hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == AUDCLNT_E_UNSUPPORTED_FORMAT ||
458                  broken(hr == S_OK &&
459                      ((fmt.nChannels == 1 && fmt.wBitsPerSample == 16) ||
460                       (fmt.nSamplesPerSec == 12000 || fmt.nSamplesPerSec == 96000))),
461                "Initialize(exclus., %ux%2ux%u) returns %08x\n",
462                fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr);
463 
464         /* Bug in native (Vista/w2k8/w7): after Initialize failed, better
465          * Release this ac and Activate a new one.
466          * A second call (with a known working format) would yield
467          * ALREADY_INITIALIZED in shared mode yet be unusable, and in exclusive
468          * mode some entity keeps a lock on the device, causing DEVICE_IN_USE to
469          * all subsequent calls until the audio engine service is restarted. */
470 
471         CoTaskMemFree(pwfx2);
472         CoTaskMemFree(pwfx);
473         IAudioClient_Release(ac);
474     }
475 }
476 
477 static void test_references(void)
478 {
479     IAudioClient *ac;
480     IAudioRenderClient *rc;
481     ISimpleAudioVolume *sav;
482     IAudioStreamVolume *asv;
483     IAudioClock *acl;
484     WAVEFORMATEX *pwfx;
485     HRESULT hr;
486     ULONG ref;
487 
488     /* IAudioRenderClient */
489     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
490             NULL, (void**)&ac);
491     ok(hr == S_OK, "Activation failed with %08x\n", hr);
492     if(hr != S_OK)
493         return;
494 
495     hr = IAudioClient_GetMixFormat(ac, &pwfx);
496     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
497 
498     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
499             0, pwfx, NULL);
500     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
501 
502     CoTaskMemFree(pwfx);
503 
504     hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&rc);
505     ok(hr == S_OK, "GetService failed: %08x\n", hr);
506     if(hr != S_OK) {
507         IAudioClient_Release(ac);
508         return;
509     }
510 
511     IAudioRenderClient_AddRef(rc);
512     ref = IAudioRenderClient_Release(rc);
513     ok(ref != 0, "RenderClient_Release gave wrong refcount: %u\n", ref);
514 
515     ref = IAudioClient_Release(ac);
516     ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
517 
518     ref = IAudioRenderClient_Release(rc);
519     ok(ref == 0, "RenderClient_Release gave wrong refcount: %u\n", ref);
520 
521     /* ISimpleAudioVolume */
522     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
523             NULL, (void**)&ac);
524     ok(hr == S_OK, "Activation failed with %08x\n", hr);
525     if(hr != S_OK)
526         return;
527 
528     hr = IAudioClient_GetMixFormat(ac, &pwfx);
529     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
530 
531     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
532             0, pwfx, NULL);
533     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
534 
535     CoTaskMemFree(pwfx);
536 
537     hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
538     ok(hr == S_OK, "GetService failed: %08x\n", hr);
539 
540     ISimpleAudioVolume_AddRef(sav);
541     ref = ISimpleAudioVolume_Release(sav);
542     ok(ref != 0, "SimpleAudioVolume_Release gave wrong refcount: %u\n", ref);
543 
544     ref = IAudioClient_Release(ac);
545     ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
546 
547     ref = ISimpleAudioVolume_Release(sav);
548     ok(ref == 0, "SimpleAudioVolume_Release gave wrong refcount: %u\n", ref);
549 
550     /* IAudioClock */
551     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
552             NULL, (void**)&ac);
553     ok(hr == S_OK, "Activation failed with %08x\n", hr);
554     if(hr != S_OK)
555         return;
556 
557     hr = IAudioClient_GetMixFormat(ac, &pwfx);
558     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
559 
560     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
561             0, pwfx, NULL);
562     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
563 
564     CoTaskMemFree(pwfx);
565 
566     hr = IAudioClient_GetService(ac, &IID_IAudioClock, (void**)&acl);
567     ok(hr == S_OK, "GetService failed: %08x\n", hr);
568 
569     IAudioClock_AddRef(acl);
570     ref = IAudioClock_Release(acl);
571     ok(ref != 0, "AudioClock_Release gave wrong refcount: %u\n", ref);
572 
573     ref = IAudioClient_Release(ac);
574     ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
575 
576     ref = IAudioClock_Release(acl);
577     ok(ref == 0, "AudioClock_Release gave wrong refcount: %u\n", ref);
578 
579     /* IAudioStreamVolume */
580     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
581             NULL, (void**)&ac);
582     ok(hr == S_OK, "Activation failed with %08x\n", hr);
583     if(hr != S_OK)
584         return;
585 
586     hr = IAudioClient_GetMixFormat(ac, &pwfx);
587     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
588 
589     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
590             0, pwfx, NULL);
591     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
592 
593     CoTaskMemFree(pwfx);
594 
595     hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&asv);
596     ok(hr == S_OK, "GetService failed: %08x\n", hr);
597 
598     IAudioStreamVolume_AddRef(asv);
599     ref = IAudioStreamVolume_Release(asv);
600     ok(ref != 0, "AudioStreamVolume_Release gave wrong refcount: %u\n", ref);
601 
602     ref = IAudioClient_Release(ac);
603     ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
604 
605     ref = IAudioStreamVolume_Release(asv);
606     ok(ref == 0, "AudioStreamVolume_Release gave wrong refcount: %u\n", ref);
607 }
608 
609 static void test_event(void)
610 {
611     HANDLE event;
612     HRESULT hr;
613     DWORD r;
614     IAudioClient *ac;
615     WAVEFORMATEX *pwfx;
616 
617     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
618             NULL, (void**)&ac);
619     ok(hr == S_OK, "Activation failed with %08x\n", hr);
620     if(hr != S_OK)
621         return;
622 
623     hr = IAudioClient_GetMixFormat(ac, &pwfx);
624     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
625 
626     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
627             AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 5000000,
628             0, pwfx, NULL);
629     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
630 
631     CoTaskMemFree(pwfx);
632 
633     event = CreateEventW(NULL, FALSE, FALSE, NULL);
634     ok(event != NULL, "CreateEvent failed\n");
635 
636     hr = IAudioClient_Start(ac);
637     ok(hr == AUDCLNT_E_EVENTHANDLE_NOT_SET ||
638             hr == D3D11_ERROR_4E /* win10 */, "Start failed: %08x\n", hr);
639 
640     hr = IAudioClient_SetEventHandle(ac, event);
641     ok(hr == S_OK, "SetEventHandle failed: %08x\n", hr);
642 
643     hr = IAudioClient_SetEventHandle(ac, event);
644     ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME) ||
645             hr == E_UNEXPECTED /* win10 */, "SetEventHandle returns %08x\n", hr);
646 
647     r = WaitForSingleObject(event, 40);
648     ok(r == WAIT_TIMEOUT, "Wait(event) before Start gave %x\n", r);
649 
650     hr = IAudioClient_Start(ac);
651     ok(hr == S_OK, "Start failed: %08x\n", hr);
652 
653     r = WaitForSingleObject(event, 20);
654     ok(r == WAIT_OBJECT_0, "Wait(event) after Start gave %x\n", r);
655 
656     hr = IAudioClient_Stop(ac);
657     ok(hr == S_OK, "Stop failed: %08x\n", hr);
658 
659     ok(ResetEvent(event), "ResetEvent\n");
660 
661     /* Still receiving events! */
662     r = WaitForSingleObject(event, 20);
663     ok(r == WAIT_OBJECT_0, "Wait(event) after Stop gave %x\n", r);
664 
665     hr = IAudioClient_Reset(ac);
666     ok(hr == S_OK, "Reset failed: %08x\n", hr);
667 
668     ok(ResetEvent(event), "ResetEvent\n");
669 
670     r = WaitForSingleObject(event, 120);
671     ok(r == WAIT_OBJECT_0, "Wait(event) after Reset gave %x\n", r);
672 
673     hr = IAudioClient_SetEventHandle(ac, NULL);
674     ok(hr == E_INVALIDARG, "SetEventHandle(NULL) returns %08x\n", hr);
675 
676     r = WaitForSingleObject(event, 70);
677     ok(r == WAIT_OBJECT_0, "Wait(NULL event) gave %x\n", r);
678 
679     /* test releasing a playing stream */
680     hr = IAudioClient_Start(ac);
681     ok(hr == S_OK, "Start failed: %08x\n", hr);
682     IAudioClient_Release(ac);
683 
684     CloseHandle(event);
685 }
686 
687 static void test_padding(void)
688 {
689     HRESULT hr;
690     IAudioClient *ac;
691     IAudioRenderClient *arc;
692     WAVEFORMATEX *pwfx;
693     REFERENCE_TIME minp, defp;
694     BYTE *buf, silence;
695     UINT32 psize, pad, written, i;
696 
697     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
698             NULL, (void**)&ac);
699     ok(hr == S_OK, "Activation failed with %08x\n", hr);
700     if(hr != S_OK)
701         return;
702 
703     hr = IAudioClient_GetMixFormat(ac, &pwfx);
704     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
705     if(hr != S_OK)
706         return;
707 
708     hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
709             0, 5000000, 0, pwfx, NULL);
710     ok(hr == S_OK, "Initialize failed: %08x\n", hr);
711     if(hr != S_OK)
712         return;
713 
714     if(pwfx->wBitsPerSample == 8)
715         silence = 128;
716     else
717         silence = 0;
718 
719     /** GetDevicePeriod
720      * Default (= shared) device period is 10ms (e.g. 441 frames at 44100),
721      * except when the HW/OS forces a particular alignment,
722      * e.g. 10.1587ms is 28 * 16 = 448 frames at 44100 with HDA.
723      * 441 observed with Vista, 448 with w7 on the same HW! */
724     hr = IAudioClient_GetDevicePeriod(ac, &defp, &minp);
725     ok(hr == S_OK, "GetDevicePeriod failed: %08x\n", hr);
726     /* some wineXYZ.drv use 20ms, not seen on native */
727     ok(defp == 100000 || broken(defp == 101587) || defp == 200000,
728        "Expected 10ms default period: %u\n", (ULONG)defp);
729     ok(minp != 0, "Minimum period is 0\n");
730     ok(minp <= defp, "Minimum period is greater than default period\n");
731 
732     hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&arc);
733     ok(hr == S_OK, "GetService failed: %08x\n", hr);
734 
735     psize = MulDiv(defp, pwfx->nSamplesPerSec, 10000000) * 10;
736 
737     written = 0;
738     hr = IAudioClient_GetCurrentPadding(ac, &pad);
739     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
740     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
741 
742     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
743     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
744     ok(buf != NULL, "NULL buffer returned\n");
745     if(!win10){
746         /* win10 appears not to clear the buffer */
747         for(i = 0; i < psize * pwfx->nBlockAlign; ++i){
748             if(buf[i] != silence){
749                 ok(0, "buffer has data in it already, i: %u, valu: %f\n", i, *((float*)buf));
750                 break;
751             }
752         }
753     }
754 
755     hr = IAudioRenderClient_GetBuffer(arc, 0, &buf);
756     ok(hr == AUDCLNT_E_OUT_OF_ORDER, "GetBuffer 0 size failed: %08x\n", hr);
757     ok(buf == NULL, "GetBuffer 0 gave %p\n", buf);
758     /* MSDN instead documents buf remains untouched */
759 
760     hr = IAudioClient_Reset(ac);
761     ok(hr == AUDCLNT_E_BUFFER_OPERATION_PENDING, "Reset failed: %08x\n", hr);
762 
763     hr = IAudioRenderClient_ReleaseBuffer(arc, psize,
764             AUDCLNT_BUFFERFLAGS_SILENT);
765     ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
766     if(hr == S_OK) written += psize;
767 
768     hr = IAudioClient_GetCurrentPadding(ac, &pad);
769     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
770     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
771 
772     psize = MulDiv(minp, pwfx->nSamplesPerSec, 10000000) * 10;
773 
774     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
775     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
776     ok(buf != NULL, "NULL buffer returned\n");
777 
778     hr = IAudioRenderClient_ReleaseBuffer(arc, psize,
779             AUDCLNT_BUFFERFLAGS_SILENT);
780     ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
781     written += psize;
782 
783     hr = IAudioClient_GetCurrentPadding(ac, &pad);
784     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
785     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
786 
787     /* overfull buffer. requested 1/2s buffer size, so try
788      * to get a 1/2s buffer, which should fail */
789     psize = pwfx->nSamplesPerSec / 2;
790     buf = (void*)0xDEADF00D;
791     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
792     ok(hr == AUDCLNT_E_BUFFER_TOO_LARGE, "GetBuffer gave wrong error: %08x\n", hr);
793     ok(buf == NULL, "NULL expected %p\n", buf);
794 
795     hr = IAudioRenderClient_ReleaseBuffer(arc, psize, 0);
796     ok(hr == AUDCLNT_E_OUT_OF_ORDER, "ReleaseBuffer gave wrong error: %08x\n", hr);
797 
798     psize = MulDiv(minp, pwfx->nSamplesPerSec, 10000000) * 2;
799 
800     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
801     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
802     ok(buf != NULL, "NULL buffer returned\n");
803 
804     hr = IAudioRenderClient_ReleaseBuffer(arc, 0, 0);
805     ok(hr == S_OK, "ReleaseBuffer 0 gave wrong error: %08x\n", hr);
806 
807     buf = (void*)0xDEADF00D;
808     hr = IAudioRenderClient_GetBuffer(arc, 0, &buf);
809     ok(hr == S_OK, "GetBuffer 0 size failed: %08x\n", hr);
810     ok(buf == NULL, "GetBuffer 0 gave %p\n", buf);
811     /* MSDN instead documents buf remains untouched */
812 
813     buf = (void*)0xDEADF00D;
814     hr = IAudioRenderClient_GetBuffer(arc, 0, &buf);
815     ok(hr == S_OK, "GetBuffer 0 size #2 failed: %08x\n", hr);
816     ok(buf == NULL, "GetBuffer 0 #2 gave %p\n", buf);
817 
818     hr = IAudioRenderClient_ReleaseBuffer(arc, psize, 0);
819     ok(hr == AUDCLNT_E_OUT_OF_ORDER, "ReleaseBuffer not size 0 gave %08x\n", hr);
820 
821     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
822     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
823     ok(buf != NULL, "NULL buffer returned\n");
824 
825     hr = IAudioRenderClient_ReleaseBuffer(arc, 0, 0);
826     ok(hr == S_OK, "ReleaseBuffer 0 gave wrong error: %08x\n", hr);
827 
828     hr = IAudioClient_GetCurrentPadding(ac, &pad);
829     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
830     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
831 
832     hr = IAudioRenderClient_GetBuffer(arc, psize, &buf);
833     ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
834     ok(buf != NULL, "NULL buffer returned\n");
835 
836     hr = IAudioRenderClient_ReleaseBuffer(arc, psize+1, AUDCLNT_BUFFERFLAGS_SILENT);
837     ok(hr == AUDCLNT_E_INVALID_SIZE, "ReleaseBuffer too large error: %08x\n", hr);
838     /* todo_wine means Wine may overwrite memory */
839     if(hr == S_OK) written += psize+1;
840 
841     /* Buffer still hold */
842     hr = IAudioRenderClient_ReleaseBuffer(arc, psize/2, AUDCLNT_BUFFERFLAGS_SILENT);
843     ok(hr == S_OK, "ReleaseBuffer after error: %08x\n", hr);
844     if(hr == S_OK) written += psize/2;
845 
846     hr = IAudioRenderClient_ReleaseBuffer(arc, 0, 0);
847     ok(hr == S_OK, "ReleaseBuffer 0 gave wrong error: %08x\n", hr);
848 
849     hr = IAudioClient_GetCurrentPadding(ac, &pad);
850     ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
851     ok(pad == written, "GetCurrentPadding returned %u, should be %u\n", pad, written);
852 
853     CoTaskMemFree(pwfx);
854 
855     IAudioRenderClient_Release(arc);
856     IAudioClient_Release(ac);
857 }
858 
859 static void test_clock(int share)
860 {
861     HRESULT hr;
862     IAudioClient *ac;
863     IAudioClock *acl;
864     IAudioRenderClient *arc;
865     UINT64 freq, pos, pcpos0, pcpos, last;
866     UINT32 pad, gbsize, bufsize, fragment, parts, avail, slept = 0, sum = 0;
867     BYTE *data;
868     WAVEFORMATEX *pwfx;
869     LARGE_INTEGER hpctime, hpctime0, hpcfreq;
870     REFERENCE_TIME minp, defp, t1, t2;
871     REFERENCE_TIME duration = 5000000, period = 150000;
872     int i;
873 
874     ok(QueryPerformanceFrequency(&hpcfreq), "PerfFrequency failed\n");
875 
876     hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
877             NULL, (void**)&ac);
878     ok(hr == S_OK, "Activation failed with %08x\n", hr);
879     if(hr != S_OK)
880         return;
881 
882     hr = IAudioClient_GetMixFormat(ac, &pwfx);
883     ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
884     if(hr != S_OK)
885         return;
886 
887     hr = IAudioClient_GetDevicePeriod(ac, &defp, &minp);
888     ok(hr == S_OK, "GetDevicePeriod failed: %08x\n", hr);
889     ok(minp <= period, "desired period %u too small for %u\n", (ULONG)period, (ULONG)minp);
890 
891     if (share) {
892         trace("Testing shared mode\n");
893         /* period is ignored */
894         hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
895                 0, duration, period, pwfx, NULL);
896         period = defp;
897     } else {
898         pwfx->wFormatTag = WAVE_FORMAT_PCM;
899         pwfx->nChannels = 2;
900         pwfx->cbSize = 0;
901         pwfx->wBitsPerSample = 16; /* no floating point */
902         pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;
903         pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign;
904         trace("Testing exclusive mode at %u\n", pwfx->nSamplesPerSec);
905 
906         hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_EXCLUSIVE,
907                 0, duration, period, pwfx, NULL);
908     }
909     ok(share ? hr == S_OK : hr == hexcl || hr == AUDCLNT_E_DEVICE_IN_USE, "Initialize failed: %08x\n", hr);
910     if (hr != S_OK) {
911         CoTaskMemFree(pwfx);
912         IAudioClient_Release(ac);
913         if(hr == AUDCLNT_E_DEVICE_IN_USE)
914             skip("Device in use, no %s access\n", share ? "shared" : "exclusive");
915         return;
916     }
917 
918     /** GetStreamLatency
919      * Shared mode: 1x period + a little, but some 192000 devices return 5.3334ms.
920      * Exclusive mode: testbot returns 2x period + a little, but
921      * some HDA drivers return 1x period, some + a little. */
922     hr = IAudioClient_GetStreamLatency(ac, &t2);
923     ok(hr == S_OK, "GetStreamLatency failed: %08x\n", hr);
924     trace("Latency: %u.%04u ms\n", (UINT)(t2/10000), (UINT)(t2 % 10000));
925     ok(t2 >= period || broken(t2 >= period/2 && share && pwfx->nSamplesPerSec > 48000) ||
926             broken(t2 == 0) /* win10 */,
927        "Latency < default period, delta %ldus\n", (long)((t2-period)/10));
928 
929     /** GetBufferSize
930      * BufferSize must be rounded up, maximum 2s says MSDN.
931      * Both is wrong.  Rounding may lead to size a little smaller than duration;
932      * duration > 2s is accepted in shared mode.
933      * Shared mode: round solely w.r.t. mixer rate,
934      *              duration is no multiple of period.
935      * Exclusive mode: size appears as a multiple of some fragment that
936      * is either the rounded period or a fixed constant like 1024,
937      * whatever the driver implements. */
938     hr = IAudioClient_GetBufferSize(ac, &gbsize);
939     ok(hr == S_OK, "GetBufferSize failed: %08x\n", hr);
940 
941     bufsize   =  MulDiv(duration, pwfx->nSamplesPerSec, 10000000);
942     fragment  =  MulDiv(period,   pwfx->nSamplesPerSec, 10000000);
943     parts     =  MulDiv(bufsize, 1, fragment); /* instead of (duration, 1, period) */
944     trace("BufferSize %u estimated fragment %u x %u = %u\n", gbsize, fragment, parts, fragment * parts);
945     /* fragment size (= period in frames) is rounded up.
946      * BufferSize must be rounded up, maximum 2s says MSDN
947      * but it is rounded down modulo fragment ! */
948     if (share)
949     ok(gbsize == bufsize,
950        "BufferSize %u at rate %u\n", gbsize, pwfx->nSamplesPerSec);
951     else
952         todo_wine
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