Changing SoundNodeBranch's Parameter at runtime causes audio to stop or restart

Hello,

I am experiencing the following issue in UE4.9.2:

  1. Create a SoundCue that contains a “Branch” node
  2. Add an AudioComponent to the player pawn that plays the given sound Cue.
  3. At runtime (say on player input), make a change to the Parameter that is used by the Branch node (using UAudioComponent::SetBoolParameter)
  4. Note that the first time the change is made, the sound being played restarts from the beginning
  5. Note that the second time the change is made, the sound being plays stops playing
  6. Note that subsequent calls to the function have no effect, and that calling UAudioComponent::IsPlaying returns false.

Expected result: Calling UAudioComponent::SetBoolParameter does not restart or stop the playing audio.

This appears to be caused by the change in NodeWaveInstanceHash in the function USoundNodeBranch::ParseNodes:

void USoundNodeBranch::ParseNodes( FAudioDevice* AudioDevice, const UPTRINT NodeWaveInstanceHash, FActiveSound& ActiveSound, const FSoundParseParameters& ParseParams, TArray<FWaveInstance*>& WaveInstances )
{
	BranchPurpose BranchToUse = BranchPurpose::ParameterUnset;
	bool bParamValue = false;

	if (ActiveSound.GetBoolParameter( BoolParameterName, bParamValue ))
	{
		BranchToUse = (bParamValue ? BranchPurpose::ParameterTrue : BranchPurpose::ParameterFalse);
	}


	const int32 ChildNodeIndex = (int32)BranchToUse;
	if (ChildNodeIndex < ChildNodes.Num() && ChildNodes[ChildNodeIndex])
	{
		ChildNodes[ChildNodeIndex]->ParseNodes(AudioDevice, GetNodeWaveInstanceHash(NodeWaveInstanceHash, ChildNodes[ChildNodeIndex], ChildNodeIndex), ActiveSound, ParseParams, WaveInstances);
	}
}

When the bool parameter changes, the BranchToUse value is different. This in turn causes a different ChildNodeIndex to be set, and so different parameters are passed into USoundNode::GetNodeWaveInstanceHash, resulting in a different NodeWaveInstanceHash after the parameter is set, compared to before. Then, in USoundWave::Parse, the call to FActiveSound::FindWaveInstance returns NULL, which causes a new WaveInstance to be created and started, via USoundWave::HandleStart. This is the cause of the audio restarting (step 4)

When the bool parameter changes back to its original value, the NodeWaveInstanceHash returns to its original value also. Then, the call to FActiveSound::FindWaveInstance finds the WaveInstance that was playing before the first parameter change. This WaveInstance, however, has bIsFinished already set to true, which causes the Audio system to flag that the audio finished playing (step 5). This in turn is propegated to the AudioComponent’s bIsActive flag, and thus IsPlaying() returns false (step 6).

Is this the expected behaviour? Are changes to audio parameters at runtime supported?

Thanks,

,

Hello ,

Thank you for the detailed report and for bringing this issue to our attention. I was able to reproduce the issue that you’re seeing where the audio cue restarts when the boolean is changed, however I’m not having the behavior where it stops entirely. This may be due to the differing ways that we are using these branches. Even though, I do not believe it is intended that this should restart the sound cue each time so I’ve placed a bug report into our system for the issue under the number UE-21848. I’ll be sure to update you here when further progress has been made.

Have a nice day!

Hi ,
thanks for your reply. Please let me know if you have any questions regarding my repro steps. I look forward to hearing from you.

Hi , thanks for your reply.
The only relevant card I can find in Trello is “Full Audio System rewrite/refactor”, which has no additional information and a target date of “Wishlist”. Can you give any more information regarding what this will involve and when it will likely be available for use?

In the meantime, can you provide any possible workaround for the bug?

Thanks,

The bug report has been updated and has been marked to not be fixed at this time. The reasoning is that the audio system itself will be overhauled or replaced in the future. Due to this, they plan to make the fix a feature of this new system rather than fixing it in the current system. You can find more information about what features are upcoming here: Trello

Unfortunately we don’t have any information as to when that new audio system will be released or the features of it at the moment.

As far as a workaround, if these branches need to be used and changed while playing, the only thing I could think of would be to use a timer. I’m not sure that it would result in seamless playback, but you could use a timer to track how long the sound cue has been playing and then, in the same function that changes the boolean parameter, set it to play from that point.

Thanks . That workaround appears to work fine, at least on PC.

I’d be very interested in some details about this new audio system, as I’m currently working on a project with a lot of potential to stretch the audio system to its limits. Can you say the reasoning behind such a major refactor?

The reason would be the same reason that Sequencer is being added to replace certain features. The work toward updating these features is being done in sections and when it comes to doing it that way, it is easier and more efficient to do an overhaul than to steadily add features that fix various things in the audio system and may introduce other issues. Unfortunately, as the engine has a multitude of features, this is a lengthy process so it may be some time before we reach certain features.