MaxLocalTalkers

MaxLocalTalkers

#Overview

name: MaxLocalTalkers

The value of this variable can be defined or overridden in .ini config files. 1 .ini config file referencing this setting variable.

It is referenced in 20 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of MaxLocalTalkers is to define the maximum number of local players that can use voice communication in an Unreal Engine game. This setting variable is primarily used in the voice communication system of the engine.

MaxLocalTalkers is utilized by the Online Subsystem and Voice Interface modules within Unreal Engine 5. Specifically, it’s used in the implementation of voice engines (FVoiceEngineImpl) and voice interfaces (FOnlineVoiceImpl).

The value of this variable is typically set in the DefaultEngine.ini configuration file under the [OnlineSubsystem] section. If not specified in the configuration, it defaults to MAX_SPLITSCREEN_TALKERS, which is likely a predefined constant.

MaxLocalTalkers interacts closely with MaxRemoteTalkers, which defines the maximum number of remote players that can communicate via voice. Together, these variables determine the overall capacity of the voice communication system.

Developers must be aware that this variable affects memory allocation and performance. Setting it too high might waste resources, while setting it too low could limit the number of local players able to use voice chat.

Best practices when using this variable include:

  1. Set it appropriately based on the maximum number of local players your game supports.
  2. Ensure it’s properly configured in the DefaultEngine.ini file.
  3. Consider the implications on memory usage and adjust accordingly.
  4. Test voice functionality thoroughly with different numbers of local talkers up to the maximum.
  5. Be aware of how changes to this value might affect existing voice communication code in your project.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEngine.ini:2232, section: [OnlineSubsystem]

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/VoiceInterface.h:57

Scope (from outer to inner):

file
class        class IVoiceEngine

Source code excerpt:

	 * Initialize the voice engine
	 * 
	 * @param MaxLocalTalkers maximum number of local talkers to support
	 * @param MaxRemoteTalkers maximum number of remote talkers to support
	 */
	virtual bool Init(int32 MaxLocalTalkers, int32 MaxRemoteTalkers) = 0;

public:
	/** Virtual destructor to force proper child cleanup */
	virtual ~IVoiceEngine() {}

	/**
	 * Starts local voice processing for the specified user index
	 *

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/OnlineSubsystemUtils.cpp:357

Scope (from outer to inner):

file
function     bool HandleVoiceCommands

Source code excerpt:

		}

		int32 MaxLocalTalkers = 0;
		if (!GConfig->GetInt(TEXT("OnlineSubsystem"), TEXT("MaxLocalTalkers"), MaxLocalTalkers, GEngineIni))
		{
			UE_LOG_ONLINE_VOICE(Warning, TEXT("Missing MaxLocalTalkers key in OnlineSubsystem of DefaultEngine.ini"));
		}

		int32 MaxRemoteTalkers = 0;
		if (!GConfig->GetInt(TEXT("OnlineSubsystem"), TEXT("MaxRemoteTalkers"), MaxRemoteTalkers, GEngineIni))

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/OnlineSubsystemUtils.cpp:402

Scope (from outer to inner):

file
function     bool HandleVoiceCommands

Source code excerpt:

		UE_LOG_ONLINE_VOICE(Display, TEXT("Voice Interface Enabled: %s"), bHasVoiceInterfaceEnabled ? TEXT("true") : TEXT("false"));
		UE_LOG_ONLINE_VOICE(Display, TEXT("Ducking Opt Out Enabled: %s"), bDuckingOptOut ? TEXT("true") : TEXT("false"));
		UE_LOG_ONLINE_VOICE(Display, TEXT("Max Local Talkers: %d"), MaxLocalTalkers);
		UE_LOG_ONLINE_VOICE(Display, TEXT("Max Remote Talkers: %d"), MaxRemoteTalkers);
		UE_LOG_ONLINE_VOICE(Display, TEXT("Notification Delta: %0.2f"), VoiceNotificationDelta);
		UE_LOG_ONLINE_VOICE(Display, TEXT("Voice Requires Push To Talk: %s"), bRequiresPushToTalk ? TEXT("true") : TEXT("false"));

		TArray<FString> OutArray;
		VoiceDump.ParseIntoArray(OutArray, TEXT("\n"), false);

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/VoiceEngineImpl.cpp:270

Scope (from outer to inner):

file
function     bool FVoiceEngineImpl::Init

Source code excerpt:

}

bool FVoiceEngineImpl::Init(int32 MaxLocalTalkers, int32 MaxRemoteTalkers)
{
	bool bSuccess = false;

	IOnlineSubsystem* OnlineSub = GetOnlineSubSystem();

	if (OnlineSub && !OnlineSub->IsDedicated())

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/VoiceEngineImpl.cpp:289

Scope (from outer to inner):

file
function     bool FVoiceEngineImpl::Init

Source code excerpt:

				DecompressedVoiceBuffer.Empty(UVOIPStatics::GetMaxUncompressedVoiceDataSizePerChannel());

				for (int32 TalkerIdx = 0; TalkerIdx < MaxLocalTalkers; TalkerIdx++)
				{
					PlayerVoiceData[TalkerIdx].VoiceRemainderSize = 0;
					PlayerVoiceData[TalkerIdx].VoiceRemainder.Empty(MAX_VOICE_REMAINDER_SIZE);
				}
			}
			else

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/VoiceInterfaceImpl.cpp:26

Scope (from outer to inner):

file
function     bool FOnlineVoiceImpl::Init

Source code excerpt:

	bool bSuccess = false;

	if (!GConfig->GetInt(TEXT("OnlineSubsystem"),TEXT("MaxLocalTalkers"), MaxLocalTalkers, GEngineIni))
	{
		MaxLocalTalkers = MAX_SPLITSCREEN_TALKERS;
		UE_LOG_ONLINE_VOICE(Warning, TEXT("Missing MaxLocalTalkers key in OnlineSubsystem of DefaultEngine.ini"));
	}
	if (!GConfig->GetInt(TEXT("OnlineSubsystem"),TEXT("MaxRemoteTalkers"), MaxRemoteTalkers, GEngineIni))
	{
		MaxRemoteTalkers = MAX_REMOTE_TALKERS;
		UE_LOG_ONLINE_VOICE(Warning, TEXT("Missing MaxRemoteTalkers key in OnlineSubsystem of DefaultEngine.ini"));

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/VoiceInterfaceImpl.cpp:58

Scope (from outer to inner):

file
function     bool FOnlineVoiceImpl::Init

Source code excerpt:

			{
				VoiceEngine = CreateVoiceEngine();
				bSuccess = VoiceEngine->Init(MaxLocalTalkers, MaxRemoteTalkers);
			}
			else
			{
				MaxLocalTalkers = 0;
				MaxRemoteTalkers = 0;
			}
		}

		LocalTalkers.Init(FLocalTalker(), MaxLocalTalkers);
		RemoteTalkers.Empty(MaxRemoteTalkers);

		if (!bSuccess)
		{
			// Not necessary to log here since VoiceEngine::Init() will report its own failure
			//UE_LOG_ONLINE_VOICE(Warning, TEXT("Failed to initialize voice interface"));

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/VoiceInterfaceImpl.cpp:137

Scope (from outer to inner):

file
function     void FOnlineVoiceImpl::StartNetworkedVoice

Source code excerpt:

{
	// Validate the range of the entry
	if (LocalUserNum >= 0 && LocalUserNum < MaxLocalTalkers)
	{
		LocalTalkers[LocalUserNum].bHasNetworkedVoice = true;
		if (VoiceEngine.IsValid())
		{
			uint32 Return = VoiceEngine->StartLocalVoiceProcessing(LocalUserNum);
			UE_LOG_ONLINE_VOICE(Log, TEXT("StartLocalProcessing(%d) returned 0x%08X"), LocalUserNum, Return);

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/VoiceInterfaceImpl.cpp:157

Scope (from outer to inner):

file
function     void FOnlineVoiceImpl::StopNetworkedVoice

Source code excerpt:

{
	// Validate the range of the entry
	if (LocalUserNum >= 0 && LocalUserNum < MaxLocalTalkers)
	{
		if (VoiceEngine.IsValid())
		{
			uint32 Return = VoiceEngine->StopLocalVoiceProcessing(LocalUserNum);
			UE_LOG_ONLINE_VOICE(Log, TEXT("StopLocalVoiceProcessing(%d) returned 0x%08X"), LocalUserNum, Return);
		}

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/VoiceInterfaceImpl.cpp:177

Scope (from outer to inner):

file
function     bool FOnlineVoiceImpl::RegisterLocalTalker

Source code excerpt:

{
	uint32 Return = ONLINE_FAIL;
	if (LocalUserNum >= 0 && LocalUserNum < (uint32)MaxLocalTalkers)
	{
		// Get at the local talker's cached data
		FLocalTalker& Talker = LocalTalkers[LocalUserNum];
		// Make local user capable of sending voice data
		StartNetworkedVoice(uint8(LocalUserNum));
		// Don't register talkers when voice is disabled

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/VoiceInterfaceImpl.cpp:228

Scope (from outer to inner):

file
function     void FOnlineVoiceImpl::RegisterLocalTalkers

Source code excerpt:

	UE_LOG_ONLINE_VOICE(Log, TEXT("Registering all local talkers"));
	// Loop through the 4 available players and register them
	for (uint32 Index = 0; Index < (uint32)MaxLocalTalkers ; Index++)
	{
		// Register the local player as a local talker
		RegisterLocalTalker(Index);
	}
}

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/VoiceInterfaceImpl.cpp:238

Scope (from outer to inner):

file
function     bool FOnlineVoiceImpl::UnregisterLocalTalker

Source code excerpt:

{
	uint32 Return = ONLINE_SUCCESS;
	if (LocalUserNum >= 0 && LocalUserNum < (uint32)MaxLocalTalkers)
	{
		// Get at the local talker's cached data
		FLocalTalker& Talker = LocalTalkers[LocalUserNum];
		// Skip the unregistration if not registered
		if (Talker.bIsRegistered == true &&
			// Or when voice is disabled

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/VoiceInterfaceImpl.cpp:281

Scope (from outer to inner):

file
function     void FOnlineVoiceImpl::UnregisterLocalTalkers

Source code excerpt:

	UE_LOG_ONLINE_VOICE(Log, TEXT("Unregistering all local talkers"));
	// Loop through the 4 available players and unregister them
	for (uint32 Index = 0; Index < (uint32)MaxLocalTalkers; Index++)
	{
		// Unregister the local player as a local talker
		UnregisterLocalTalker(Index);
	}
}

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/VoiceInterfaceImpl.cpp:427

Scope (from outer to inner):

file
function     bool FOnlineVoiceImpl::IsMuted

Source code excerpt:

bool FOnlineVoiceImpl::IsMuted(uint32 LocalUserNum, const FUniqueNetId& UniqueId) const
{
	if (LocalUserNum >= 0 && LocalUserNum < (uint32)MaxLocalTalkers)
	{
		return IsLocallyMuted(UniqueId);
	}

	return false;
}

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/VoiceInterfaceImpl.cpp:450

Scope (from outer to inner):

file
function     bool FOnlineVoiceImpl::MuteRemoteTalker

Source code excerpt:

{
	uint32 Return = ONLINE_FAIL;
	if (LocalUserNum >= 0 && LocalUserNum < MaxLocalTalkers )
	{
		if (bIsSystemWide)
		{
			// Add them to the system wide mute list
			SystemMuteList.AddUnique(FUniqueNetIdWrapper(PlayerId.AsShared()));
			// Should update MuteList after going up to the server and coming back down

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/VoiceInterfaceImpl.cpp:492

Scope (from outer to inner):

file
function     bool FOnlineVoiceImpl::UnmuteRemoteTalker

Source code excerpt:

{
	uint32 Return = ONLINE_FAIL;
	if (LocalUserNum >= 0 && LocalUserNum < MaxLocalTalkers )
	{
		if (bIsSystemWide)
		{
			// Remove them from the system wide mute list
			SystemMuteList.RemoveSingleSwap(FUniqueNetIdWrapper(PlayerId.AsShared()));
			// Should update MuteList after going up to the server and coming back down

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/VoiceInterfaceImpl.cpp:544

Scope (from outer to inner):

file
function     void FOnlineVoiceImpl::ProcessMuteChangeNotification

Source code excerpt:

		{
			// For each local user with voice
			for (int32 Index = 0; Index < MaxLocalTalkers; Index++)
			{
				// Use the common method of checking muting
				UpdateMuteListForLocalTalker(Index);
			}
		}
	}

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Public/VoiceEngineImpl.h:262

Scope (from outer to inner):

file
class        class FVoiceEngineImpl : public IVoiceEngine, public FSelfRegisteringExec, public IDeviceChangedListener

Source code excerpt:


	// IVoiceEngine
	virtual bool Init(int32 MaxLocalTalkers, int32 MaxRemoteTalkers) override;

public:

	FVoiceEngineImpl(IOnlineSubsystem* InSubsystem);
	virtual ~FVoiceEngineImpl();

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Public/VoiceInterfaceImpl.h:21

Scope (from outer to inner):

file
class        class FOnlineVoiceImpl : public IOnlineVoice

Source code excerpt:


	/** Maximum permitted local talkers */
	int32 MaxLocalTalkers;
	/** Maximum permitted remote talkers */
	int32 MaxRemoteTalkers;

	/** State of all possible local talkers */
	TArray<FLocalTalker> LocalTalkers;
	/** State of all possible remote talkers */

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Public/VoiceInterfaceImpl.h:75

Scope (from outer to inner):

file
class        class FOnlineVoiceImpl : public IOnlineVoice

Source code excerpt:

		IdentityInt(NULL),
		VoiceEngine(NULL),
		MaxLocalTalkers(MAX_SPLITSCREEN_TALKERS),
		MaxRemoteTalkers(MAX_REMOTE_TALKERS),
		VoiceNotificationDelta(0.0f)
	{};

	// IOnlineVoice
	virtual bool Init() override;