Placeholder-Software / Dissonance

Unity Voice Chat Asset
69 stars 5 forks source link

[bug] iPhone sound comes from earpiece instead of the speakerphone #219

Open vladbasin opened 3 years ago

vladbasin commented 3 years ago

Expected Behavior

During voice chat communication the sound must come from speakerphone (or headphones if they are present).

Actual Behavior

During voice chat communication the sound comes from earpiece.

Workaround

Toggle 'Force iOS Speaker while recording' on in unity player settings for iOS. This, however, makes headphones use impossible (the device always switches back to speaker). Which makes this workaround useless.

Your Environment

More notes

There was a fix suggestion by @martindevans in another thread: https://github.com/Placeholder-Software/Dissonance/issues/131

To insert those calls I would suggest creating a custom microphone capture class for Dissonance. You should be able to inherit from Assets/Plugins/Dissonance/Core/Audio/Capture/BasicMicrophoneCapture.cs and simply insert your calls into the StartCapture and StopCapture methods in the correct places. Something like this:

class FixedIosMicrophoneCapture
  : BasicMicrophoneCapture
{
    override WaveFormat StartCapture(string name)
    {
        // Do this before mic is started
        iPhoneSpeaker.CheckiOSPrepare();

        // Now invoke the usual mic starting behaviour
        return base.StartCapture(name);
    }

    override void StopCapture()
    {
        // Invoke normal mic ending behaviour
        base.StopCapture();

        // Do this after mic is stopped
        iPhoneSpeaker.ForceToSpeaker();
    }
}

To do this you will need to modify the methods in the base class to be virtual.

This script does not fix the issue. The sound is still coming from the mic. After debugging I have discovered that for some reason, StopCapture() has never been called, therefore iPhoneSpeaker.ForceToSpeaker() is not called either. StopCapture() is called only AFTER client is disconnected. Therefore, no iPhoneSpeaker.ForceToSpeaker() is called during the game (should be called after Microphone.Start(...)). Tried to call iPhoneSpeaker.ForceToSpeaker() in StartCapture() - no voice captured happens at all.

martindevans commented 3 years ago

Unfortunately I don't think it's possible to fix this in Unity+iOS.

Unity+iOS auto switches the audio output as soon as Microphone.Start is called - the only way to override this within Unity (that I am aware of) is the Force iOS Speaker while recording setting, which is certainly not ideal!

UnitySpeakerFix looks to be two years out of date, so is probably no longer a workable solution. It also only allows you to force to speakers at runtime, so suffers the same issue as the Force iOS Speaker while recording setting.

StopCapture() has never been called

StopCapture is called when Dissonance no longer wants mic input - i.e. when the player leaves the session.

vladbasin commented 3 years ago

@martindevans thanks for the input.

I think it is quite critical for this library to work correctly with headphones\speakers scenarios on iOS devices. This is what really required for acceptable game experience.

And looks like I have found a way to make it working without changing Unity settings. However, I would appreciate your advice as this lib code owner\expert.

I wrote a native script in Objective C that detects headphones and if they are not plugged in, it forces speakers. However, once the user plugs in headphones, he cannot be heard anymore. I assume that it happens because BasicMicrophoneCapture stops capturing (maybe operation system internal switches break something).

Do you know how can I force BasicMicrophoneCapture to 're-initialize'? As the workaround, I can detect this scenario and force Dissonance to re-initialize

vladbasin commented 3 years ago

I have started game on iOS with EarPods plugged in and the user cannot be heard by anyone. Does Dissonance support headset microphone?

EarPods is default iPhone's headset: image

vladbasin commented 3 years ago

Ok, it seems that I have managed to fix all speaker\earpiece\headset related issues of Dissonance library that I found on iPhone. I can conclude that unfortunately, Dissonance does not play well with iOS devices :(

What I did to make voice chat experience smooth:

Going to test how things work on Android next week. Hope it will be more reliable than on iOS.

martindevans commented 3 years ago

how can I force BasicMicrophoneCapture to 're-initialize'?

You can call ResetMicrophoneCapture on the DissonanceComms script to force the entire microphone capture system to re-initialise.

Does Dissonance support headset microphone?

Dissonance uses the Unity Microphone class in BasicMicrophoneCapture. So if Unity supports it Dissonance does. It's possible to replace this class with a custom mic capture script if that's needed.

workaround the issue that AudioSettings.OnAudioConfigurationChanged

Ouch, that's a bad bug! If this isn't being triggered it will definitely cause issues. How did you work around it in this case?

cemkoker commented 3 years ago

+1 I'd be also interested if you manage to have a reliable audio switching on iOS.

bryanmtg commented 3 years ago

@vladbasin are you able to share the scripts and steps to fix this if it is working on iOS?

Currently stuck on this issue and would be much appreciated!!

dimmduh commented 1 year ago

I deleted Dissonance from project 2 years ago because of this bug. Was it fixed?

martindevans commented 1 year ago

I'm not completely sure what the situation is on iOS right now - the problems were always an unfortunate confluence of Unity issues (e.g. not properly invoking the callback when devices change) and iOS issues (e.g. automatically using the call speaker when the mic is in use).

FWIW I believe the situation should be much better - no one has contacted me with any issues regarding this for a long time. I'm also going to be working with a customer on their app (developing some custom features for them, specifically for iOS), so if there are any remaining issues I'll hopefully be able to work through them with them.

Rica02 commented 1 month ago

We are having this issue right now on both iOS and Android. Our project has a voice chat feature using Dissonance, and when the user is muted, the audio comes from the speakerphone. When unmuted, the audio comes faintly from the earpiece. This behaviour has been consistent with different models of iPhones, iPad and Pixel phones.

Things I've tried:

iOS workarounds are not working and I've heard absolutely nothing about a workaround for Android. This is quite problematic for us, everything else about Dissonance has been smooth except for this issue. Does anyone have any updated workaround or ideas?

Using Unity 2021.3.19f1.