Hello
I’m developing a rhythm game. As others, I would like to keep the sync between music and game as close as possible.
Up to now, I always succeed to do that using EVENT_CALLBACK, by synchronising the game on the first TIMELINE_BEAT
However, I would like to pause/unpause, and sync the game when unpause is done.
I’m a little bit confused about the way it works.
Here is one of my reference topic : Some delay occurs when pause the music on Android
First, to pause/unpause, we can call myChannel.setPause but also myEventInstance.setPause
Is there a difference between the two ?
Second, if I apply the proposed method referenced in the above post (retrive channel, get dsp clock, set position), does the method setPause is synchronise, or is there an unknown delay between my call and the effective play ?
If there is a delay, how may I know exactly when the music starts again and to know at which position (in ms) it unpause ? I’m asking, because there is absolutly no EVENT_CALLBACK triggered after the unpause.
Thank you
In other words and in a more general question, is there a way to know the exact cursor position, accurate both in its position and in the delay to get the answer ?
rather than pause/unpause you could try instance.getTimelinePosition();
stop the event
then when you need it settimelineposition and start again.
Unsure on the delay aspect
Thanks @benhoughton for the suggestion. It works, but I do not really understand why. Here is my new code
int pauseLastPos = 0;
public void PauseMusic(bool paused)
{
if (paused)
{
musicInstance.getTimelinePosition(out pauseLastPos);
musicInstance.setPaused(true);
}
else
{
musicInstance.getTimelinePosition(out int pauseLastPos2);
musicInstance.setTimelinePosition(pauseLastPos);
musicInstance.setPaused(false);
}
}
What is strange is that if I comment the setTimelinePosition line, timeline starts to be out of sync after some pause/unpause, but uncomment this line allows to keep timeline sync (when I say timeline, I mean
BeatEventCallback and EVENT_CALLBACK_TYPE).
Here is the strange point: in both situations (while calling or not setTimelinePosition), pauseLastPos and pauseLastPos2 have the same values, meaning I’m passing the same value in setTimelinePosition that I retrieve from getTimelinePosition.
Sorry for the delayed response!
What you’re likely running into is the asynchronous nature of how the FMOD Studio system operates. When called, almost all API commands, including EventInstance.setPaused()
, are enqueued in a buffer that is submitted to the Studio system to execute asynchronously when Studio.System.update() is called. The default update period is 20ms, meaning that would explain the drift you’re running into.
However, by accessing an EventInstance’s underlying ChannelGroup as detailed in the thread you linked, you can make these calls synchronously - notably getting the DSP clock for sample accurate timing info, and calling ChannelControl.setPaused(). I’d recommend trying this method of pausing out and seeing whether it resolves your issue. It’s worth noting however that due to the way the Studio and Core API interact, you’ll likely also need to call EventInstance.setPaused()
on the event instance at the same time as calling ChannelControl.setPaused()
to ensure that the pause states remain in sync.