Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

Resolved Smooth audio source switching

Discussion in 'Audio & Video' started by ut110, Jul 18, 2021.

  1. ut110

    ut110

    Joined:
    May 31, 2018
    Posts:
    8
    Is it possible to have one audio source get to the end and have another immediately start with no gaps (and not early)? My code looks something like this:

    Code (CSharp):
    1. public AudioSource loopingSong;
    2. public AudioSource introSong;
    3. public AudioClip firstLoop;
    4.  
    5. private double loopTime;
    6. private double startTime;
    7. private double firstLoopEnd;
    8.  
    9. public void Start ()
    10. {
    11.       loopingSong = GetComponent<AudioSource>();
    12.       loopTime = firstLoop.length;
    13.       startTime = AudioSettings.dspTime;
    14.       firstLoopEnd = startTime + loopTime;
    15.       introSong = transform.GetChild(0).GetComponent<AudioSource>();
    16.       introSong.clip = firstLoop;
    17.       introSong.Play();
    18.  
    19.       loopingSong.PlayScheduled(firstLoopEnd);
    20. }

    I notice if I schedule an end time for the introSong at the firstLoopEnd it ends slightly early while doing it as I posted starts early. I think it can randomly vary though. I've looked into this quite a bit and everywhere I look seems to either say doing it smoothly is not possible or just to do it like how I did it. But this certainly is not precise enough.

    I know this has to do with the dsp time not being accurate because it's on a seperate thread but how would you do it then? Please, this shouldn't be this hard.
    (I'm using unity 2019.4.21f1 at the moment)
     
  2. ut110

    ut110

    Joined:
    May 31, 2018
    Posts:
    8
    Ok, might have fixed it just by adding a bit to the startTime and changing introSong to scheduled. I really thought I had tried that before but maybe it was just too small of a number. It needs to be pretty large like at least +0.5.
    I guess it must be because it's still loading things? I don't know, I would have thought it would be all loaded before running the code. I did wonder if getting the audio source component was messing it up.
     
  3. Hikiko66

    Hikiko66

    Joined:
    May 5, 2013
    Posts:
    1,306
    Yeah, I was going to say, when unity is starting up it seems to take longer to play a clip, so that will throw your calculations off, because your are calculating your scheduling time before the clip plays, as opposed to working things out as it gets close to ending. If you were doing the latter, unity could take as long as it needs to play the first clip, and it wouldn't mess up your calculations.

    Another thing that will throw your calculations off, is that even once unity is up and running, it doesn't play a clip immediately, without delay, you need to use play scheduled to get the timing right.

    Another thing that can introduce inaccuracy is you using floats, like clip.length
    You can work out the length of a clip more accurately with (double)clip.samples / (double)clip.frequency

    You will also probably want to take into account pitch and the effect on the length of clips.
    Unfortunately pitch is a float, but we can't do anything about that
    (double)source.clip.samples / (double)source.clip.frequency / (double)source.pitch