[PATCH] devenum: Register IEEE float for Direct Sound default device.

Rémi Bernon rbernon at codeweavers.com
Tue Jun 22 10:23:47 CDT 2021


This fixes Planet Coaster missing intro audio, which outputs IEEE float
audio and for which quartz is looking for a filter. It ends up trying
ACM filters, but that doesn't support IEEE float to PCM conversion.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/devenum/createdevenum.c | 12 +++++----
 dlls/devenum/tests/devenum.c | 49 ++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c
index 8e9cf56eb09..97855b12b81 100644
--- a/dlls/devenum/createdevenum.c
+++ b/dlls/devenum/createdevenum.c
@@ -481,7 +481,7 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, cons
     static const WCHAR defaultW[] = L"Default DirectSound Device";
     IPropertyBag *prop_bag = NULL;
     REGFILTERPINS2 rgpins = {0};
-    REGPINTYPES rgtypes = {0};
+    REGPINTYPES rgtypes[2] = {};
     REGFILTER2 rgf = {0};
     WCHAR clsid[CHARS_IN_GUID];
     VARIANT var;
@@ -512,10 +512,12 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, cons
     rgf.rgPins2 = &rgpins;
     rgpins.dwFlags = REG_PINFLAG_B_RENDERER;
     /* FIXME: native registers many more formats */
-    rgpins.nMediaTypes = 1;
-    rgpins.lpMediaType = &rgtypes;
-    rgtypes.clsMajorType = &MEDIATYPE_Audio;
-    rgtypes.clsMinorType = &MEDIASUBTYPE_PCM;
+    rgpins.nMediaTypes = 2;
+    rgpins.lpMediaType = rgtypes;
+    rgtypes[0].clsMajorType = &MEDIATYPE_Audio;
+    rgtypes[0].clsMinorType = &MEDIASUBTYPE_PCM;
+    rgtypes[1].clsMajorType = &MEDIATYPE_Audio;
+    rgtypes[1].clsMinorType = &MEDIASUBTYPE_IEEE_FLOAT;
 
     write_filter_data(prop_bag, &rgf);
 
diff --git a/dlls/devenum/tests/devenum.c b/dlls/devenum/tests/devenum.c
index 3e0d6f57dc3..cb3b810a30e 100644
--- a/dlls/devenum/tests/devenum.c
+++ b/dlls/devenum/tests/devenum.c
@@ -28,6 +28,7 @@
 #include "mmddk.h"
 #include "vfw.h"
 #include "setupapi.h"
+#include "wine/fil_data.h"
 #include "wine/test.h"
 
 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
@@ -775,13 +776,18 @@ end:
 
 static BOOL CALLBACK test_dsound(GUID *guid, const WCHAR *desc, const WCHAR *module, void *context)
 {
+    BOOL has_pcm = FALSE, has_ieee_float = FALSE;
     IParseDisplayName *parser;
     IPropertyBag *prop_bag;
+    IAMFilterData *filter;
+    REGFILTER2 **rgf2;
     IMoniker *mon;
     WCHAR buffer[200];
     WCHAR name[200];
     VARIANT var;
+    BYTE *data;
     HRESULT hr;
+    int i;
 
     if (guid)
     {
@@ -849,6 +855,49 @@ static BOOL CALLBACK test_dsound(GUID *guid, const WCHAR *desc, const WCHAR *mod
     ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
         wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
 
+    VariantClear(&var);
+    hr = IPropertyBag_Read(prop_bag, L"FilterData", &var, NULL);
+    ok(hr == S_OK, "Read failed: %#x\n", hr);
+
+    hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, &IID_IAMFilterData,
+                          (void **)&filter);
+    ok(hr == S_OK, "CoCreateInstance failed: %#x\n", hr);
+
+    ok(V_ARRAY(&var)->rgsabound[0].cElements == 664, "got rgsabound[0].cElements %d\n",
+       V_ARRAY(&var)->rgsabound[0].cElements);
+
+    hr = SafeArrayAccessData(V_ARRAY(&var), (void **)&data);
+    ok(hr == S_OK, "SafeArrayAccessData failed: %#x\n", hr);
+    hr = IAMFilterData_ParseFilterData(filter, data, V_ARRAY(&var)->rgsabound[0].cElements,
+                                       (BYTE **)&rgf2);
+    ok(hr == S_OK, "IAMFilterData_ParseFilterData failed: %#x\n", hr);
+
+    ok(rgf2[0]->dwVersion == 2, "got version %d\n", rgf2[0]->dwVersion);
+    ok(rgf2[0]->dwMerit == MERIT_PREFERRED, "got merit %d\n", rgf2[0]->dwMerit);
+    ok(rgf2[0]->cPins2 == 1, "got pins count %d\n", rgf2[0]->cPins2);
+    ok(rgf2[0]->rgPins2 != NULL, "got NULL pins\n");
+    ok(rgf2[0]->rgPins2[0].dwFlags, "got pins[0] flags %x\n", rgf2[0]->rgPins2[0].dwFlags);
+    ok(rgf2[0]->rgPins2[0].nMediaTypes, "got pins[0] media type count %d\n",
+       rgf2[0]->rgPins2[0].nMediaTypes);
+    ok(rgf2[0]->rgPins2[0].lpMediaType != NULL, "got pins[0] NULL media types\n");
+
+    for (i = 0; i < rgf2[0]->rgPins2[0].nMediaTypes; ++i)
+    {
+        GUID major = *rgf2[0]->rgPins2[0].lpMediaType[i].clsMajorType;
+        GUID minor = *rgf2[0]->rgPins2[0].lpMediaType[i].clsMinorType;
+        ok(IsEqualGUID(&major, &MEDIATYPE_Audio), "unexpected media type %s\n", wine_dbgstr_guid(&major));
+        if (IsEqualGUID(&minor, &MEDIASUBTYPE_PCM)) has_pcm = TRUE;
+        if (IsEqualGUID(&minor, &MEDIASUBTYPE_IEEE_FLOAT)) has_ieee_float = TRUE;
+    }
+
+    ok(has_pcm, "expected PCM media type\n");
+    ok(has_ieee_float, "expected IEEE float media type\n");
+
+    CoTaskMemFree(rgf2);
+    IAMFilterData_Release(filter);
+    hr = SafeArrayUnaccessData(V_ARRAY(&var));
+    ok(hr == S_OK, "SafeArrayUnaccessData failed: %#x\n", hr);
+
     VariantClear(&var);
     IPropertyBag_Release(prop_bag);
     IMoniker_Release(mon);
-- 
2.31.0




More information about the wine-devel mailing list