1

FMODの経験がある人は、私がそれを失うのを止めてください. これらの同期点を動作させることができません。イントロとループの 2 つの部分で構成されるゲーム ミュージックがあります。それらは別々の音で、イントロが終わると永遠に繰り返されるループセクションに入る。イントロの最後に同期点を設定して、ループを開始しました。音楽を停止して再開しようとするまで(たとえば、プレーヤーが死亡したとき)、問題なく動作します。何があっても、同期点は、イントロの終わりに設定されているにもかかわらず、イントロが再開されるとすぐに発火することを主張します。その効果は、音楽の両方のセクションが同時に再生されるということです。チャネルを再利用するように指示しているため、1 つのチャネルで再生されているように見えます。それは可能ですか?これが私のコードの一部です(システム、イントロ、ループ、およびチャネルはメンバー変数であることに注意してください):

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;
}

少なくとも、これはコールバックの 1 つのバージョンです。他にも20本ほど試しました。同期点を削除するように指示していることに注意してください。リターンを確認したところ、問題ありませんでした。念のため、 loop.deleteSyncPoint も試しました。また、起動していたのが StartLoop 同期点であることを確認するために、getsyncpointinfo も実行しました。それでも、stop の呼び出しの後、play が再度呼び出されると起動します。

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 syncpoint」をグーグルで検索すると、これが最初の結果として返されるので、これが他の誰かの助けになることを願っています。重複は、一部のコールバックが同期点タイプ用であり、一部が終了用であったためでした。これはイントロ セクションが終了したためです。それで、自分の同期点さえ必要ないことに気づきました。イントロのエンディングをトリガーにして持っているだけです。よりクリーンなコードで、完璧に動作します。

于 2009-12-21T20:01:18.417 に答える