Syncpoint is not hit

Hi everyone,

I’m using the Fmod API via C#. I’m performing the following actions:

  1. Create a sound (in paused state)
  2. Set a sync point
  3. Make the sound unpaused
  4. Wait until the sync point occurs.

Now, this works in the normal case. But when I insert a Thread.Sleep between 1 and 2, the sync point is never hit. This is surprising: The sound only starts playing after the sync point is configured. So I would assume that the syncpoint must always get hit.

The Thread.Sleep serves no particular purpose. This is a test code to make sure that my sync code is robust, no matter the timing in the real world. Inserting a Sleep anywhere should not affect the functionality of the code.

Here’s how to reproduce this problem:

static bool check(FMOD.RESULT res, string purpose = null)
{
	if (res != FMOD.RESULT.OK)
		throw new InvalidOperationException(res.ToString());
	return true;
}
static ManualResetEvent onsyncPoint = new ManualResetEvent(false);
public static void FreezeWithSyncPoints()
{
	check(FMOD.Studio.System.create(out var sys));
	check(sys.getCoreSystem(out var coreSystem));
	check(sys.initialize(64, FMOD.Studio.INITFLAGS.NORMAL, INITFLAGS.NORMAL, IntPtr.Zero));
	check(coreSystem.createSound("c:\\temp\\synctest.wav", FMOD.MODE.CREATESTREAM | FMOD.MODE._2D, out var sound), "core.createSound");

	// place syncpoint at position 2ms
	check(sound.addSyncPoint(2, TIMEUNIT.MS, "Sync", out IntPtr syncPoint));
	check(coreSystem.playSound(sound, new ChannelGroup(), true, out var channel), "core.playSound");

	// sleeping for 400ms causes the syncpoint to never be hit.
	System.Threading.Thread.Sleep(400);

	// now we set the callback. Since the channel is paused, it shouldn't matter that we set the callback after a 400ms sleep.
	CHANNELCONTROL_CALLBACK ccb = ChannelCallback;
	check(channel.setCallback(ccb));


	check(channel.setPaused(false));
	System.Diagnostics.Debug.WriteLine("Waiting for syncpoint");
	onsyncPoint.WaitOne();
	System.Diagnostics.Debug.WriteLine("Syncpoint reached.");
}
static RESULT ChannelCallback(IntPtr channelcontrol, CHANNELCONTROL_TYPE controltype, CHANNELCONTROL_CALLBACK_TYPE callbacktype, IntPtr commanddata1, IntPtr commanddata2)
{
	if (callbacktype == CHANNELCONTROL_CALLBACK_TYPE.SYNCPOINT)
		onsyncPoint.Set();
	return RESULT.OK;
}

Any ideas what the problem is here?
Thanks a lot!

I think you’ve found a bug where a sync point can be missed if the voice is virtual (which happens when it’s paused) then it becomes real, I’ll log a bug report to have this fixed.

1 Like