Hi everyone,
I’m using the Fmod API via C#. I’m performing the following actions:
- Create a sound (in paused state)
- Set a sync point
- Make the sound unpaused
- 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!