SoundPool使用隨筆

基本概念

最近在做一個音樂相關(guān)的項目,對音樂的播放的基本操作是免不了的,作為android 小白的我來說第一時間想到了使用MediaPlayer來實現(xiàn)。

SoundPool 顧名思義是聲音的池子??纯聪旅?a target="_blank" rel="nofollow">SoundPool官方文檔的解釋:

<!--soundpool 用來管理和播放音頻文件的-->
The SoundPool class manages and plays audio resources for applications.

A SoundPool is a collection of samples that can be loaded into memory 
from a resource inside the APK or from a file in the file system.

SoundPool 與 MediaPlayer

為什么他們要用SoundPool 而不用MediaPlayer? 它們有什么區(qū)別呢?

為了以后就不用對著英文翻譯,就把整個SoundPool文檔翻譯了一下:

除了低延遲播放之外,SoundPool還可以管理一次渲染的音頻流數(shù)量。當(dāng)構(gòu)建SoundPool對象時,maxStreams參數(shù)設(shè)置可從此單個SoundPool一次播放的最大流數(shù)。 SoundPool跟蹤活動流的數(shù)量。如果超過了最大數(shù)量的數(shù)據(jù)流,SoundPool會根據(jù)優(yōu)先級自動停止先前播放的數(shù)據(jù)流,然后根據(jù)該優(yōu)先級按年齡自動停止。限制數(shù)據(jù)流的最大數(shù)量有助于限制CPU負(fù)載,并減少混音會影響視覺效果或UI性能的可能性。

聲音可以通過設(shè)置非零循環(huán)值來循環(huán)。值為-1會導(dǎo)致聲音永久循環(huán)。在這種情況下,應(yīng)用程序必須顯式調(diào)用stop()函數(shù)來停止聲音。任何其他非零值將導(dǎo)致聲音重復(fù)指定的次數(shù),例如,值為3會導(dǎo)致聲音總共播放4次。

播放速率也可以改變。 1.0的播放速率會導(dǎo)致聲音以其原始頻率播放(如果需要,重新采樣至硬件輸出頻率)。 2.0的播放速率會使聲音以原始頻率的兩倍播放,0.5的播放速度會使其以原始頻率的一半播放。播放速率范圍是0.5到2.0。

優(yōu)先級從低到高,即數(shù)字越大,優(yōu)先級越高。當(dāng)創(chuàng)建SoundPool時,對play()的調(diào)用會導(dǎo)致活動流的數(shù)量超過maxStreams參數(shù)所設(shè)置的值時使用優(yōu)先級。在這種情況下,流分配器將停止最低優(yōu)先級的流。如果有多個具有相同低優(yōu)先級的流,它將選擇最舊的流停止。在新流的優(yōu)先級低于所有活動流的情況下,新的聲音將不會播放,并且play()函數(shù)將返回0的流ID。

讓我們來看一個典型的用例:一個游戲包含多個層次的游戲。對于每個級別,都有一組只有該級別使用的獨特聲音。在這種情況下,游戲邏輯應(yīng)該在第一級加載時創(chuàng)建一個新的SoundPool對象。關(guān)卡數(shù)據(jù)本身可能包含此關(guān)卡使用的聲音列表。加載邏輯遍歷調(diào)用相應(yīng)SoundPool.load()函數(shù)的聲音列表。這通常應(yīng)該在流程的早期完成,以便在需要播放之前有時間將音頻解壓為原始PCM格式。

一旦聲音加載并開始播放,應(yīng)用程序可以通過調(diào)用SoundPool.play()來觸發(fā)聲音。播放流可以暫?;蚧謴?fù),應(yīng)用程序還可以通過實時調(diào)整播放速率來改變音高,以獲得多普勒效應(yīng)或綜合效果。

請注意,由于流可因資源限制而停止,因此streamID是對流的特定實例的引用。如果流停止以允許播放更高優(yōu)先級的流,則流不再有效。但是,應(yīng)用程序可以無錯地調(diào)用streamID上的方法。這可能有助于簡化程序邏輯,因為應(yīng)用程序不需要關(guān)注流生命周期。

在我們的例子中,當(dāng)玩家完成關(guān)卡時,游戲邏輯應(yīng)該調(diào)用SoundPool.release()來釋放所有正在使用的本地資源,然后將SoundPool參考設(shè)置為null。如果玩家開始另一個關(guān)卡,則會創(chuàng)建一個新的SoundPool,聲音會被載入,然后重新開始播放。

SoundPool文檔中,以及小白對MediaPlayer 之前的簡單使用,總結(jié)了亮點:

  • soundPool 相比MediaPlayer 播放延時更低;

  • soundPool 適用于播放聲音短促的音樂文件(10s以內(nèi)的)

  • 支持多個音頻同時播放

基本使用

  • 構(gòu)造方法

SoundPool (int maxStreams,  int streamType, int srcQuality)
//maxStreams 設(shè)置soundpool對象的并發(fā)流的最大數(shù)量
//streamType 設(shè)置流的類型,一般為STREAM_MUSIC
//srcQuality 采樣轉(zhuǎn)換率的質(zhì)量  現(xiàn)在沒有什么效果 0 設(shè)為默認(rèn)

但在上面的構(gòu)造方法在api 21 被廢棄了。API 21 以后使用SoundPool.Builder創(chuàng)建soundpool對象實例:

 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            mSoundPool = new SoundPool.Builder()
                    .setMaxStreams(maxSteams)
                    .build();
        } else {
            mSoundPool = new SoundPool(maxSteams, AudioManager.STREAM_MUSIC, 0);
        }
  • 常用方法

    加載音頻文件

與MediaPlayer相同 SoundPool 加載音頻文件有多種方式

<!--加載應(yīng)用資源文件--> 注意:切忌使用文件名相同,格式名不同的文件example.mp3  ,example.wav
int load(Context context, int resId, int priority)

<!--從音頻文件路徑加載-->
int load(String path, int priority)

<!--從asset 文件中加載-->
int load(AssetFileDescriptor afd, int priority)

<!--從文件中加載-->
int load(FileDescriptor fd, long offset, long length, int priority)

上述方法加載音頻返回一個sound ID. 這個ID就是用來播放對應(yīng)加載音樂文件以及相應(yīng)操作的標(biāo)識。

控制播放等一些其他設(shè)置


stop(int streamID)

pause(int streamID)

resume(int streamID)

release()

<!--設(shè)置循環(huán)播放  (0 不循環(huán), -1 循環(huán))-->
setLoop(int streamID, int loop)

<!--設(shè)置有播放優(yōu)先級-->
setPriority(int streamID, int priority)

<!--設(shè)置播放播放速度 rate值 0.5 ~2.0 之間--> 
setRate(int streamID, float rate)

setVolume(int streamID, float leftVolume, float rightVolume)

<!--相對于load方法-->
unload(int soundID)

<!--此方法會遍歷所有正在播放的音樂  并設(shè)置flag ,在autoResume的時候恢復(fù)播放-->
autoPause()
autoResume()

監(jiān)聽

setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener listener)

SoundPool 使用起來還是很簡單的。還是想總結(jié)一下做個筆記。

每天都有進(jìn)步。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容