歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android游戲編程之音頻編程

Android游戲編程之音頻編程

日期:2017/3/1 10:01:56   编辑:Linux編程

如果你有一台Android設備,就會注意到當你按下增大或降低音量按鈕時,你所控制的不同音量設置取決於你正在運行的應用程序。在通話中,你控制的是輸入語音流的音量;在視頻播放器中,你控制的是視頻音頻的音量;在主屏幕上,你控制的是鈴聲的音量。

Android為不同的目的提供不同音頻流。當我們在游戲中播放音頻時,可使用類來輸出音效和音樂到特定的音樂流。不過,在我們想播放音效或音樂之前,需要確定音量按鈕控制了正確的音頻流。為此,我們使用Context接口的另一個方法:

context.setVolumeControlStream(AudioManager.STREAM_MUSIC);

一如既往,Context的實現仍然由我們的活動來負責。調用該方法之後,音量按鈕就控制了該音樂流,後面我們就可使用它來輸出我們的音效和音樂。在活動的生命周期內我們只需要調用該方法一次,最好是在Activity.onCreate()方法中調用它。

首先我們要分清音樂流和音效的不同。後者一般是存儲在內存中且其長度不會超過幾秒鐘。Android系統給我們提供了一個SoundPool類,使用它可以很容易實現音效播放。

我們可以很簡單地初始化一個新的SoundPool實例,如下所示:

SoundPool soundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);

第一個參數指定在同一時刻我們最多能播放多少個音效。這並不是說我們不能加載更多的音效文件,它只不過是限制可同時播放的音效個數。第二個參數指定了SoundPool使用什麼音頻流來輸出該音頻。我們在這裡選擇音樂流,同時也已經為它設置好音量控件。最後一個參數現在沒有使用,它應該為默認值0.

為了從一個音頻文件加載音效到堆內存中,我們可使用SoundPool.load()方法。所有的文件都存儲在assets/目錄下,因此我們需要重載SoundPool.load()方法。所有的文件都存儲在assets/目錄下,因此我們需要重載SoundPool.load()方法來獲得一個AssetFileDescriptor。我們怎麼獲得AssetFileDescriptor呢?使用AssetManager。這裡我們使用SoundPool從assets/目錄加載一個名為explosion.ogg的OGG文件:

AssetFileDescriptor descriptor = assetManager.openFd("explosion.ogg");

int explosionId = soundPool.load(descriptor, 1);

通過AssetManager.openFd()方法可直接獲得AssetFileDescriptor,而通過SoundPool可很容易地加載音效,第二個參數用於指定該音效的優先級。這個參數目前未使用,為了以後的兼容應設置為1.

SoundPool.load()方法將返回一個整型值,它將作為一個句柄用於加載的音效。當我們想播放音效時,只需要指定該句柄,SoundPool就知道該播放哪個音頻。

soundPool.play(explosionId, 1.0f, 1.0f, 0, 0, 1);

第一個參數是從SoundPool.load()方法接受句柄。接下來兩個參數分別用於指定左右通道的音量,其值應該從0(靜音)到1(最大)

接下來兩個參數我們很少使用,其中第一個參數是優先級,目前沒有使用,並且應該設置為0.而另一個參數用於指定音效循環播放的頻率,一般不建議循環播放音效,因此設置為0。最後一個參數是播放速率,將其設置為大於1時,音效播放的速度將會比其在錄制時快;而將它設置為小於1時,播放該音效就會比較慢。

當我們不再需要一個音效並希望釋放內存時,可使用SoundPool.unload()方法:

soundPool.unload(explosionId);

我們只需要將從SoundPool.load()方法接收的音效句柄傳入即可,該方法會將音效從內存卸載。

當我們完成所有的音效輸出且不再需要SoundPool時,需要調用SoundPool.release()方法來釋放SoundPool所占用的所有資源。當然,在釋放之後,我們不能再使用SoundPool,而且SoundPool所加載的所有音效也會被釋放。

Copyright © Linux教程網 All Rights Reserved