具有FMOD经验的人可以阻止我失去它吗?我无法使这些同步点正常运行。我有一些游戏音乐,由两部分组成,前奏和循环。它们是不同的声音,在前奏结束后,它将开始循环部分,该循环部分将永远重复。我在简介结尾处设置了一个同步点以触发循环。效果很好,直到我尝试停止并重新启动音乐(例如,播放器死后)。无论如何,即使重新启动简介,同步点仍会坚持触发。效果是音乐的两个部分同时播放-并且似乎在单个 channel 上播放,因为我告诉它重用该 channel 。那有可能吗?这是我的一些代码(请注意,system,intro,loop和channel是成员变量):
public void Play()
{
if (intro != null)
{
CHANNELINDEX index = (channel == null) ? CHANNELINDEX.FREE : CHANNELINDEX.REUSE;
system.playSound(index, intro, false, ref channel);
uint length = 0;
intro.getLength(ref length, TIMEUNIT.MS);
intro.addSyncPoint(length, TIMEUNIT.MS, "StartLoop", ref loopPtr);
channel.setCallback(callback);
}
else system.playSound(CHANNELINDEX.FREE, loop, false, ref channel);
Playing = true;
}
这是同步点:
private FMOD.RESULT SyncCallback(IntPtr c, CHANNEL_CALLBACKTYPE type, IntPtr a, IntPtr b)
{
if (Playing)
{
RESULT result = intro.getSyncPoint(0, ref loopPtr);
intro.deleteSyncPoint(loopPtr);
system.playSound(CHANNELINDEX.REUSE, loop, false, ref channel);
}
return RESULT.OK;
}
至少,这是回调的一种版本。我已经尝试了大约20个其他对象。注意,我告诉它删除同步点-当我检查返回值时,它确定。我也尝试了loop.deleteSyncPoint以防万一。我还对其执行了getsyncpointinfo,以确保触发了我的StartLoop同步点。但是,在调用停止后再次调用播放时,它仍然会触发:
public void Stop()
{
Playing = false;
if (intro != null && loopPtr != IntPtr.Zero)
{
IntPtr ptr = IntPtr.Zero;
RESULT result = intro.getSyncPoint(0, ref ptr);
result = intro.deleteSyncPoint(ptr);
result = intro.getSyncPoint(0, ref ptr);
loopPtr = IntPtr.Zero;
}
channel.stop();
channel.setPosition(0, TIMEUNIT.MS);
}
请注意,Stop()还会尝试删除同步点,但是这样做同样会失败(即使结果返回OK)。我试图在停止时将通道位置设置为0,这使情况变得更糟。在deletesyncpoint()调用之后,我在同步点中尝试了channel.stop(),但这引起了堆栈溢出,因为尽管每次尝试删除同步点,它都会在每次调用时继续调用该同步点来停止。我给它的指针是错误的还是什么?我尝试制作某种标记来表示不播放循环部分,但是我不能这样做,因为它将被设置在Play()的中间,并且在Play()完成后立即调用同步点,在下一次调用系统更新时。 FMOD损坏了还是我遗漏了一些明显的东西?还是有些晦涩且没有记载的东西...
最佳答案
我刚得到它,希望对其他人有所帮助,因为谷歌搜索“fmod syncpoint”现在将其返回为第一个结果。之所以重复,是因为某些回调是针对同步点类型的,而某些回调是针对结束的,因为介绍部分已经结束。因此,我意识到我什至不需要自己的同步点。我只是将简介的结尾用作触发条件。更清晰的代码,并且完美运行。
关于c# - FMOD声音库-同步点让我发疯!,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1940645/