Steam Voice Chat Cutting Out

Hey ,

Having VOIP work for dedicated servers is also a big priority for our game. I tried to implement the following pull request to enable VOIP over dedicated servers: https://github.com/EpicGames/UnrealEngine/pull/1661/files but had similar issues where the voice would drop out (in 4.12).

In debugging this myself I found that moving the line ‘QueuedData->AudioComponent->Play();’ to the end of the ‘FVoiceEngineSteam::SubmitRemoteVoiceData(…)’ function fixed voice from dropping out however the audio would cut in and out and with lots of players became unintelligible. But I think the logic surrounding when to play voice data may be the culprit. Hoping this may help Epic address this sooner! Here is the function in question:

uint32 FVoiceEngineSteam::SubmitRemoteVoiceData(const FUniqueNetId& RemoteTalkerId, uint8* Data, uint32* Size) 
{
	UE_LOG(LogVoiceDecode, VeryVerbose, TEXT("SubmitRemoteVoiceData(%s) Size: %d received!"), *RemoteTalkerId.ToDebugString(), *Size);

	const FUniqueNetIdSteam& SteamId = (const FUniqueNetIdSteam&)RemoteTalkerId;
	FRemoteTalkerDataSteam* QueuedData = RemoteTalkerBuffers.Find(SteamId);

	if (QueuedData == NULL)
	{
		RemoteTalkerBuffers.Add(SteamId, FRemoteTalkerDataSteam());
		QueuedData = RemoteTalkerBuffers.Find(SteamId);
	}

	check(QueuedData);

	// new voice packet.
	QueuedData->LastSeen = FPlatformTime::Seconds();

	uint32 BytesWritten = 0;

	DecompressedVoiceBuffer.Empty(MAX_UNCOMPRESSED_VOICE_BUFFER_SIZE);
	DecompressedVoiceBuffer.AddUninitialized(MAX_UNCOMPRESSED_VOICE_BUFFER_SIZE);
	const EVoiceResult VoiceResult = SteamUserPtr->DecompressVoice(Data, *Size, DecompressedVoiceBuffer.GetData(),
		DecompressedVoiceBuffer.Num(), &BytesWritten, SteamUserPtr->GetVoiceOptimalSampleRate());

	if (VoiceResult != k_EVoiceResultOK)
	{
		UE_LOG(LogVoiceDecode, Warning, TEXT("SubmitRemoteVoiceData: DecompressVoice failure: VoiceResult: %s"), *SteamVoiceResult(VoiceResult));
		*Size = 0;
		return E_FAIL;
	}

	// If there is no data, return
	if (BytesWritten <= 0)
	{
		*Size = 0;
		return S_OK;
	}

	// Generate a streaming wave audio component for voice playback
	if (QueuedData->AudioComponent == NULL || QueuedData->AudioComponent->IsPendingKill())
	{
		if (SerializeHelper == NULL)
		{
			SerializeHelper = new FVoiceSerializeHelper(this);
		}

		QueuedData->AudioComponent = CreateVoiceAudioComponent(SteamUserPtr->GetVoiceOptimalSampleRate());
		if (QueuedData->AudioComponent)
		{
			QueuedData->AudioComponent->OnAudioFinishedNative.AddRaw(this, &FVoiceEngineSteam::OnAudioFinished);
            //QueuedData->AudioComponent->Play();
		}
	}

	if (QueuedData->AudioComponent != NULL)
	{
		USoundWaveProcedural* SoundStreaming = CastChecked<USoundWaveProcedural>(QueuedData->AudioComponent->Sound);
		if (SoundStreaming->GetAvailableAudioByteCount() == 0)
		{
			UE_LOG(LogVoiceDecode, Log, TEXT("VOIP audio component was starved!"));
		}
		SoundStreaming->QueueAudio(DecompressedVoiceBuffer.GetData(), BytesWritten);
		QueuedData->AudioComponent->Play(); //moved Play() to come after QueueAudio(...)
	}

	return S_OK;
}