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