Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

AudioMixer SetFloat does not apply immediately causing audio clip to play when a group is silenced

Discussion in 'Scripting' started by Spankenstein, Jul 10, 2021.

  1. Spankenstein

    Spankenstein

    Joined:
    Jan 9, 2014
    Posts:
    25
    I have an AudioMixer with a group called SFX and I use SetFloat to silence that group.

    If I play an AudioSource clip which has its output set to the SFX group immediately after calling SetFloat then the audio clip will still play a few samples before being correctly silenced. Presumably because the audio is on a separate thread and I need to wait for things to be synced?

    Code (CSharp):
    1.  
    2. var volume = 0.0001f;
    3. audioMixer.SetFloat("SFX", Mathf.Log10(volume) * 20f);
    4. audioSource.Play();
    5.  
    If I put the audioSource.Play into a Coroutine and wait until the end of the frame to play the AudioSource then the problem still persists.

    This slight delay is evident whenever SetFloat is used. How can I make sure the audioSource is played immediately after the audio mixer value has been set via SetFloat without resorting to using delays with magic numbers?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,779
    It might be because the AudioMixer actually tweens the sound down over a short period of time to avoid abrupt changes in volume and the resultant clicks.

    I haven't used Unity's audiomixer recently myself, but I've seen such dwells in other audio subsystems.

    See if there is a way to override any time filtering on that channel and force the value immediately.
     
  3. Spankenstein

    Spankenstein

    Joined:
    Jan 9, 2014
    Posts:
    25
    That would make a lot of sense and is probably responsible for the behaviour I am seeing. However, I am unable to see any exposed property or method that allows me to have any control over this (both in the Editor or programmatically).
     
  4. Spankenstein

    Spankenstein

    Joined:
    Jan 9, 2014
    Posts:
    25
    Snapshots have a timeToReach argument but there may still be the hidden ramping beyond that. Snapshots also cover the entire state of the mixer so it looks like it is not possible to set groups parameters independently using this approach either?

    Code (CSharp):
    1.     /// <summary>
    2.     ///   <para>Transitions to a weighted mixture of the snapshots specified. This can be used for games that specify the game state as a continuum between states or for interpolating snapshots from a triangulated map location.</para>
    3.     /// </summary>
    4.     /// <param name="snapshots">The set of snapshots to be mixed.</param>
    5.     /// <param name="weights">The mix weights for the snapshots specified.</param>
    6.     /// <param name="timeToReach">Relative time after which the mixture should be reached from any current state.</param>
    7.     [NativeMethod("AudioMixerBindings::TransitionToSnapshots", HasExplicitThis = true, IsFreeFunction = true, ThrowsException = true)]
    8.     [MethodImpl(MethodImplOptions.InternalCall)]
    9.     public extern void TransitionToSnapshots(
    10.       AudioMixerSnapshot[] snapshots,
    11.       float[] weights,
    12.       float timeToReach);