我發佈了一個question on gamedev關於如何在FMOD中播放nsf文件(NES控制檯音樂)。它沒有得到任何結果,但從那時起我取得了一些進展。我決定最簡單的方法就是將現有的播放器編譯成一個dll,然後從C#調用它來填充我的緩衝區。現在的問題是讓它聽起來正確,並確保我所有的參數都是正確的。FMOD.net流媒體,回調和exinfo參數
這裏是事實至今:
- 美國國家科學基金會的DLL是處理
short
S,這樣的數據是PCM16。 - 我正在使用的示例nsf的播放速率爲60 Hz。
- 只是現在打轉轉,我使用的是基於2和3的48000
- 的頻率,該dll計算48000/60HZ的必需的緩衝器大小= 800這意味着它將使800
short
值得的每個模擬NES幀的緩衝區。
到目前爲止,我已經得到了我的C#代碼,以正確的音高和速度播放nsf,但它非常有顆粒感/模糊,我認爲FMOD讀回調給出了一個事實數據長度爲1600,而我應該預計爲800.我嘗試過使用所有數字,並且要麼崩潰,要麼音樂改變音高,速度,或者兩者兼而有之。
下面是我的一些C#代碼:
uint channels = 1, frequency = 48000;
FMOD.MODE mode = (FMOD.MODE.DEFAULT | FMOD.MODE.OPENUSER | FMOD.MODE.LOOP_NORMAL);
FMOD.Sound sound = new FMOD.Sound();
FMOD.CREATESOUNDEXINFO ex = new FMOD.CREATESOUNDEXINFO();
ex.cbsize = Marshal.SizeOf(ex);
ex.fileoffset = 0;
ex.format = FMOD.SOUND_FORMAT.PCM16;
// does this even matter? It doesn't change my results as long as it's long enough for one update
ex.length = frequency;
ex.numchannels = (int)channels;
ex.defaultfrequency = (int)frequency;
ex.pcmreadcallback = pcmreadcallback;
ex.dlsname = null;
// eventually I will calculate this with frequency/nsf hz, but I'm just testing for now
ex.decodebuffersize = 800;
// from the dll
load_nsf_file("file.nsf", 8, (int)frequency); // 8 is the track number to play
var result = system.createSound(
(string)null,
(mode | FMOD.MODE.CREATESTREAM),
ref ex,
ref sound);
channel = new FMOD.Channel();
result = system.playSound(FMOD.CHANNELINDEX.FREE, sound, false, ref channel);
private FMOD.RESULT PCMREADCALLBACK(IntPtr soundraw, IntPtr data, uint datalen)
{
// from the dll
process_buffer(data, (int)800); // if I use datalen, it usually crashes (I can't get datalen to = 800 safely)
return FMOD.RESULT.OK;
}
因此,這裏是我的一些問題:
- 什麼是和讀的
datalen
參數exinfo.decodebuffersize,頻率之間的關係,回電話?有了這個代碼示例,它將以3200進入。我不知道它和decodebuffersize之間的因子是從哪裏來的。 - 是否
datalen
在回調中提到byte
s或short
s? process_buffer函數使用一個簡短的數組及其長度。我希望fmod也在談論短褲,因爲我告訴它PCM16。 - 也許我的播放質量不好,因爲一些完全不同的原因。如果是這樣,我不知道從哪裏開始解決。那裏有任何想法?
謝謝,這就是我所需要的。質量問題實際上是在NSF庫中,而不是我的FMOD代碼。 – Tesserex 2011-01-11 03:19:18