SteamVR headset speaker and microphone switching fails with errors

SETUP:

  • Alienware m17 laptop
    • ‘Speakers/Headphones (Realtek(R) Audio)’
    • ‘Microphone (Realtek(R) Audio)’
  • Index headset
    • ‘Index HMD (NVIDIA High Definition Audio)’
    • ‘Digital Audio Interface (Valve VR Radio & HMD Mic)’
  • Windows 10
  • Unity 2019.4.36f1
  • FMOD (UnityAudio disabled)
  • SteamAudio (set to use FMOD)
  • SteamVR

Speaker output is controlled using FMODUnity.RuntimeManager.CoreSystem.setDriver(driverId)
Microphone output is controlled using FMODUnity.RuntimeManager.CoreSystem.recordStart(deviceID, sound, true) and FMODUnity.RuntimeManager.CoreSystem.recordStop(_deviceID)

TEST 1: Just switch between desktop & headset display modes, without changing audio
Everything is fine.

TEST 2: Switch microphone while speakers are running…
=> No FMOD errors reported

TEST 3: Switch speakers while microphone is running…
=> FMOD errors and microphone does not work
[FMOD] OutputWASAPI::recordStart : IMMDeviceEnumerator::GetDevice returned 0x80004003.
FMOD Result: ERR_RECORD

NOTE: When using UnityAudio instead of FMOD the microphone can be switched. (Calling this a “workaround” seems like a stretch, but it does cover some use-cases.)

CROSS-POST: This same issue is posted in the SteamVR project issues: FMOD speaker and microphone switching fails with errors · Issue #1055 · ValveSoftware/steamvr_unity_plugin · GitHub

REQUEST: Additional testing with other hardware configurations.

I do not have equipment to test speaker & microphone switching without using SteamVR… if this bug CANNOT be reproduced on devices that are NOT managed by SteamVR then the issue is entirely with SteamVR.

OBSERVATION: Stopping the microphone recording, switching the device driver and then restarting the microphone recording works… but ONLY if there is a delay between the call to System::setDriver and System::recordStart.

The magic number (for me) is somewhere between 15 & 30 frames (at 90fps Unity update)… but my guess is that the timing (roughly 1/4 second) is what actually matters.

I have reproduced this as you have described, and this does not seem to be exclusive to SteamVR.
The recommended way to handle recording device switching can be found in the Core API record_enumeration example. It’s in C++ but the FMOD API calls are the same and should be fairly straightforward to convert to C#.
If you intend on doing a lot of input device plugging and unplugging and want it to be handled automatically then you can try implementing a FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED callback, reverting to a different recording device when an existing one is lost.

@jeff_fmod thank you for checking on this, and thank you for the example references. In light of your assessment I have closed the issue with SteamVR Unity Plugin.

Since you have confirmed that this is an FMOD issue I’m going to mark the work-around as the solution. If I have misunderstood and there is a way to switch the output device without an arbitrary pause on the input device please let me know.

P.S. To clarify: I am not plugging in or unplugging any devices. I have a laptop with speakers and a microphone, and a VR headset with speakers and microphone. My goal is to switch audio input and output between the headset and the laptop.

Thank you for clarifying, it seems I have misunderstood the original issue here. It seems that the recording device is not available until some time after a device change occurs. I have passed this onto the Dev team to investigate in more detail, thank you for bringing this to our attention!