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 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.
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;
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 🙂