C# ゲーム開発のために FMOD をいじっていましたが、早い段階でうまくいかないように思われる障害にぶつかりました。オーディオの分岐処理を行い、ゲームプレイ アクションをビートなどに同期させたいので、音楽トラックに同期点を追加してみました。コードは次のとおりです。
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();
曲は読み込まれ、正常に再生されます...追加した 500ms の同期点に達するまで。この時点で、VC# は FMOD.EventSystem.update() 内から次のエラーを吐き出します。
タイプ 'Game!FMOD.CHANNEL_CALLBACK::Invoke' のガベージ コレクション デリゲートでコールバックが行われました。これにより、アプリケーションのクラッシュ、破損、データ損失が発生する可能性があります。デリゲートをアンマネージ コードに渡す場合、デリゲートが呼び出されないことが保証されるまで、マネージ アプリケーションによって保持される必要があります。
どういうわけか、FMOD は私が渡したデリゲートを見失っています。デリゲートを保持する Music インスタンスはガベージ コレクションされていません。今のところ静的変数に格納していますが、静的メソッドでも試してみましたが、役に立ちませんでした。CallbackOnCollectedDelegate MDA を無効にすると、エラーは null 参照例外になるので、MDA は間違っていません。ここで FMOD が何をしているのかを完全には理解していないと思います。
C# + FMOD の専門家は私の間違いに気付くことができますか?