Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Audio How do we make a normalized Cross fade with snapshots?

Discussion in 'Audio & Video' started by laurentlavigne, Aug 1, 2017.

  1. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    TransitionToSnapshots will always make a crossfade that has a total volume % <100 in the middle of the transition.
    Meaning, with crossfade between snapshot INGAME-0 and snapshot INGAME-1 configured as shown below
    then
    if transition is 1 second
    at 0.5 seconds the total volume will be < 0db instead of being normalized at 0db
    so
    the result is the sound tracks are muted for a fraction of a second.

    How can this be fixed whilst still using convenient gizmos such as snapshot and the sound mixer?

    s1.PNG

    s2.PNG
     
  2. Pelican_7

    Pelican_7

    Joined:
    Nov 25, 2014
    Posts:
    190
    Hi laurentlavigne,

    I believe what you want is an equal-power cross fade. Simply crossfading two audio signals in a linear manner will result in a perceived volume dip in the middle as you describe.

    An equal-power cross fade can be achieved by using the squares of the two crossfade gains. You can do this with Unity's AudioMixers by clicking on your INGAME-0/INGAME-1 sliders and in the inspector right-click on the volume parameter under Attenuation and select the "Squared Snapshot Transition" setting.

    Screen Shot 2017-08-01 at 14.18.49.png

    Hope that helps!
    Andy
     
  3. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    That is very well hidden.
    Thanks for the tip but the volume still dips.
    I call the transition with this bit of code, so maybe the TransitionToSapshots command does something funky to the values?:
    Code (CSharp):
    1.     [Task]
    2.     void EvaluateMusic()
    3.     {
    4.         int threat = EvaluateThreat ();
    5.         var choice = new MusicToThreat {threat = 0 };
    6.         foreach (var m in snapshots)
    7.         {
    8.             if (threat > choice.threat && threat > m.threat)
    9.                  choice = m;
    10.         }
    11.         AudioMixerSnapshot[] thisSnap = new AudioMixerSnapshot [snapshots.Length];
    12.         float[] thisWeights = new float[snapshots.Length];
    13.         for (int i=0;i<snapshots.Length;i++)
    14.         {
    15.             thisSnap [i] = snapshots[i].snapshot;
    16.             thisWeights[i] = snapshots[i] == choice ? 1 : 0;
    17.         }
    18.         mixer.TransitionToSnapshots (thisSnap, thisWeights, 1.0f);
    19.         Task.current.Succeed();
    20.     }
     
  4. Pelican_7

    Pelican_7

    Joined:
    Nov 25, 2014
    Posts:
    190
    Indeed it is well hidden isn't it.

    Hmm, I just had a look at the transition curves in this video (4m 58s):



    The SquareRoot transition curve looks more like the curve I was aiming for (and what Pro Tools does for equal power crossfades). Did you try the SquareRoot transition curve?

    I'd be surprised if TransitionToSnapshots doesn't respect the transition curve (and would report it as a bug if that is the case).
     
  5. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    The silence is less pronounced but still exists.
    I thought it could be due to half phase offset so I verified the tracks in audition by overlaying them and they don't cancel each other out (or I'm doing it wrong).

    I look at the slider in the audio mixer and TransitionToSnapshots does apply the curve but in a weird way: instead of mapping the curve to the volume, it maps the curve to the transition. This means that no curve can ever provide an approximation of equal power volume cross fade.
     
    Last edited: Aug 2, 2017
  6. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
  7. Pelican_7

    Pelican_7

    Joined:
    Nov 25, 2014
    Posts:
    190
    Damn. Thanks for the info.

    Perhaps we should make a feature request for an equal power transition curve. Doing this manually loses all the convenience of AudioMixerSnapshots.
     
    laurentlavigne likes this.
  8. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    Solution: bypass the new audio mixer and do it by hand, as usual
    (and enjoy NaN volumes because it's 3am and I can't be bothered fixing the arithmetic :p)
    {EDIT: 3am ain't no 'scuse, boy!}
    <EDIT: is fixed>

    Code (CSharp):
    1.     IEnumerator CrossFadeTo(AudioSource destination, float duration)
    2.     {
    3.         var timer = Time.time + duration;
    4.         while (Time.time < timer)
    5.         {
    6.             var t = (timer - Time.time)/duration ;
    7.             foreach(var s in sources)
    8.             {
    9.                 if (s == destination)
    10.                     s.volume = Mathf.Sqrt (1-t);
    11.                 else
    12.                     s.volume *= Mathf.Sqrt (t);
    13.             }
    14.             yield return null;
    15.         }
    16.         foreach(var s in sources)
    17.         {
    18.             if (s == destination)
    19.                 s.source.volume = 1;
    20.             else
    21.                 s.source.volume = 0;
    22.         }
    23.     }
    24.  
     
    Last edited: Aug 2, 2017
    jtink and grobonom like this.
  9. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    The request was made in 2015, ignored by the staff, maybe the new dev that took over will be more receptive.
     
  10. Pangamini

    Pangamini

    Joined:
    Aug 8, 2012
    Posts:
    54
    Still no proper crossfade?
     
  11. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    you tried the beta?
     
  12. highlyinteractive

    highlyinteractive

    Joined:
    Sep 6, 2012
    Posts:
    116
    Any proper crossfade yet?
     
  13. doublegumbo

    doublegumbo

    Joined:
    Oct 24, 2013
    Posts:
    53
  14. zoooom

    zoooom

    Joined:
    Feb 8, 2012
    Posts:
    50
    Bump

    It's a huge limitation of snapshots that you can't transition between them without an audible volume dip.
     
    Last edited: Jun 6, 2019
    Gekigengar, grobonom and doublegumbo like this.
  15. grobonom

    grobonom

    Joined:
    Jun 23, 2018
    Posts:
    335
    BTW it is not a bug; it's a feature :D

    I just discovered the audio mixer yesterday and it works like a charm but this 'dip' problem is really annoying.

    The interpolation between snaps goes perfectly linearly.
    Just try to setup a manual slider sending from 0 to 1 on snapshotA and 1 to 0 on snapshotB; you'll notice the snapshots' cursors match perfectly the manual slider.

    The problem comes with U3D devs wanting to do perfect audio things and use log volume sliders ( like any you can find on a real life mixing table ).
    The pain comes when we game devs just don't care log !
    we want ( and need ) linear cursor scales !

    I guess this is a matter of 15 minutes for devs to change from log to lin cursors scales and say 2h to make it choosable globally ( as we definitely don't need log at all ) in project config.

    Unfortunately this 'bad joke' lasts now for ages and i doubt it will be one day changed/solved.
    I think the dirty workaround ( we're used with this in unity :p ) would be to send to the snapshots interpolator the result of an exp curve between 0 and 1.....

    It would have been so simple that user don't have to care with this..... but i seems U3D dev like when their user have brainstorms :D

    Happy unitying ! :)

    EDIT:
    For those curious of how to do this ( and for me when i forget the 'how-to' :D )
    here's the way to setup main volume and mixing values for snapshots:
    add this func to your c#:
    Code (CSharp):
    1.    float linearize_shitty_U3D_audio(float v) // v:[0:1] ---> out:[0:-80] in log10
    2.    {
    3.    float tmp = Mathf.Log10(v)*20f;
    4.  
    5.       return((tmp <-80f)?-80f:tmp); // -80 = min value on audio scale
    6.    }
    7.  
    8.  
    now you set, say.... your AudioMixer master_volume ( that you have previously made visible ):
    M.SetFloat("Volume_General",linearize_shitty_U3D_audio(zero_to_one));

    Proper values are in:
    100% is 0dB
    50% is -6dB
    25% is -12dB
    etc....
    up to -80dB when the log reaches -Infinity....

    Hope you like the cheat ;)

    Happy unitying !
     
    Last edited: Jul 23, 2020
  16. FOXAcemond

    FOXAcemond

    Joined:
    Jan 23, 2015
    Posts:
    99
    In short, professional and clean version:
    Code (CSharp):
    1. private static float ToLogVolume(float value)
    2. {
    3.   return Mathf.Clamp(Mathf.Log10(value) * 20f, -80f, 20f);
    4. }
    5.  
    6. private static float FromLogVolume(float value)
    7. {
    8.   return Mathf.Clamp01(Mathf.Exp(value / 20f));
    9. }
     
    grobonom and laurentlavigne like this.
  17. TimHeijden2

    TimHeijden2

    Joined:
    Aug 11, 2016
    Posts:
    86
    Bump? Still looking for a good way to cross fade between snapshots that works properly :(
     
  18. juanmaguerrero_

    juanmaguerrero_

    Joined:
    Dec 6, 2017
    Posts:
    6
    @TimHeijden2 Hello to you and also to the rest, I've managed to get it working by exposing the volume param to script and then selecting "attenuation Snapshot Transition", from the context menu appearing on right click. Hope that helps!
     
  19. juanmaguerrero_

    juanmaguerrero_

    Joined:
    Dec 6, 2017
    Posts:
    6
    Here's a screenshot of what I'm selecting:
     

    Attached Files:

    Necron99 likes this.