PCM データではなく生データをストリーミングしたい場合は、FMOD ファイル システムをオーバーライドすることで実現できます。これを実現するには 2 つの方法があります。1 つ目は、これが 1 つの特定のファイルに対するものである場合、CreateSoundExInfo 構造体でファイル コールバックを設定することです。2 つ目は、すべての FMOD ファイル操作に対してファイル システムをグローバルに設定できることです (複数のファイルでこれを行う場合)。
後者について説明しますが、前者に切り替えるのは簡単です。完全な例については、「filecallbacks」FMOD の例を参照してください。
関数ポインタ:
private FMOD.FILE_OPENCALLBACK myopen = new FMOD.FILE_OPENCALLBACK(OPENCALLBACK);
private FMOD.FILE_CLOSECALLBACK myclose = new FMOD.FILE_CLOSECALLBACK(CLOSECALLBACK);
private FMOD.FILE_READCALLBACK myread = new FMOD.FILE_READCALLBACK(READCALLBACK);
private FMOD.FILE_SEEKCALLBACK myseek = new FMOD.FILE_SEEKCALLBACK(SEEKCALLBACK);
コールバック:
private static FMOD.RESULT OPENCALLBACK([MarshalAs(UnmanagedType.LPWStr)]string name, int unicode, ref uint filesize, ref IntPtr handle, ref IntPtr userdata)
{
// You can ID the file from the name, then do any loading required here
return FMOD.RESULT.OK;
}
private static FMOD.RESULT CLOSECALLBACK(IntPtr handle, IntPtr userdata)
{
// Do any closing required here
return FMOD.RESULT.OK;
}
private static FMOD.RESULT READCALLBACK(IntPtr handle, IntPtr buffer, uint sizebytes, ref uint bytesread, IntPtr userdata)
{
byte[] readbuffer = new byte[sizebytes];
// Populate readbuffer here with raw data
Marshal.Copy(readbuffer, 0, buffer, (int)sizebytes);
return FMOD.RESULT.OK;
}
private static FMOD.RESULT SEEKCALLBACK(IntPtr handle, int pos, IntPtr userdata)
{
// Seek your stream to desired position
return FMOD.RESULT.OK;
}
実装:
// Usual init code here...
result = system.setFileSystem(myopen, myclose, myread, myseek, 2048);
ERRCHECK(result);
// Usual create sound code here...