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