=?UTF-8?Q?J=C3=B6rg=20H=C3=B6hle=20?=: mmdevapi/tests: Add a worst-case XAudio2 fragment-size writes scenario.
Alexandre Julliard
julliard at winehq.org
Thu Jan 26 14:49:25 CST 2012
Module: wine
Branch: master
Commit: 4e323ec618ec57c11e9e9f345ca6a0e36a609b3a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4e323ec618ec57c11e9e9f345ca6a0e36a609b3a
Author: Jörg Höhle <hoehle at users.sourceforge.net>
Date: Tue Jan 24 20:54:40 2012 +0100
mmdevapi/tests: Add a worst-case XAudio2 fragment-size writes scenario.
---
dlls/mmdevapi/tests/render.c | 116 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 116 insertions(+), 0 deletions(-)
diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c
index f918460..2427be7 100644
--- a/dlls/mmdevapi/tests/render.c
+++ b/dlls/mmdevapi/tests/render.c
@@ -1532,6 +1532,121 @@ static void test_session_creation(void)
IAudioClient_Release(ac);
}
+static void test_worst_case(void)
+{
+ HANDLE event;
+ HRESULT hr;
+ IAudioClient *ac;
+ IAudioRenderClient *arc;
+ IAudioClock *acl;
+ WAVEFORMATEX *pwfx;
+ REFERENCE_TIME defp;
+ UINT64 freq, pos, pcpos0, pcpos;
+ BYTE *data;
+ DWORD r;
+ UINT32 pad, fragment, sum;
+ int i,j;
+
+ hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
+ NULL, (void**)&ac);
+ ok(hr == S_OK, "Activation failed with %08x\n", hr);
+ if(hr != S_OK)
+ return;
+
+ hr = IAudioClient_GetMixFormat(ac, &pwfx);
+ ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
+
+ hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED,
+ AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 500000, 0, pwfx, NULL);
+ ok(hr == S_OK, "Initialize failed: %08x\n", hr);
+ if(hr != S_OK)
+ return;
+
+ hr = IAudioClient_GetDevicePeriod(ac, &defp, NULL);
+ ok(hr == S_OK, "GetDevicePeriod failed: %08x\n", hr);
+
+ fragment = MulDiv(defp, pwfx->nSamplesPerSec, 10000000);
+
+ event = CreateEventW(NULL, FALSE, FALSE, NULL);
+ ok(event != NULL, "CreateEvent failed\n");
+
+ hr = IAudioClient_SetEventHandle(ac, event);
+ ok(hr == S_OK, "SetEventHandle failed: %08x\n", hr);
+
+ hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&arc);
+ ok(hr == S_OK, "GetService(IAudioRenderClient) failed: %08x\n", hr);
+
+ hr = IAudioClient_GetService(ac, &IID_IAudioClock, (void**)&acl);
+ ok(hr == S_OK, "GetService(IAudioClock) failed: %08x\n", hr);
+
+ hr = IAudioClock_GetFrequency(acl, &freq);
+ ok(hr == S_OK, "GetFrequency failed: %08x\n", hr);
+
+ for(j = 0; j <= (winetest_interactive ? 9 : 2); j++){
+ sum = 0;
+ trace("Should play %ums continuous tone with fragment size %u.\n",
+ (ULONG)(defp/100), fragment);
+
+ hr = IAudioClock_GetPosition(acl, &pos, &pcpos0);
+ ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
+
+ /* XAudio2 prefills one period, we don't */
+ hr = IAudioClient_Start(ac);
+ ok(hr == S_OK, "Start failed: %08x\n", hr);
+
+ for(i = 0; i <= 99; i++){ /* 100 x 10ms = 1 second */
+ r = WaitForSingleObject(event, 70);
+ ok(r == WAIT_OBJECT_0, "Wait gave %x\n", r);
+
+ /* the app has nearly one period time to feed data */
+ Sleep((i % 10) * defp / 120000);
+
+ hr = IAudioClient_GetCurrentPadding(ac, &pad);
+ ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
+
+ /* XAudio2 writes only when there's little data left */
+ if(pad <= fragment){
+ hr = IAudioRenderClient_GetBuffer(arc, fragment, &data);
+ ok(hr == S_OK, "GetBuffer failed: %08x\n", hr);
+
+ /* fixme: produce audible output */
+ hr = IAudioRenderClient_ReleaseBuffer(arc, fragment, AUDCLNT_BUFFERFLAGS_SILENT);
+ ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr);
+ if(hr == S_OK)
+ sum += fragment;
+ }
+ }
+
+ hr = IAudioClient_Stop(ac);
+ ok(hr == S_OK, "Stop failed: %08x\n", hr);
+
+ hr = IAudioClient_GetCurrentPadding(ac, &pad);
+ ok(hr == S_OK, "GetCurrentPadding failed: %08x\n", hr);
+
+ hr = IAudioClock_GetPosition(acl, &pos, &pcpos);
+ ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
+
+ Sleep(100);
+
+ trace("Released %u=%ux%u -%u frames at %u worth %ums in %ums\n",
+ sum, sum/fragment, fragment, pad,
+ pwfx->nSamplesPerSec, MulDiv(sum-pad, 1000, pwfx->nSamplesPerSec),
+ (ULONG)((pcpos-pcpos0)/10000));
+
+ ok(pos * pwfx->nSamplesPerSec == (sum-pad) * freq,
+ "Position %u at end vs. %u-%u submitted frames\n", (UINT)pos, sum, pad);
+
+ hr = IAudioClient_Reset(ac);
+ ok(hr == S_OK, "Reset failed: %08x\n", hr);
+
+ Sleep(250);
+ }
+
+ CoTaskMemFree(pwfx);
+ IAudioClient_Release(ac);
+ IAudioRenderClient_Release(arc);
+}
+
START_TEST(render)
{
HRESULT hr;
@@ -1568,6 +1683,7 @@ START_TEST(render)
test_simplevolume();
test_volume_dependence();
test_session_creation();
+ test_worst_case();
IMMDevice_Release(dev);
More information about the wine-cvs
mailing list