[PATCH 2/2] xaudio2_8: Implement CreateFX

Andrew Eikum aeikum at codeweavers.com
Fri Oct 23 14:31:19 CDT 2015


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
---
 dlls/xaudio2_7/tests/xaudio2.c    | 108 ++++++++++++++++++++++++++++++++++++++
 dlls/xaudio2_7/xaudio_classes.idl |   7 +++
 dlls/xaudio2_8/xaudio2_8.spec     |   2 +
 dlls/xaudio2_8/xaudio_dll.c       |  45 ++++++++++++++++
 4 files changed, 162 insertions(+)

diff --git a/dlls/xaudio2_7/tests/xaudio2.c b/dlls/xaudio2_7/tests/xaudio2.c
index 7d7ee17..a664817 100644
--- a/dlls/xaudio2_7/tests/xaudio2.c
+++ b/dlls/xaudio2_7/tests/xaudio2.c
@@ -903,6 +903,113 @@ static void test_xapo_creation_legacy(const char *module, unsigned int version)
     FreeLibrary(xapofxdll);
 }
 
+static void test_xapo_creation_modern(const char *module)
+{
+    HANDLE xaudio2dll;
+    HRESULT hr;
+    IUnknown *fx_unk;
+    unsigned int i;
+
+    HRESULT (CDECL *pCreateFX)(REFCLSID,IUnknown**,void*,UINT32) = NULL;
+    HRESULT (WINAPI *pCAVM)(IUnknown**) = NULL;
+    HRESULT (WINAPI *pCAR)(IUnknown**) = NULL;
+
+    /* CLSIDs are the same across all versions */
+    static struct {
+        const GUID *clsid;
+        BOOL todo;
+    } const_clsids[] = {
+        { &CLSID_FXEQ27, TRUE },
+        { &CLSID_FXMasteringLimiter27, TRUE },
+        { &CLSID_FXReverb27, FALSE },
+        { &CLSID_FXEcho27, TRUE},
+        /* older versions of xapofx actually have support for new clsids */
+        { &CLSID_FXEQ, TRUE },
+        { &CLSID_FXMasteringLimiter, TRUE },
+        { &CLSID_FXReverb, FALSE },
+        { &CLSID_FXEcho, TRUE}
+    };
+
+    xaudio2dll = LoadLibraryA(module);
+    if(xaudio2dll){
+        pCreateFX = (void*)GetProcAddress(xaudio2dll, "CreateFX");
+        ok(pCreateFX != NULL, "%s did not have CreateFX?\n", module);
+        if(!pCreateFX){
+            FreeLibrary(xaudio2dll);
+            return;
+        }
+    }else{
+        win_skip("Couldn't load %s\n", module);
+        return;
+    }
+
+    if(pCreateFX){
+        for(i = 0; i < sizeof(const_clsids) / sizeof(*const_clsids); ++i){
+            hr = pCreateFX(const_clsids[i].clsid, &fx_unk, NULL, 0);
+            if(const_clsids[i].todo)
+                todo_wine ok(hr == S_OK, "%s: CreateFX(%s) failed: %08x\n", module, wine_dbgstr_guid(const_clsids[i].clsid), hr);
+            else
+                ok(hr == S_OK, "%s: CreateFX(%s) failed: %08x\n", module, wine_dbgstr_guid(const_clsids[i].clsid), hr);
+            if(SUCCEEDED(hr)){
+                IXAPO *xapo;
+                hr = IUnknown_QueryInterface(fx_unk, &IID_IXAPO, (void**)&xapo);
+                ok(hr == S_OK, "Couldn't get IXAPO interface: %08x\n", hr);
+                if(SUCCEEDED(hr))
+                    IXAPO_Release(xapo);
+                IUnknown_Release(fx_unk);
+            }
+
+            hr = CoCreateInstance(const_clsids[i].clsid, NULL, CLSCTX_INPROC_SERVER,
+                    &IID_IUnknown, (void**)&fx_unk);
+            ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance should have failed: %08x\n", hr);
+            if(SUCCEEDED(hr))
+                IUnknown_Release(fx_unk);
+        }
+
+        /* test legacy CLSID */
+        hr = pCreateFX(&CLSID_AudioVolumeMeter, &fx_unk, NULL, 0);
+        ok(hr == S_OK, "%s: CreateFX(CLSID_AudioVolumeMeter) failed: %08x\n", module, hr);
+        if(SUCCEEDED(hr)){
+            IXAPO *xapo;
+            hr = IUnknown_QueryInterface(fx_unk, &IID_IXAPO, (void**)&xapo);
+            ok(hr == S_OK, "Couldn't get IXAPO interface: %08x\n", hr);
+            if(SUCCEEDED(hr))
+                IXAPO_Release(xapo);
+            IUnknown_Release(fx_unk);
+        }
+    }
+
+    pCAVM = (void*)GetProcAddress(xaudio2dll, "CreateAudioVolumeMeter");
+    ok(pCAVM != NULL, "%s did not have CreateAudioVolumeMeter?\n", module);
+
+    hr = pCAVM(&fx_unk);
+    ok(hr == S_OK, "CreateAudioVolumeMeter failed: %08x\n", hr);
+    if(SUCCEEDED(hr)){
+        IXAPO *xapo;
+        hr = IUnknown_QueryInterface(fx_unk, &IID_IXAPO, (void**)&xapo);
+        ok(hr == S_OK, "Couldn't get IXAPO interface: %08x\n", hr);
+        if(SUCCEEDED(hr))
+            IXAPO_Release(xapo);
+        IUnknown_Release(fx_unk);
+    }
+
+    pCAR = (void*)GetProcAddress(xaudio2dll, "CreateAudioReverb");
+    ok(pCAR != NULL, "%s did not have CreateAudioReverb?\n", module);
+
+    hr = pCAR(&fx_unk);
+    ok(hr == S_OK, "CreateAudioReverb failed: %08x\n", hr);
+    if(SUCCEEDED(hr)){
+        IXAPO *xapo;
+        hr = IUnknown_QueryInterface(fx_unk, &IID_IXAPO, (void**)&xapo);
+        ok(hr == S_OK, "Couldn't get IXAPO interface: %08x\n", hr);
+        if(SUCCEEDED(hr))
+            IXAPO_Release(xapo);
+        IUnknown_Release(fx_unk);
+    }
+
+    FreeLibrary(xaudio2dll);
+}
+
 static void test_xapo_creation(void)
 {
     test_xapo_creation_legacy("xapofx1_1.dll", 22);
@@ -911,6 +1018,7 @@ static void test_xapo_creation(void)
     test_xapo_creation_legacy("xapofx1_3.dll", 25);
     test_xapo_creation_legacy("xapofx1_4.dll", 26);
     test_xapo_creation_legacy("xapofx1_5.dll", 27);
+    test_xapo_creation_modern("xaudio2_8.dll");
 }
 
 static UINT32 check_has_devices(IXAudio2 *xa)
diff --git a/dlls/xaudio2_7/xaudio_classes.idl b/dlls/xaudio2_7/xaudio_classes.idl
index 1f8b020..42a8cbf 100644
--- a/dlls/xaudio2_7/xaudio_classes.idl
+++ b/dlls/xaudio2_7/xaudio_classes.idl
@@ -82,3 +82,10 @@ coclass FXReverb14 { interface IXAPO; }
     uuid(a90bc001-e897-e897-7439-43FF02000105)
 ]
 coclass FXReverb15 { interface IXAPO; }
+
+[
+    helpstring("XAudio2.8 FXReverb Class (Wine)"),
+    threading(both),
+    uuid(a90bc001-e897-e897-7439-43FF02000208)
+]
+coclass FXReverb28 { interface IXAPO; }
diff --git a/dlls/xaudio2_8/xaudio2_8.spec b/dlls/xaudio2_8/xaudio2_8.spec
index 3228d71..09032f9 100644
--- a/dlls/xaudio2_8/xaudio2_8.spec
+++ b/dlls/xaudio2_8/xaudio2_8.spec
@@ -1,2 +1,4 @@
 @ stdcall XAudio2Create(ptr long long)
 @ stdcall CreateAudioVolumeMeter(ptr)
+@ stdcall CreateAudioReverb(ptr)
+@ cdecl CreateFX(ptr ptr ptr long)
diff --git a/dlls/xaudio2_8/xaudio_dll.c b/dlls/xaudio2_8/xaudio_dll.c
index 4a73783..b1c5fd4 100644
--- a/dlls/xaudio2_8/xaudio_dll.c
+++ b/dlls/xaudio2_8/xaudio_dll.c
@@ -23,11 +23,15 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winuser.h"
+#include "wine/debug.h"
 
 #include "initguid.h"
 #include "xaudio2.h"
 #include "xaudio2fx.h"
 #include "xapo.h"
+#include "xapofx.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(xaudio2);
 
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
 {
@@ -85,3 +89,44 @@ HRESULT WINAPI CreateAudioReverb(IUnknown **out)
     return CoCreateInstance(&CLSID_AudioReverb, NULL, CLSCTX_INPROC_SERVER,
             &IID_IUnknown, (void**)out);
 }
+
+HRESULT CDECL CreateFX(REFCLSID clsid, IUnknown **out, void *initdata, UINT32 initdata_bytes)
+{
+    HRESULT hr;
+    IUnknown *obj;
+    const GUID *class;
+
+    *out = NULL;
+    class = clsid;
+
+    if(IsEqualGUID(clsid, &CLSID_FXReverb27) ||
+            IsEqualGUID(clsid, &CLSID_FXReverb))
+        class = &CLSID_WINE_FXReverb28;
+
+    hr = CoCreateInstance(class, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&obj);
+    if(FAILED(hr)){
+        WARN("CoCreateInstance failed: %08x\n", hr);
+        return hr;
+    }
+
+    if(initdata && initdata_bytes > 0){
+        IXAPO *xapo;
+
+        hr = IUnknown_QueryInterface(obj, &IID_IXAPO, (void**)&xapo);
+        if(SUCCEEDED(hr)){
+            hr = IXAPO_Initialize(xapo, initdata, initdata_bytes);
+
+            IXAPO_Release(xapo);
+
+            if(FAILED(hr)){
+                WARN("Initialize failed: %08x\n", hr);
+                IUnknown_Release(obj);
+                return hr;
+            }
+        }
+    }
+
+    *out = obj;
+
+    return S_OK;
+}
-- 
2.6.2




More information about the wine-patches mailing list