Some delay occurs when pause the music on Android

I am developing a rhythm game for Android.

Other features work great and better than Unity native audiosystem.

But, I have a problem in implementing the pause and resume function.

I implemented the pause and resume function using channel.setPause(),
and found that there was a slight delay when resume using channel.setPause(false).

https://qa.fmod.com/t/off-sync-on-position-gettimelineposition-when-using-setpaused-method/13069/2
I saw in one article that it need to sync using dspclock, but I don’t understand the solution well, so I can’t solve this problem.

Is there anyway this problem can be solved?

Thank you.

Hi,

So DSP clock is the correct solution to the problem. I’ll try to explain it in a different way.

First, we will need the Channel and Channel Group to which the event belongs. I achieved this like so:

Retrieving Channel and Channel Group
/// <summary>
/// Using supplied event Emitter return the event's channel and channel group
/// </summary>
private FMOD.RESULT ReturnEventChannel(FMODUnity.StudioEventEmitter eventEmitter, out FMOD.Channel requestedChannel, out FMOD.ChannelGroup channelsGroup)
{
	requestedChannel = new FMOD.Channel();
	channelsGroup = new FMOD.ChannelGroup();

	FMOD.RESULT result = eventEmitter.EventInstance.getChannelGroup(out FMOD.ChannelGroup newgroup);

	//Checking at every step if there is an error which will return a invalid result 
	if (result != FMOD.RESULT.OK)
    {
		Debug.Log("Failed to retrieeve parent channel group with error: " + result);
		return result; 
    }

	result = newgroup.getGroup(0, out channelsGroup);

	if (result != FMOD.RESULT.OK)
	{
		Debug.Log("Failed to retrieve child channel group with error: " + result);
		return result;
	}

	result = channelsGroup.getChannel(0, out requestedChannel); 

	if (result == FMOD.RESULT.OK)
    {
		Debug.Log("Retrieved the correct channel"); 
		return result;
	}
	else
    {
		Debug.Log("Failed to find the right channel with error: " + result);
		return result;
    }
}

Now when you pause the event, get the current DSP position. To do so we need the Channel Group the event belongs to. The Channel Group is an out value of the previous function. So we can just use that.

Getting current DSP clock
private FMOD.RESULT GetCurrentDSPClock(FMOD.ChannelGroup cG, out ulong dspClock, out ulong parent)
{
	FMOD.RESULT result = cG.getDSPClock(out dspClock, out parent);

	if (result != FMOD.RESULT.OK)
	{
		Debug.Log("Failed to retrieve DSP clock with error: " + result);
		dspClock = 0;
		parent = 0;
		return result;
	}
	else
		Debug.Log("Retrieved DSP Clock"); 
	
	return result; 
}

Now we have an accurate value to set our playback position to when we resume the event avoiding any drift.


channelToPause.setPosition((uint)dspClockCurrent, FMOD.TIMEUNIT.PCM);

channelToPause.setPaused(false);

Hope this explains it better!

*Removed a member bool which would cause errors

I’m using Core System right now,
and when I used channelGroup.getDSPClock() to get dspClock,
it seems to work like uptime.
If I apply this as a setPosition(), it goes against the actual music. What am I using wrong?

Hi,

Is it possible to get a code snippet of how you are trying to retrieve the DSP clock and then use it to set the playback position?

Sorry, I wrote the wrong code. Now it works perfectly. Thanks!

1 Like

Hey iceuser, may you share the pause/unpause code ?