Layers not syncing in Unity

Hi there!

I’m currently setting up a simple music event as a test for a more expansive music track in our game, which will dynamically add in instrument layers/other sound depending on where the player is.

Currently, it’s just an upright bass and a hi-hat, simple 12 bar blues loop. The bass plays all the time, but the hi-hat has a volume parameter that turns it on when the player is walking and off when the player is still.

In FMOD Studio, it loops correctly forever, but in game, the hi-hat track will eventually de-sync from the bass if the player moves erratically (effectively urning the parameter on and off a lot really fast). The hat will stay out of sync with the bass, not playing on time, until the track loops, where it resets and is in time again.

I don’t quite understand how this is possible; the bass and hat parts are in the same event, and are the same length. The parameter on the hat only effects its volume, not it’s length or the start time of the region. I can simulate the issue in FMOD by turning the parameter on and off a lot really fast, but no de-sync occurs, it’s only in our game when the player starts/stops moving really fast. It’s worse toward the end of the loop.

Any ideas would be hugely appreciated!

You should be able to get the behavior you want by setting the hi-hat instrument to synchronous playback mode.

If I’m right, the behavior you describe is caused by a feature called VOL0 Virtual. This feature automatically virtualizes content that has been ducked to the point of inaudability, and then restarts it when it becomes audible again. Asynchronous instruments that are restarted in this fashion begin playing from the beginning as if just triggered, which is why this issue causes your asynchronous hi-hat instrument to begin playing from the beginning whenever it becomes audible again.

Ok, cool. I’m new enough to FMOD that this is the first I’ve heard of this feature. I’ll try this out and report back. Thanks so much!

Sadly, that doesn’t seem to be the issue. I already had the “async” button deactivated for the hi-hat track. Just to be safe, I rebuilt and tried it in the game build, but no dice. Is there maybe something our programer should be doing from his end with the VOLO Virtual feature?

Ok! After reaching out to some other audio folks, I think I’ve solved it! So the parameter that causes the hi-hat to come in and out when the player moves just automates the hi-hat’s volume. So at “0”, the volume for the hi-hat is dragged all the way down to the “no sound” position, and then it curves up to 0.0db just before the parameter hits “1.”

The problem seems to come from the fact that the volume dips all the way down to the bottom. If I set it so the parameter curve goes from -75db (the lowest I can get it to drop before it just cutting all sound completely), the hi-hat is still completely inaudible when I want it to be, but now it stays in sync the entire time in the game build, no matter how erratically I move. Apparently this is a known issue with getting instruments in an event to stay synced up to the proper tempo or rhythm in events like these.

So while it’s less-than-satisfying to not understand why this is the case, that did fix the issue. Thanks so much to those that tried to help me with this!

2 Likes

So I’m having this same problem, and was so grateful to read your fix for it–but I still have tracks that sit empty (and therefore silent, and therefore virtualized) until an instrument gets played, and so I’m still having sync issues between the tracks.

Can this Vol0 feature be disabled? (And what would be the ramifications on memory? Would doing so mean that OneShot events don’t get automatically released…?)

It’d be great to be able to have silence on a track without it being virtualized and risking out-of-sync playback in Unity.

FWIW I’m in FMOD 2.01.07.

Your loss of synchronization is probably unrelated to the Vol0virtual issue described in this thread. That issue is caused by a channel becoming non-virtual some time after an asynchronous instrument’s trigger conditions are met, resulting in the instrument starting to play at the time when the instance becomes non-virtual rather than back when its trigger conditions became true.

In your case, the track ceases to be silent when an instrument on that track is triggered. Virtualization only happens to the channels associated with playing instruments, not the channelGroups associated with event tracks, and the channel associated with a playing instrument is only created when the instrument begins playing. As such, the channelGroup associated with the audio track in your case isn’t (and can’t be) virtual, and the channel associated with the instrument comes into existence when that instrument is triggered and is non-virtual from that first moment.

Which is to say, the synchronization issue you are experiencing must be caused by something else.

Are any of the assets used in your music set to streaming loading mode, perhaps? Assets 10 seconds or longer are automatically set to stream by default, and will have a #Stream tag next to their names when viewed in the assets browser. Streaming assets consume less memory at run time, but cannot be scheduled in a sample-accurate fashion, and so cannot be perfectly synchronized with other playing assets. As such, if you need two assets to play perfectly synchronized, you should set those assets to a loading mode other than streaming in the assets browser.

Yes. To disable Vol0virtual, use the FMOD_INIT_VOL0_BECOMES_VIRTUAL flag when creating the FMOD System.

As I mentioned above, however, Vol0Virtual is probably not the cause of the synchronization issues you are experiencing.

Naturally, if an inaudible event is not virtualized, it continues to play despite being inaudible, and so continues to consume CPU and memory in the same manner as an event that’s playing audibly.

No. Vol0Virtual and event release are both tools for reducing memory consumption, but they work in different ways, affect different things, and do not interact: Virtualization affects only channels that are currently playing, by putting them in a “low power mode” to reduce their resource consumption; and automatic release affects only event instances that have stopped, by destroying the event instance.