Giovanni Mascellani : xactengine3_7/tests: Test notifications when loading a wave bank.

Alexandre Julliard julliard at winehq.org
Mon Jul 18 15:47:02 CDT 2022


Module: wine
Branch: master
Commit: 1ac80a99dd8ffa92e1822a71168030d2cd0bf802
URL:    https://gitlab.winehq.org/wine/wine/-/commit/1ac80a99dd8ffa92e1822a71168030d2cd0bf802

Author: Giovanni Mascellani <gmascellani at codeweavers.com>
Date:   Thu Jul  7 15:15:05 2022 +0200

xactengine3_7/tests: Test notifications when loading a wave bank.

"The King of Fighters '98 Ultimate Match Final Edition" depends on
this behavior. At least, the build I have is; it seems other builds
are not.

Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>

---

 dlls/xactengine3_7/tests/xact3.c | 171 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 171 insertions(+)

diff --git a/dlls/xactengine3_7/tests/xact3.c b/dlls/xactengine3_7/tests/xact3.c
index 623a1c97db8..1b27eb9aa19 100644
--- a/dlls/xactengine3_7/tests/xact3.c
+++ b/dlls/xactengine3_7/tests/xact3.c
@@ -28,6 +28,7 @@
 
 #include "initguid.h"
 #include "xact3.h"
+#include "xact3wb.h"
 
 DEFINE_GUID(IID_IXACT3Engine30, 0x9e33f661, 0x2d07, 0x43ec, 0x97, 0x04, 0xbb, 0xcb, 0x71, 0xa5, 0x49, 0x72);
 DEFINE_GUID(IID_IXACT3Engine31, 0xe72c1b9a, 0xd717, 0x41c0, 0x81, 0xa6, 0x50, 0xeb, 0x56, 0xe8, 0x06, 0x49);
@@ -90,11 +91,181 @@ static void test_interfaces(void)
     }
 }
 
+static WCHAR *gen_xwb_file(void)
+{
+    static const WAVEBANKENTRY entry =
+    {
+        .Format =
+        {
+            .wFormatTag = WAVEBANKMINIFORMAT_TAG_ADPCM,
+            .nChannels = 2,
+            .nSamplesPerSec = 22051,
+            .wBlockAlign = 48,
+        },
+    };
+    static const WAVEBANKDATA bank_data =
+    {
+        .dwFlags = WAVEBANK_TYPE_STREAMING,
+        .dwEntryCount = 1,
+        .szBankName = "test",
+        .dwEntryMetaDataElementSize = sizeof(entry),
+        .dwEntryNameElementSize = WAVEBANK_ENTRYNAME_LENGTH,
+        .dwAlignment = 0x800,
+    };
+    static const WAVEBANKHEADER header =
+    {
+        .dwSignature = WAVEBANK_HEADER_SIGNATURE,
+        .dwVersion = XACT_CONTENT_VERSION,
+        .dwHeaderVersion = WAVEBANK_HEADER_VERSION,
+        .Segments =
+        {
+            [WAVEBANK_SEGIDX_BANKDATA] =
+            {
+                .dwOffset = sizeof(header),
+                .dwLength = sizeof(bank_data),
+            },
+            [WAVEBANK_SEGIDX_ENTRYMETADATA] =
+            {
+                .dwOffset = sizeof(header) + sizeof(bank_data),
+                .dwLength = sizeof(entry),
+            },
+        },
+    };
+    static WCHAR path[MAX_PATH];
+    DWORD written;
+    HANDLE file;
+
+    GetTempPathW(ARRAY_SIZE(path), path);
+    lstrcatW(path, L"test.xwb");
+
+    file = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
+    ok(file != INVALID_HANDLE_VALUE, "Cannot create file %s, error %ld\n",
+            wine_dbgstr_w(path), GetLastError());
+
+    WriteFile(file, &header, sizeof(header), &written, NULL);
+    ok(written == sizeof(header), "Cannot write header\n");
+
+    WriteFile(file, &bank_data, sizeof(bank_data), &written, NULL);
+    ok(written == sizeof(bank_data), "Cannot write bank data\n");
+
+    WriteFile(file, &entry, sizeof(entry), &written, NULL);
+    ok(written == sizeof(entry), "Cannot write entry\n");
+
+    CloseHandle(file);
+
+    return path;
+}
+
+struct notification_cb_data
+{
+    XACTNOTIFICATIONTYPE type;
+    IXACT3WaveBank *wave_bank;
+    BOOL received;
+    DWORD thread_id;
+};
+
+static void WINAPI notification_cb(const XACT_NOTIFICATION *notification)
+{
+    struct notification_cb_data *data = notification->pvContext;
+    DWORD thread_id = GetCurrentThreadId();
+
+    data->received = TRUE;
+    ok(notification->type == data->type,
+            "Unexpected notification type %u\n", notification->type);
+    ok(notification->waveBank.pWaveBank == data->wave_bank, "Unexpected wave bank %p instead of %p\n",
+            notification->waveBank.pWaveBank, data->wave_bank);
+    ok(thread_id == data->thread_id, "Unexpected thread id %#lx instead of %#lx\n", thread_id, data->thread_id);
+}
+
+static void test_notifications(void)
+{
+    struct notification_cb_data prepared_data = { 0 }, destroyed_data = { 0 };
+    XACT_NOTIFICATION_DESCRIPTION notification_desc = { 0 };
+    XACT_STREAMING_PARAMETERS streaming_params = { 0 };
+    XACT_RUNTIME_PARAMETERS params = { 0 };
+    IXACT3Engine *engine;
+    WCHAR *filename;
+    unsigned int i;
+    HANDLE file;
+    DWORD state;
+    HRESULT hr;
+
+    hr = CoCreateInstance(&CLSID_XACTEngine, NULL, CLSCTX_INPROC_SERVER, &IID_IXACT3Engine, (void **)&engine);
+    ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /* Win 10 v1507 */, "Cannot create engine, hr %#lx\n", hr);
+
+    if (hr == REGDB_E_CLASSNOTREG)
+    {
+        win_skip("XACT not supported\n");
+        return;
+    }
+
+    params.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT;
+    params.fnNotificationCallback = notification_cb;
+
+    hr = IXACT3Engine_Initialize(engine, &params);
+    ok(hr == S_OK, "Cannot initialize engine, hr %#lx\n", hr);
+
+    prepared_data.type = XACTNOTIFICATIONTYPE_WAVEBANKPREPARED;
+    prepared_data.thread_id = GetCurrentThreadId();
+    notification_desc.type = XACTNOTIFICATIONTYPE_WAVEBANKPREPARED;
+    notification_desc.flags = XACT_FLAG_NOTIFICATION_PERSIST;
+    notification_desc.pvContext = &prepared_data;
+    hr = IXACT3Engine_RegisterNotification(engine, &notification_desc);
+    ok(hr == S_OK, "Cannot register notification, hr %#lx\n", hr);
+
+    destroyed_data.type = XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED;
+    destroyed_data.thread_id = GetCurrentThreadId();
+    notification_desc.type = XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED;
+    notification_desc.flags = XACT_FLAG_NOTIFICATION_PERSIST;
+    notification_desc.pvContext = NULL;
+    hr = IXACT3Engine_RegisterNotification(engine, &notification_desc);
+    ok(hr == S_OK, "Cannot register notification, hr %#lx\n", hr);
+
+    /* Registering again overrides pvContext, but each notification
+     * class has its own pvContext. */
+    notification_desc.pvContext = &destroyed_data;
+    hr = IXACT3Engine_RegisterNotification(engine, &notification_desc);
+    ok(hr == S_OK, "Cannot register notification, hr %#lx\n", hr);
+
+    filename = gen_xwb_file();
+
+    file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+    ok(file != INVALID_HANDLE_VALUE, "Cannot open file\n");
+
+    streaming_params.file = file;
+    streaming_params.packetSize = 0x800;
+    hr = IXACT3Engine_CreateStreamingWaveBank(engine, &streaming_params, &prepared_data.wave_bank);
+    ok(hr == S_OK, "Cannot create a streaming wave bank, hr %#lx\n", hr);
+    destroyed_data.wave_bank = prepared_data.wave_bank;
+
+    for (i = 0; i < 10 && !prepared_data.received; i++)
+    {
+        IXACT3Engine_DoWork(engine);
+        Sleep(1);
+    }
+
+    hr = IXACT3WaveBank_GetState(prepared_data.wave_bank, &state);
+    ok(hr == S_OK, "Cannot query wave bank state, hr %#lx\n", hr);
+    ok(state == XACT_WAVEBANKSTATE_PREPARED, "Wave bank is not in prepared state, but in %#lx\n", state);
+
+    todo_wine ok(prepared_data.received, "The 'wave bank prepared' notification was never received\n");
+    ok(!destroyed_data.received, "The 'wave bank destroyed' notification was received too early\n");
+
+    IXACT3WaveBank_Destroy(prepared_data.wave_bank);
+    todo_wine ok(destroyed_data.received, "The 'wave bank destroyed' notification was never received\n");
+
+    CloseHandle(file);
+    IXACT3Engine_Release(engine);
+
+    DeleteFileW(filename);
+}
+
 START_TEST(xact3)
 {
     CoInitialize(NULL);
 
     test_interfaces();
+    test_notifications();
 
     CoUninitialize();
 }




More information about the wine-cvs mailing list