LAN voice chat abruptly stops playback

In a LAN session, when someone sends voice data to another computer, the audio plays a single packet’s worth of voice and then just stops, even though there is still a steady stream of voice packets being sent and received. The receiver will continue to not play any voice audio, though the voice data is still being queued up. The sender must stop sending, and then start sending after some delay (around 1 second of silence) . Then the receiver will start playing all the queued up voice audio, and all the new audio must wait until the old audio is played back.

For consistent testing, I am using the ‘Stereo Mix’ recording device in Windows, which uses my computer’s audio output as microphone input.

Steps:

  1. Setup a simple blueprints LAN session, with voice enabled, voice always on (push to talk is off)
  2. Have a client send some voice (a song sent thru ‘Stereo Mix’ for easier and more consistent testing)
  3. Observe the receiver playing a tiny blip of audio and then silence
  4. Stop the song for a few seconds, then resume it
  5. Observe the receiver starting to play the start of the song which had been queued up

Here are some of my settings:

DefaultEngine.ini

[OnlineSubsystem]
DefaultPlatformService=Null
bHasVoiceEnabled=true

[Voice]
bEnabled=true

[/Script/OnlineSubsystemUtils.IpNetDriver]
MaxClientRate=30000
MaxInternetClientRate=30000

[/Script/Engine.Player]
ConfiguredLanSpeed=30000
ConfiguredInternetSpeed=30000

DefaultGame.ini

[/Script/Engine.GameSession]
bRequiresPushToTalk=false

I investigated by littering the source with logs, and discovered some useful info. Upon receiving the first voice packet, the voice engine consumes it, but then the buffer runs dry before the next voice packet arrives and the voice engine stops playback or stalls or something. When the next voice packet does arrive, it gets queued up in SoundWaveProcedural’s QueuedAudio, but the voice engine is still stuck or stopped or something. The only way to get it unstuck is to stop sending voice packets for some time, and then to resume sending them (basically have some period of silence). Then the voice engine will start playing through the queued voice data again.

I have a possible solution that appears to work, but I’m sure there is a better, more proper fix.

In VoiceEngineImpl.h, I added:

/** Is in process of queueing up some data to come back from starvation */
	bool bRestartFromStarvation;

In VoiceEngineImpl.cpp, function SubmitRemoteVoiceData, at the bottom inside the last big if:

if (!QueuedData.AudioComponent->IsActive())
{
	QueuedData.AudioComponent->Play();
}

USoundWaveProcedural* SoundStreaming = CastChecked<USoundWaveProcedural>(QueuedData.AudioComponent->Sound);

if (!bAudioComponentCreated && SoundStreaming->GetAvailableAudioByteCount() == 0)
{
	// VOIP audio component was starved! This used to be a log inside an if(0). I added the following assignment
	bRestartFromStarvation = true;
}

SoundStreaming->QueueAudio(DecompressedVoiceBuffer.GetData(), BytesWritten);

// I added this part too. If we are starved, hold out until we have some cushion so that we can play the audio without micro-stutters due to small packet timing inconsistencies. Then restart the audio component so it starts playing again
if (bRestartFromStarvation && SoundStreaming->GetAvailableAudioByteCount() >= (int32)(VOICE_SAMPLE_RATE * sizeof(int16) / 2))
{
	bRestartFromStarvation = false;

	QueuedData.AudioComponent->Stop();
	QueuedData.AudioComponent->Play();
}

I hope that helps, let me know if I can help clarify anything!

Hello AadarshPatel,

After reading over your post I noticed that you appear to have a solution to the issue that you mentioned. I would suggest submitting a pull request to the developers. Once that is done it will under go further investigation. I have provided a link below. Thank you for your time and information.

Pull request page: https://github.com/EpicGames/UnrealEngine/compare?expand=1

Make it a great day

I also found we have this issue in 4.12.3 on the headsets. We have implemented Aadarsh’s fix into the VoiceEngineSteam.h/.cpp instead of VoiceEngineImpl as those didn’t seem to be being hit and it sorts our issue, however looking back at 4.11.2 code, it looks to be relatively the same, so I don’t know where this issue was introduced from.