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