[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