Microphone bug on Meta Quest 2 and 3 when putting the headset to sleep

Hello,
We’re experiencing a Microphone bug when starting the Microphone the usual way, with Microphone.Start().
What happens on the Quest 2 is that when we put the headset to sleep mode, by pressing the button on the side, the Microphone stops. BUT this bug is inconsistent, at least from our tests, it looks like the Microphone only stops if when coming back from sleep mode on the Quest 2, we get a popup window (like enter passcode, choose user account, etc.). If we don’t get a popup, from our tests, the microphone doesn’t stop.

We don’t like that when starting the microphone on the quest there is always a black frame. Would it be best practice to always start the Microphone when coming back from an OnApplicationPause event?

Do other people have that bug?

It would be great to learn a little bit more about your use case. Are you having issues with the microphone still picking up audible data when the HMD is in sleep mode? Could we get a little more info (i.e. Editor version, code snippets, use case)?

We are using the Microphone API in the VR Multiplayer Template, and I have not seen this bug. Albeit Vivox is doing most of the heavy lifting for voice chat, but we have a simple implementation to show voice activity while offline. You can check out how the VR Multiplayer Template handles Microphone input in the script OfflinePlayerAvatar.cs where you can see the sample in action.

It looks sort of like this.
After we receive the callback that our Microphone Permissions are granted, we then call:

m_Device ??= Microphone.devices[0];
m_ClipRecord = Microphone.Start(m_Device, true, 999, 44100);

Then, in our script that is handling the Microphone API, the OnDisable() function looks sort of like this:

if (Permission.HasUserAuthorizedPermission(Permission.Microphone))
{
    Microphone.End(m_Device);
}

We have some additional checking in there that handles a local “muted” state, and will force set said local muted state if no microphone is detected, etc… but overall this should get you started in the right direction.

Side Note: Possibly completely unrelated, but the Microphone API will sometime behave oddly if you are actively screen recording on your Quest HMD (observed on Quest 2 and Quest 3).

Hope this helps and may the odds be ever in your favor!
-Joegre

Hello Joegre,

Thanks a lot for your answer.
Our issue is not that the Microphone still picks up audio when the HMD is in sleep mode. Our issue is that when we go to sleep mode and then come back, the Microphone doesn’t pickup audio anymore.

Our use case is quite simple, we want to have access to what the user says throughout the entire experience. Therefore, when the user launches the app, we trigger Microphone.Start() and we never stop it.
The issue that we’re facing is that some users manage to break our app by going to sleep mode and then coming back and boom, the application doesn’t recognize their voice.

I have tried it with an empty Unity Scene and a new fresh scene. And this script:

public AudioClip _clipRecord;
public int _sampleWindow = 128;
public float loudness;
public bool _isInitialized;
public string micName;


//mic initialization
void InitMic(){
        if (micName == null || micName == "") micName = Microphone.devices[0];
        //Debug.Log (micName);
        _clipRecord = Microphone.Start(micName, true, 2, 44100);
        //Debug.Log("started mic");
        _isInitialized = true;
       // threshold = mean + 2 * (Mathf.Sqrt(sd));
}
	
	//get data from microphone into audioclip
	float  LevelMax()
	{
		float levelMax = 0;
		float[] waveData = new float[_sampleWindow];
		int micPosition = Microphone.GetPosition(micName)-(_sampleWindow+1); // null means the first microphone
      //Debug.Log(micPosition + " " + Microphone.GetPosition(micName) + " " + (_sampleWindow + 1));
      if (micPosition < 0) return 0;
		_clipRecord.GetData(waveData, micPosition);
		// Getting a peak on the last 128 samples
		for (int i = 0; i < _sampleWindow; i++) {
			float wavePeak = waveData[i] * waveData[i];
			if (levelMax < wavePeak) {
				levelMax = wavePeak;
			}
		}
		return levelMax;
	}

void Update()
{
    if (!_isInitialized)
    {
        InitMic();
    }
    loudness = LevelMax ();
}

If you display the loudness picked up by the Mic, the expected behavior is that when I speak, the loudness goes up.
But what happens once I go to sleep mode & come back is that the loudness stays at the minimum but the Microphone is still marked as recording. So the mic is actually not giving any audio data anymore.

But, the very important thing: this bug ONLY happens if we setup a passcode on the Meta Headset or if we have multiple accounts. Because, when going to sleep mode and coming back, we won’t go back directly to our app, we will first have to enter the passcode & then we’ll come to our app. (Note that this bug happens only when staying 10/15 sec in sleep mode)

So I am pretty sure that when in sleep mode with a passcode the Unity experience is not only paused but loses priority/access from the headset somehow.

Let me know if something isn’t clear, because we have a very clear way to reproduce it.

Best,
Alexis

Here is how we fixed it. For some reasons, there is a bug with the MetaQuest 2 that when we activate passcode & put the headset to sleep. Then the mic has to be restarted.

    private void OnApplicationPause(bool pauseStatus)
    {
        if (pauseStatus)
        {
            StopMicrophone();
        }
        else
        {
            InitMic();
        }
    }
1 Like