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@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);