Search Unity

Can you have sounds only play in sync with music? Effectively quantizing them?

Discussion in 'Scripting' started by Shazimus, Aug 29, 2013.

  1. Shazimus

    Shazimus

    Joined:
    Mar 7, 2013
    Posts:
    22
    So I'm getting into Unity properly for the first time. I've been trying a few things to have sounds play in time with music but have not found a solution yet.

    Wonder if anyone has already solved this? (Didn't find anything on searches either).

    The idea is the player presses buttons to trigger sounds. The sounds are in tune with various backing loops. Ideally the sounds will only trigger in time with the music. So the player can never play out of time. As I'm using 120bpm music, intervals of 0.25 seconds would work.

    The problem seems to be with having to use the update function. Normally I'd tell the sounds to trigger at time%0.25. But if using the update function this means lots of intervals of 0.25 are missed and you get silent gaps even if hammering on the button.

    I tried adding a couple of variables and if-statements so anything at intervals of 0.22 to 0.28 (an error of 0.03 seconds allowed) will allow sounds to be triggered. But you still get gaps. And if you increase the 0.03 it starts sounding out of time. Defeating the point.

    Is there a way to trigger things at more than once per frame?
     
  2. Hikiko66

    Hikiko66

    Joined:
    May 5, 2013
    Posts:
    1,304

    A few things:

    -The sound engine is running on a different thread to the update function. This is a good thing, because it means it's not tied to fps, and you don't need the update function to run at exactly the right time you want to start an audio clip.

    -You can schedule sounds to play accurately at a future time, that's how you are able to get sounds to play in sync. That also allows the engine time to load the file, or buffer the file, depending on the load/compression settings of your audio clips. If you don't schedule slightly in the future, there will be a delay as data needs to be loaded.

    -DSPtime is the audioengine current time, it can be used kind of like a metronome. You can also see how long a clip is in seconds (clip.length) and how many seconds you are into playing a clip (audiosource.time). You can use all of these things to help you schedule sounds to play in the future, in sync with other sounds.

    If you just want a sync point every 0.25 seconds, you'd need to work out when your music is going to hit its next 0.25 seconds, and schedule the sound to play then. (if the difference between now and then is not enough time to load the data then you will need to schedule the clip to play on the sync point after the next)
     
    Last edited: Aug 30, 2013
  3. Shazimus

    Shazimus

    Joined:
    Mar 7, 2013
    Posts:
    22
    Thanks both for those detailed replies. Gives me a lot to think about. I'll be looking through some of things mentioned and see if I can work out a solution.

    Cheers
     
  4. Shazimus

    Shazimus

    Joined:
    Mar 7, 2013
    Posts:
    22
    DSP time sounds very promising. The script ref explains how to build a metronome, so that should be applicable to my example.

    http://docs.unity3d.com/Documentation/ScriptReference/AudioSettings-dspTime.html