FmodEX 編程人門(轉)-- Fmod文檔中GETTING STARTED的翻譯

GETTING  STARTED.

導言

FMOD Ex API被設計得非常直觀和靈活,本教程將簡要介紹引擎的使用方法,並對使用中涉及的相關問題做出解釋。

配置——What to include and what to link.

查閱文檔中的"Platform specific issues",找出指定平臺上要使用FMOD Ex函數所需鏈接的文件。在C/C++中,如果只須使用C接口,則包含"fmod.h",要使用C++接口則須包含"fmod.hpp"

注意:常量、回調函數、宏定義和枚舉類型都在fmod.h中,所以fmod.hpp也包含fmod.h,如果你使用C++的話就必須交叉使用。

對於DelphiC#Visual Basic,都有其對應的頭文件可供在程序中使用。

初始化

要初始化fmod,最簡單的方法就是調用System::init函數,FMOD會使用默認參數來配置聲卡和其他設置。

在查看文檔中的System::init函數時,要記住maxchannels參數是你在遊戲中可以同時播放聲音的最大數量,該數與聲卡或軟件混合器無關。

這些聲音是 虛擬聲音(virtual voices)。這意味着你可以同時播放任意多的聲音,而不用擔心硬件或軟件資源問題。你可以在遊戲中安全地播放每個聲音,而無須擔心System::playSound超出播放上限或搶佔其它聲音。因此只要你喜歡,你可以將maxchannels設置爲任意大的數,如11002001000

注意:同時播放1000個聲音並不會影響性能,因爲它們中的大部分是聽不見的 (聽不見的聲音被虛擬化)。而FMOD Ex虛擬聲音管理器決定哪些聲音能聽見,哪些聽不見只需要很小的系統開銷。
下面我們看一個初始化FMOD Ex的例子。

FMOD_RESULT result;

FMOD::System *system;

result = FMOD::System_Create(&system); // 創建主system對象

if (result != FMOD_OK)

{

printf("FMOD error! (%d) %s/n", result, FMOD_ErrorString(result));

exit(-1);

}

result = system->init(100, FMOD_INIT_NORMAL, 0); // 初始化FMOD

if (result != FMOD_OK)

{

printf("FMOD error! (%d) %s/n", result, FMOD_ErrorString(result));

exit(-1);

}

這是最基本的初始化FOMD引擎的方法,使用了100個虛擬聲音。
注意:mods3mxmitmidi格式的文件播放時只使用一個聲音,不要以爲在這裏增大數量就可以使用多個聲音來播放這些格式的文件。這些格式的都使用它們自己的internal pool voices

配置選

如果你不想使用默認設置的話,可以自行設定輸出硬件、FOMD資源使用和其他配置選項。
這些操作都必須在System::init函數調用前進行。
常用配置如下:

. System::setOutput選擇輸出方式。例如你可以在Windows上選擇DirectSoundWinMMASIOno-soundwave-writer或其他輸出選項,每個平臺都有不同的選擇。如果你只是要使用默認配置,就不需要調用它。

. System::setDriver選擇用於播放的設備驅動。當你擁有不止一塊聲卡並且不想使用默認聲卡的時候,這個函數就很有用了。你需要用System::getNumDrivers函數來獲取設備數,用System::getDriverName函數來獲取驅動名稱以供用戶選擇。

. System::setHardwareChannels使用這個函數來限制硬件聲音的數量,或設定硬件最少的聲音數量以達到軟件合成同樣的效果, “minimum”選項用於保證同時至少能聽到的聲音數量。(更詳細的情參見此函數的說明)

. System::setSoftwareChannels使用這個函數來設定FMOD通道使用的軟件混合聲音的數量。這將採用聲音疊加(複音)的方法,並佔用CPU和內存資源,使用mod/s3m/xm/it/midi這些格式時,不要指望使用它來增加聲音的數量,它們不使用通道的pool而使用自己的。

. System::setSoftwareFormat用於改變FMOD軟件混合器的設置。包括採樣率、輸出模式(integer vs float)、輸出通道數(multi-output channel ASIO devices)、內存使用和混合質量。

. System::setDSPBufferSize如果在很慢的機器上或非良好的聲卡驅動上出現聲音抖動,就需要使用這個函數。它可以改變軟件混合器的響應時間,但誤用的話也可能影響性能。一些人可能想讓用戶在低響應時間高兼容性兩種模式間做出選擇,可以通過調整緩衝大小來達到犧牲響應時間換取穩定性的目的。

. System::setSpeakerMode設置揚聲器輸出模式。此函數只對FMOD軟件混合引擎起作用,默認值爲stereo (5.1 on xbox and xbox360 and 7.1 on ps3),可以按需要任意更改。注意:聲道數越多,佔用的內存也越多。

下面的例子使用了一些配置項來初始化FMOD要記住這些選項都是可選的,如果不需要就不用設置,在你沒有弄懂其真正含義前,千萬不要僅僅將下面的代碼複製再粘貼! 例如,如果用戶沒有5.1聲道的系統,你就不能僅僅將揚聲器模式設定爲5.1

FMOD_RESULT result;

FMOD::System *system;

result =system); //創建主system對象

ERRCHECK(result);

// 設置揚聲器模式爲5.1聲道

result = system->setSpeakerMode(FMOD_SPEAKERMODE_5POINT1); ERRCHECK(result);

// 允許同時播放100個軟件混合聲音

result = system->setSoftwareChannels(100); ERRCHECK(result);

// 要求聲卡至少要有322D3D硬件聲音,如果聲音數超過64,就限制爲64

result = system->setHardwareChannels(32, 64, 32, 64); ERRCHECK(result);

// 初始化FOMD,使用100個虛擬聲音

result = system->init(200, FMOD_INIT_NORMAL, 0);

ERRCHECK(result);

加載與播放

要播放聲音,你必須先加載!
使用System::createSoundSystem::createStream就可以完成這項工作。
默認情況下,系統會嘗試將整個聲音解壓到內存中(如果使用 System::createSound函數),而和sample不同的是stream(System::createStream創建)是在運行時解碼,僅使用很少的內存作爲緩衝,這就是爲什麼大文件最好用stream的原因。
更多請參見術語/基本原理

下面是一個加載MP3文件的例子,默認條件下System::createSound函數將整個MP3解壓成16bitPCM格式,這就意味着將佔用比文件本身大許多倍的內存。

FMOD::Sound *sound;
// FMOD_DEFAULT
等效於FMOD_LOOP_OFF | FMOD_2D | FMOD_HARDWARE.

result = system->createSound("../media/wave.mp3", FMOD_DEFAULT, 0, &sound);

ERRCHECK(result);

下面是一個用stream打開MP3文件的例子。System::createStream函數將打開文件並預緩衝小部分數據,然後就可以在System::playSound調用時直接播放了。

FMOD::Sound *sound;
// FMOD_DEFAULT
等效於FMOD_LOOP_OFF | FMOD_2D | FMOD_HARDWARE.

result = system->createStream("../media/wave.mp3", FMOD_DEFAULT, 0, &sound);

ERRCHECK(result);



指定用軟件混合就必須使用FMOD_SOFTWARE標記。如果你想要使用如DSP effectsspectrum analysisgetwavedatapoint to point looping和其它更多的高級技術,就必須使用軟件混合。

FMOD::Sound *sound;
//
使用軟件混合

result = system->createSound("../media/wave.mp3", FMOD_SOFTWARE, 0, &sound);

ERRCHECK(result);



下一個例子是將MP3sample的形式載入內存而不解壓,使用 FMOD_CREATECOMPRESSEDSAMPLE標記。此時如果沒有指定FMOD_HARDWAREFMOD_SOFTWARE,將默認爲軟件混合。硬件聲音回放不支持這個標記,除非格式爲ADPCM on XboxVAG on PS2/PSPGCADPCM on Gamecube/Wii Platforms like PS3 and Xbox 360 are all done one the cpu (usually a different core to the main cpu so it does not affect performance).

FMOD::Sound *sound;
// FMOD_CREATECOMPRESSEDSAMPLE
標記讓sample先嚐試直接播放(不解壓到內存),但僅限於IMA ADPCMMP2MP3XMA格式

result = system->createSound("../media/wave.mp3", FMOD_CREATECOMPRESSEDSAMPLE, 0, &sound);

ERRCHECK(result);

警告! 必須謹慎使用這種模式,它看上去和PCM sample很相似,但它會在運行時導致巨大CPU開銷。FMOD按照聲音的壓縮格式,在播放時對其進行解碼。


現在,要播放soundstream只需簡單地調用System::playSound就行了。

FMOD::Channel *channel;

result = system->playSound(FMOD_CHANNEL_FREE, sound, false, &channel);

ERRCHECK(result);

此時,聲音已經在後臺播放了!而你的程序將繼續執行。

關於playSound的注意事項:

. 如果不需要的話,可以不必獲取channel句柄,可以將其設爲0NULL。如果你不需要更改這個sound實例,或者這個聲音很短(不循環),就可以省去它。例如:

result = system->playSound(FMOD_CHANNEL_FREE, sound, false, 0);

ERRCHECK(result);

. 可以在開始播放時暫停,這樣就可以更改聲音的屬性而不會被用戶聽見,這就是“paused”參數的用處所在。例如,如果你將paused設爲true,再設置音量爲0.5,然後解除暫停,此時聲音就會一一般的音量播放。但如果你是將paused設爲false,而其它操作相同的話,你會聽見聲音開始時瞬間是全音量播放的,用戶可不希望聽到。

result = system->playSound(FMOD_CHANNEL_FREE, sound, true, &channel);

ERRCHECK(result);

// 暫停時設定音量

result = channel->setVolume(0.5f);

ERRCHECK(result);

// 聲音從這裏纔開始播放

result = channel->setPaused(false);

ERRCHECK(result);

. 一個“channel”就是一個聲音的實例。一個聲音你可以同時播放多次,每次播放都會得到一個新的channel句柄,stream除外,它只能同時播放一次,如果你嘗試多次播放,只會重複播放當前stream並返回同上次一樣的channel句柄。這是因爲stream只有一個緩衝和一個文件句柄。要同時播放兩個stream就必須打開兩次再播放兩次。

. 始終使用FMOD_CHANNEL_FREEFMOD會使用通道管理器自動爲你選擇一個未使用的channel。如果希望使用一個現有的channel來播放,就使用FMOD_CHANNEL_REUSE標記,這樣可以避免每次調用System::playSound函數都產生一個新的實例。

. 不需要“free”“release”一個channel句柄。所有的channel都位於你使用System::init所創建的一個pool中。當聲音停止後,channel可以被複用;如果所有的channel都處於播放狀態,那麼其中一個優先級最低的會被搶佔。其實只需增大System::init中的通道數就可以避免發生這樣的情況。

. 一個channel會在播放結束時即刻失效。這意味着你不能再對其進行更改,即使做了也沒有實際意義,因爲它不可能再播放了。絕大多數情況下,引用一個已失效的channel會導致一個FMOD_ERR_INVALID_HANDLE錯誤。

Update. (This is important!)

在每一幀中調用System::update函數是很重要的,但不需要多次調用,那樣只會影響效率。
該函數用於更新FMOD Ex的以下內容:

. Platform specific routines 例如向PS2IOP發送一個frame command packet。在這個平臺上,不調用update的話就聽不到聲音。

. Virtual voice emulation 不調用update,虛擬聲音就不會播放。

. 3D voice calculation 如果不調用update,就算channellistener已經正確設置,也無法聽到聲音移動的3D音效。

. Geometry engine FMODpolygon/geometry引擎需要通過update來啓用。否則用戶定義的occlusion/obstruction特性將無法呈現。

. Non realtime output FMOD_OUTPUTTYPE_NOSOUND_NRTFMOD_OUTPUTTYPE_WAVWRITER_NRT標記需要此函數才能更新到輸出(如用FMOD_OUTPUTTYPE_WAVWRITER_NRT寫出到文件)

. Streaming engine 如果指定了FMOD_INIT_STREAM_FROM_UPDATE標記,如果用戶希望在主線程中自己驅動流引擎,就必須有規律地調用update,否則會導致抖動和緩衝溢出。

關閉

調用System::release函數來關閉輸出設備並釋放對象關聯的內存。
你不必人工關閉channelsound,這些都在System::release中自動完成。
當然,你也可以手動關閉它們,這是個很好的編程練習(雖然是多餘的)
如果你要釋放system對象就不需要調用System::close函數了,在System::release中已經包含了對System::close的調用。

資源使用配製

在程序開發中,一些開發人員希望和其它程序一樣用自己的函數來訪問所有的磁盤或內存。
FMOD Ex中你可以通過System::setFileSystem函數來設置FMOD文件系統使你自己的文件程序。

要讓FMOD使用你的內存系統,或將FMOD限制在一個內存塊中,使用Memory_Initialize

注意! XboxXBox 360中,必須給FMOD提供一個塊內存。Xbox 360上必須使用XPhysicalAlloc來分配這塊內存。更多參見"Platform specific issues"

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章