SoundControlBusMix Multiple activations

Good morning,

I am working on the Audio settings page for our game and I am facing an issue with SoundControlBusMix being “activated” more than once. We have a setup with a Master mix, and a user settings Mix. The master Mix has N stages never modified for now and the User Settings one has the same stages that we modify in response to the slider on the UI. You can think of this setup as extremely similar to the one used in the Lyra project. The problem happens seemingly unreliably and randomly and manifests itself simply by not changing the values in the mix anymore. So every call to UAudioModulationStatics::UpdateMix(…) stop having effect at all, where it used to behave correctly just a moment before. Another effect of the issue is that once this apparent “disconnect” happens if any code path calls UAudioModulationStatics::ActivateBusMix() again the system goes back to working but this newly activated mix gets stacked on top of the old disconnected one. The screenshot attached below shows the output of the command “au.Debug.Modulation 1”, as you can see we end up with multiple mixes enabled on top of each other even if they are the same mix asset.

I should clarify that once the mix gets “disconnected” it does not seem possible to deactivate it in any way, any call to UAudioModulationStatics::DeactivateBusMix() has no effect at all.

Another important bit is that our settings page does not ever modify the values of the Master mix, yet that mix seems to be getting to the “disconnected” state as well, not necessarily at the same time as the user settings one.

I tried to reproduce this issue in a dummy smaller project and I don’t seem to be able to. Would you be able to give some hints on what might be causing this?

[Attachment Removed]

Steps to Reproduce
Do not have clear reproduction steps. The issue is explained to the best of my knowledge in the description.

[Attachment Removed]

We are still diagnosing this root cause and have seen similar issues crop up internally, but similarily haven’t been able to consistently repro.

I am currently investigating a leading theory that is a two step solution.

1. Its possible during level transition or similar (where the object is unloaded and possibly reloaded), GC causing the object identifier to become stale, which ultimately results in the underlying proxy info that is stored on the Audio Render Thread to become stale and handleless. Locally, you could try the following. In the FModulatorBusMixSettings::FModulatorBusMixSettings constructor change the forwarded parent (TModulatorBase) constructor argument from:

InBusMix.GetUniqueID()

to something like

static_cast<FBusMixId>(GetTypeHash(FName(InBusMix.GetPathName())))

The idea here is that using a stable hash of the asset path rather than the runtime UObject UniqueID ensures any reloading of the object references the same proxy on the AudioRenderThread (even though the UniqueID may have changed).

2. A change that was submitted early 2025 to enable Control Bus Mix Timers & Retriggering mixes looks to have potentially broken the contract of avoiding re-enabling a mix that has been set to stopping. The fix here is to allow updating fades in FAudioModulationSystem::UpdateMix when stopping (i.e. the check MixProxy.GetStatus() == FModulatorBusMixProxy::EStatus::Enabled needs to be updated to MixProxy.GetStatus() != FModulatorBusMixProxy::EStatus::Stopped)

We are hoping to test out and get these fixes in asap! Hope that helps!

[Attachment Removed]