When i resume FMOD Studio instance from pause, song position shift a little bit

I’m using FMOD Studio with banks and as a raw file in my project, and I’ve encountered an issue when pausing and resuming audio. I load my audio as a bank event (i.e., an FMOD Studio Event Instance) and use the setPaused(true) method to pause the audio. However, while the audio is paused, the event’s internal timeline continues advancing. This means that when I unpause the event, the playback position jumps ahead (e.g., from 100 ms to 150 ms), even though the audio was supposed to be paused.

CHARTER-9001_SSMBavjunx

When i use raw file (like wav or ogg) everything is fine.

Audio.cpp

unsigned int Audio::GetSongPosition(const std::string& songName)
{
	unsigned int pos;

	if (auto* channel = ResourceManager::GetChannel(songName))
		ERRCHECK(channel->getPosition(&pos, FMOD_TIMEUNIT_MS));
	else if (auto* instance = ResourceManager::GetEventInstance(songName))
	{
		int tmpPos;
		ERRCHECK(instance->getTimelinePosition(&tmpPos));
		pos = static_cast<unsigned int>(tmpPos);
	}
	else
	{
		std::cout << "There is no: " << songName << std::endl;
		return 0;
	}

	return pos;
}

Hi,

Thank you for the explanation and the code. Could I please grab the FMOD version you are using?


Hello

Here is my FMOD Studio version

1 Like

Thank you for the information.

I have been able to reproduce the behavior. It is possible to get the sound’s channel from the event instance to get a more accurate position.

Example function
// Example use:
FMOD::ChannelGroup* cg = nullptr;
ERRCHECK(instance->getChannelGroup(&cg));

chan = FindSoundChannel(cg);
//

FMOD::Channel* FindSoundChannel(FMOD::ChannelGroup* channelGroup)
{
    FMOD::Channel* chan = nullptr;
    FMOD::Sound* sound = nullptr;

    int numChannels = 0;
    if (channelGroup->getNumChannels(&numChannels) == FMOD_OK && numChannels > 0)
    {
        if (numChannels > 1)
        {
            return chan;
        }
        else
        {
            if (channelGroup->getChannel(0, &chan) == FMOD_OK)
            {
                if (chan->getCurrentSound(&sound) != FMOD_OK)
                {
                    chan = nullptr;
                    return chan;
                }
                else
                {
                    return chan;
                }
            }
        }
    }

    int numGroups = 0;
    if (channelGroup->getNumGroups(&numGroups) == FMOD_OK && numGroups > 0)
    {
        if (numGroups > 1)
        {
            return chan;
        }
        else
        {
            FMOD::ChannelGroup* child = nullptr;
            if (channelGroup->getGroup(0, &child) == FMOD_OK)
            {
                chan = FindSoundChannel(child);
            }
        }
    }
}

However, I will pass on this issue to our development team to investigate further. Thank you for bringing this to our attention.

1 Like

Okay, thanks for help

1 Like

Hello again, the code that im using now still makes that jumps at a pause

Here the GetSongPos function

unsigned int Audio::GetSongPosition(const std::string& songName)
{
	unsigned int pos;

	if (auto* channel = ResourceManager::GetChannel(songName))
		ERRCHECK(channel->getPosition(&pos, FMOD_TIMEUNIT_MS));
	else if (auto* instance = ResourceManager::GetEventInstance(songName))
	{
		FMOD::ChannelGroup* cg = nullptr;
		ERRCHECK(instance->getChannelGroup(&cg));

		FMOD::Channel* chan = FindSoundChannel(cg);
		ERRCHECK(chan->getPosition(&pos, FMOD_TIMEUNIT_MS));
	}
	else
	{
		std::cout << "There is no: " << songName << std::endl;
		return 0;
	}

	return pos;
}

And a little re-writen but still the same FindSoundChannel function

FMOD::Channel* Audio::FindSoundChannel(FMOD::ChannelGroup* channelGroup)
{
	if (!channelGroup)
	{
		return nullptr;
	}

	FMOD::Channel* chan = nullptr;
	FMOD::Sound* sound = nullptr;

	int numChannels = 0;
	if (channelGroup->getNumChannels(&numChannels) == FMOD_OK && numChannels > 0)
	{
		for (int i = 0; i < numChannels; ++i)
		{
			if (channelGroup->getChannel(i, &chan) == FMOD_OK)
			{
				if (chan->getCurrentSound(&sound) == FMOD_OK && sound)
				{
					return chan;
				}
			}
		}
	}

	int numGroups = 0;
	if (channelGroup->getNumGroups(&numGroups) == FMOD_OK && numGroups > 0)
	{
		for (int i = 0; i < numGroups; ++i)
		{
			FMOD::ChannelGroup* child = nullptr;
			if (channelGroup->getGroup(i, &child) == FMOD_OK && child)
			{
				chan = FindSoundChannel(child);
				if (chan)
				{
					return chan;
				}
			}
		}
	}

	return nullptr;
}

Thank you for the code.

Can you try using FMOD Engine | Core API Reference - ChannelControl:setPaused rather than pausing the event instance?

A detailed explanation of the the delay is present can be found here: Best way to pause/unpause while keeping sync - #5 by Leah_FMOD

For the audio asset could you please try toggling the Loading mode (FMOD Studio | Managing Assets - Loading Modes):

This will help to reduce the jump noticed when resuming the event. Another option may be setting the event macro Priority to Highest (FMOD Studio | Event Macros Drawer - Priority) which can also reduce some drift caused by the virtualization system. I will note this has been solved in 2.03.

Hope this helps.