1

有FMOD经验的人可以阻止我失去它。我无法让这些同步点正常运行。我有一些游戏音乐,由两部分组成,一个介绍和一个循环。它们是独立的声音,在前奏结束后,它开始循环部分,永远重复。我在介绍的末尾设置了一个同步点来触发循环。它工作得很好,直到我尝试停止并重新启动音乐(例如当播放器死亡时)。无论如何,同步点坚持在 intro 重新启动后立即触发,即使它已设置为 intro 结束。效果是音乐的两个部分同时播放 - 似乎在一个频道上,因为我告诉它重用频道。这甚至可能吗?这是我的一些代码(注意系统、介绍、循环和通道是成员变量):

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 同步点。然而,当再次调用 play 时,它仍然会触发,在调用 stop 之后:

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 坏了还是我遗漏了一些明显的东西?或者一些真正模糊和无证的东西......

4

1 回答 1

5

我刚刚得到它,我希望这对其他人有所帮助,现在将其视为“fmod 同步点”的谷歌搜索返回此作为第一个结果。重复是因为有些回调是针对同步点类型的,有些是针对结束的,因为介绍部分已经结束。因此,我意识到我什至不需要自己的同步点。我只是使用介绍的结尾作为触发器。更简洁的代码,完美运行。

于 2009-12-21T20:01:18.417 回答