IOS - Sound plays through receiver when using voice chat

Hi

Our project requires enabling voice chat while playing sounds through fmod at the same time. However sound does not play as expected when AVAudioSession category and mode are configured for voice chat.

Reproduction steps are as follows.

  1. Start playing any sound (UFMODAudioComponent::Play)
  2. Call IOSAppDelegate::EnableVoiceChat and IOSAppDelegate::EnableHighQualityVoiceChat. (This is equivalent to calling AVAudioSession::setCategory with AVAudioSessionCategoryPlayAndRecord with mode AVAudioSessionModeVoiceChat with options AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionMixWithOthers)
  3. Sound starts playing through both the speaker and the receiver. (If was connected to a bluetooth device, sound stops).

We expect that sound plays though only the speaker (not the reciever), and when connected to a bluetooth device, through that device only.

Everything is ok when voice chat is not enabled, but our voice chat module (Vivox) requires that we set AVAudioSessionCategory to those listed above.

Thanks

I have not been able to reproduce this issue. Can you please tell me what version of FMOD and Unreal you are using?

We are using ue4 4.27.2 and FMOD 2.02.09.

After your reply I found out that the issue might have something to do with the IOS version. We have two iPhone 8 devices one with IOS version 15.5 and one with 15.6.1. I installed the same ipa file to both devices and the issue was reproduced on 15.6.1 and not on 15.5

Below is the code I used.

	TSoftObjectPtr<UFMODEvent> Event{ FSoftObjectPath{ TEXT("PATH") } };
	FMODAudio->SetEvent(Event.LoadSynchronous());
	FMODAudio->Play();

	[[IOSAppDelegate GetDelegate] EnableVoiceChat: YES];
	[[IOSAppDelegate GetDelegate] EnableHighQualityVoiceChat: YES];

Thanks again for your help

Thank you for the additional information. After some discussion with the development team I’m not sure there is much we can do about this issue unfortunately; we don’t have any control over which output device we send audio to on iOS as this is handled by AVAudioSessionCategory / AVAudioSessionCategoryOptions, which are expected to be set by the user depending on their unique requirements. If you are finding this issue does not reproduce with regular Unreal audio however then there may be an issue with FMOD that we can investigate further.
Does the bluetooth issue still reproduce on 15.5? I saw in the Vivox docs that you also need to set AVAudioSessionCategoryOptionAllowBluetooth and/or AVAudioSessionCategoryOptionAllowBluetoothA2DP to allow audio to send to a bluetooth device, which may be worth investigating if you haven’t yet.

Yes, the bluetooth issue is still reproduced and it might not have been related to IOS version after all. I tested with another iPhone 12 device with IOS 15.5 installed and it was no different than with 15.6.1. It might be that the device that looked normal happened to have its receiver broken. I’m sorry for the misinformation.

When tested with the default audio library, sound did play with a bluetooth device although it was quite laggy for some reason. Below is the code I used. (EAudioFeature::BluetoothMicrophone sets AVAudioSessionCategoryOptionAllowBluetooth)

	TSoftObjectPtr<USoundWave> Event{ FSoftObjectPath{ TEXT("PATH'") } };
	UGameplayStatics::PlaySound2D(this, Event.LoadSynchronous());

	[[IOSAppDelegate GetDelegate] SetFeature: EAudioFeature::BluetoothMicrophone Active: YES];
	[[IOSAppDelegate GetDelegate] EnableVoiceChat: YES];
	[[IOSAppDelegate GetDelegate] EnableHighQualityVoiceChat: YES];

Thanks

Apologies for the delayed response, and thank you for the additional information. Unfortunately I have still been unable to reproduce this issue; does removing the AVAudioSessionCategoryOptionDefaultToSpeaker flag help at all? That is the only one I can see in the AVAudioSession docs that might explain why it is being forced to the receiver and not the bluetooth headset.
Bluetooth does have significantly more latency than a wired connection. There are a few things you can do to try to reduce latency which you can find in the Platforms | iOS section of the docs.

Hi. I’m sorry for the delayed reply. We are still experiencing the issue even with the AVAudioSessionCategoryOptionDefaultToSpeaker suggestion. I’m re-listing the exact setup and reproduction steps here to avoid any confusion.

Mobile Device: iPhone 12 with IOS 15.5
Bluetooth Device: Samsung Galaxy Buds Pro
UE4 version: 4.27 built from source with minimal modification in IOSToolChain.cs to ignore unused variable errors with Xcode 13
FMOD version: 2.02.09 for UE4.27

Issue: Sound does not play with the following code. (Sound plays normally if IOSAppDelegate calls are removed)

	TSoftObjectPtr<UFMODEvent> Event{ FSoftObjectPath{ TEXT("FMODEvent'/Game/FMOD/Events/BGM_New/InGame/BGM_Game_Loading.BGM_Game_Loading'") } };
	FMODAudio->SetEvent(Event.LoadSynchronous());
	FMODAudio->Play();

	[[IOSAppDelegate GetDelegate] SetFeature: EAudioFeature::BluetoothMicrophone Active: YES];
	[[IOSAppDelegate GetDelegate] SetFeature: EAudioFeature::UseReceiver Active: YES];
	[[IOSAppDelegate GetDelegate] EnableVoiceChat: YES];
	[[IOSAppDelegate GetDelegate] EnableHighQualityVoiceChat: YES];

FMOD settings in the project are as defaulted.

I will send you a minimal project that demonstrates the issue (at least on my device) if it is okay with you.

Thanks again for your help.

A minimal reproduction would be appreciated as I still haven’t been able to reproduce this issue unfortunately. If you could please upload it to your FMOD Profile I will take a look.

I uploaded a link to the project on this account’s profile. Please have a look and let me know if you have any issues building the project.

Thanks

Thank you for sending that over, I can reproduce the initial issue of audio outputting through the receiver, but I am finding bluetooth is behaving as expected on my test device.
Audio outputting through the receiver is expected behaviour when using the UseReceiver feature. On iOS the output device is set by IOSAppDelegate calls, as you have done here, and we do not have any additional control over which speaker to send audio to. If I remove the UseReceiver line from your repro or change it to NO, audio outputs through the speaker on iOS:

[[IOSAppDelegate GetDelegate] SetFeature: EAudioFeature::UseReceiver Active: NO];

I am also finding that FMOD is behaving exactly the same as Unreal’s built-in audio system, both in regards to outputting through the receiver and bluetooth device connection.

Can you please try removing the call to SetFeature: EAudioFeature::UseReceiver and see if that results in audio outputting from your device’s speaker instead of the receiver?