[PATCH] devenum: Register IEEE float for Direct Sound default device.
Zebediah Figura (she/her)
zfigura at codeweavers.com
Tue Jun 22 11:20:34 CDT 2021
On 6/22/21 10:23 AM, Rémi Bernon wrote:
> 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] = {};
Not all compilers like an empty pair of braces, unfortunately.
> 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);
As you've already noticed, IAMFilterData::ParseFilterData() is broken
and can't be used in tests.
> +
> + 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);
>
More information about the wine-devel
mailing list