我一直在尝试使用FMOD进行C#游戏开发,但早期遇到了一个问题,似乎无法解决。我想要做一些分支音频处理并将一些游戏动作与节拍同步,因此尝试将同步点添加到我的音乐轨道上。以下是代码:
public class Music
{
private Sound music;
private Channel channel;
private IntPtr syncPtr;
public string File { get; private set; }
public Music(string file)
{
File = file;
}
public void Load()
{
music = new Sound();
Audio.System.createSound(File, MODE.HARDWARE, ref music);
}
public void Unload()
{
music.release();
}
public virtual void Play()
{
Audio.System.playSound(channel == null ? CHANNELINDEX.FREE : CHANNELINDEX.REUSE, music, false, ref channel);
music.addSyncPoint(500, TIMEUNIT.MS, "wooo", ref syncPtr);
channel.setCallback(channelCallback);
}
private RESULT channelCallback(IntPtr channelraw, CHANNEL_CALLBACKTYPE type, IntPtr commanddata1, IntPtr commanddata2)
{
if (type == CHANNEL_CALLBACKTYPE.SYNCPOINT)
Console.WriteLine("sync!");
return RESULT.OK;
}
}
然后...
m = new Music(MUS_TUTORIAL); //m is static
m.Load();
m.Play();
歌曲可以正常加载和播放,直到达到我添加的500毫秒同步点。此时,VC#会从FMOD.EventSystem.update()中输出以下错误:“在回收的委托类型'Game!FMOD.CHANNEL_CALLBACK :: Invoke'上进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。当将委托传递给非托管代码时,必须由托管应用程序保持其生存状态,直到确保它们永远不会被调用。”
所以,某种方式FMOD正在失去我传递给它的委托的跟踪。持有该委托的Music实例尚未被垃圾回收——我现在将其存储在静态变量中——但我也尝试过使用静态方法来解决问题,但无法成功。如果禁用CallbackOnCollectedDelegate MDA,则错误变为空引用异常,因此MDA没有错误。我想我可能只是没有完全理解FMOD在这里的工作方式。
是否有任何C#+FMOD专家能够看出我的错误?