Forum Discussion

🚨 This forum is archived and read-only. To submit a forum post, please visit our new Developer Forum. 🚨
Anonymous's avatar
Anonymous
8 years ago

Xaudio2 and ovr_GetAudioDeviceOutGuidStr() ( create mastering voice )

Hi,
I recently switched all my PC audio stuff to Xaudio2 ( win 10 ) apparently the function XAudio2->CreateMasteringVoice() has one of the parameters listed as LPCWSTR szDeviceId, which should be the "device ID" where the mastering audio voice get created.

I tried to pass in the result of ovr_GetAudioDeviceOutGuidStr() that in case of CV1 appears to be {0.0.0.00000000}.{4a98d273-85c2-4bf2-9977-e4f2ff62a11e} ( the headphones )

However this results always in an E-FAIL returned by CreateMasteringVoice().

I tried to read around and I don't quite get precisely "what is this deviceID expected by that function".

Somewhere I found someone saying " As of Windows 8, pass a software device ID (this is not the same as an IMMDevice ID.) " but I am not sure about the difference nor "how I can get it for the CV1" and/or if there' s way to derive it from ovr_GetAudioDeviceOutGuidStr() by appending some extra stuff.

Thanks in advance for any info.

4 Replies

  • Anonymous's avatar
    Anonymous
    Hi,
    just re-checking .. nothing yet ? :)
  • Anonymous's avatar
    Anonymous
    Thanks it's just that I tried every string I could came out with, and tried without success to compile some "Windows code" found in some places that were listing a different way to enumerate devices/get ID 'strings'.
    But to no avail, could not make it work yet I still don't get exactly what sort of "ID String" that type of function wants.
  • Anonymous's avatar
    Anonymous
    Hi,

    long story made short, I found the answer myself but using bit of this and that.

    Longer story you need to implement a "full device enumeration" "WinRT style" using some Windows functions and ways that change depending on WIN7, Win 8/8.1, if you have Xaudio_2.7.DLL or some other version ( Win 10 ) .

    In Win10, it appears that what you look for is in case you have a system like mine is "an output like this" :

    Device 0
        ID = "\\?\SWD#MMDEVAPI#{0.0.0.00000000}.{256627e6-4a51-46c3-9aad-2501f8ff15a7}#{e6327cad-dcec-4949-ae8a-991e976a79d2}"
        Description = "Speakers (Realtek High Definition Audio)"

    Device 1
        ID = "\\?\SWD#MMDEVAPI#{0.0.0.00000000}.{6590cdf2-d7d0-403b-88fb-0fadcd744036}#{e6327cad-dcec-4949-ae8a-991e976a79d2}"
        Description = "PHL BDM4037U (NVIDIA High Definition Audio)"

    Device 2
        ID = "\\?\SWD#MMDEVAPI#{0.0.0.00000000}.{4a98d273-85c2-4bf2-9977-e4f2ff62a11e}#{e6327cad-dcec-4949-ae8a-991e976a79d2}"
        Description = "Headphones (Rift Audio)"

    And the string that you want o pass to pXAudio2->CreateMasteringVoice() is something like this :

        if (FAILED(hr = pXAudio2->CreateMasteringVoice(&pMasteringVoice,
            XAUDIO2_DEFAULT_CHANNELS, XAUDIO2_DEFAULT_SAMPLERATE, 0,
            list[devindex].deviceId.c_str())))

    Which in my specific case of "Headphones (Rift Audio)" turns out to be :

    Mastering voice crated with device : \\?\SWD#MMDEVAPI#{0.0.0.00000000}.{4a98d273-85c2-4bf2-9977-e4f2ff62a11e}#{e6327cad-dcec-4949-ae8a-991e976a79d2}

    Mastering voice created with 2 input channels, 48000 sample rate

    Now I am still working on it to "compact" it into a single function/stuff that would get that string and find the one that contains "Rift Audio" in it ( and/or match part of it with some of you OVR_ ... functions) but the little problem is I should give you "a full ZIP with the VS project" because "the source alone won't compile if you don't know how to make it compile".

    Also I haven't really tested it yet ( but I will ) with Win7 and Win 8.1.

    Anyway "those are the strings you are looking for", actually to be honest that's just an 'external source' I been trying I yet have to put it all together and see if any audio really gets out :smile: but I think it shuld be ok.

    In Win10 alone "you may get away" with something like this below but the "generic case" you really have to consider 4 separate cases and 3 different methods.

        // Enumerating with WinRT using C++/CX
        using namespace concurrency;
        using Windows::Devices::Enumeration::DeviceClass;
        using Windows::Devices::Enumeration::DeviceInformation;
        using Windows::Devices::Enumeration::DeviceInformationCollection;

        auto operation = DeviceInformation::FindAllAsync(DeviceClass::AudioRender);

        auto task = create_task(operation);

        task.then([&list](DeviceInformationCollection^ devices)
        {
            for (unsigned i = 0; i < devices->Size; ++i)
            {
                using Windows::Devices::Enumeration::DeviceInformation;

                DeviceInformation^ d = devices->GetAt(i);

                AudioDevice device;
                device.deviceId = d->Id->Data();
                device.description = d->Name->Data();
                list.emplace_back(device);
            }
        }).wait();

        //task.wait();

        if (list.empty())
            return S_FALSE;

    NOTE, DOES NOT WORK if you use that task.wait(), .wait() HAS to be there where I put it ! ( or the function exists while the task is still running ).

    Cheers.

  • Anonymous's avatar
    Anonymous
    Hi,

    just saying still working on it, did not test ALL the cases yet but I managed to create a FindOculusHeadphones(_In_ IXAudio2* pXaudio2, _Inout_ std::wstring &deviceId) function that seems to work ( so far in the case I tested it ) with Xaudio2.

    I have NOT tested/tried ALL the cases yet so I am not going to put yet this function around here to hear people crying "does not work" :smile:

    But yes I can confirm that at least in one case ( I tested so far ) is possible to have Xaudio2 working with OR CV1 and make it find the headphones output by its own.

    I am NOT sure ( I really don't know ) if you could someway "construct" the string by "attaching this and that" to the "IDs" you already have and assume it will work, what I do is to enumerate all Windows "audio output" devices and look for the one that contains as substring your ID and/or "Rift Audio" in the device description.

    I am building up my function based on some DirectX SDK sample I found around so I don' think there should be any (C) or such issues as it's derivative from it.

    But yeah it's "one of those things a la' Windows" you know bit of mess there and there :)

    Cheers.