SoundPool
SoundPool簡介
如果應用程序經常播放密集、急促而又短暫的音效(如遊戲音效)那麼使用MediaPlayer顯得有些不太適合了。因爲MediaPlayer存在如下缺點: 1.延時時間較長,且資源佔用率高;2.不支持多個音頻同時播放
Android中除了MediaPlayer播放音頻之外還提供了SoundPool來播放音效,SoundPool使用音效池的概念來管理多個短促的音效,例如它可以開始就加載20個音效,以後在程序中按音效的ID進行播放。
SoundPool主要用於播放一些較短的聲音片段,與MediaPlayer相比,SoundPool的優勢在於CPU資源佔用量低和反應延遲小。另外,SoundPool還支持自行設置聲音的品質、音量、 播放比率等參數。
SoundPool提供了一個構造器,該構造器可以指定它總共支持多少個聲音(也就是池的大小)、聲音的品質等。構造器如下:
SoundPool(int maxStreams, int streamType, int srcQuality):第一個參數指定支持多少個聲音;第二個參數指定聲音類型:第三個參數指定聲音品質。
一旦得到了SoundPool對象之後,接下來就可調用SoundPool的多個重載的load方法來加載聲音了。
SoundPool提供瞭如下4個load方法:
int load(Context context, int resld, int priority):從 resld 所對應的資源加載聲音。
int load(FileDescriptor fd, long offset, long length, int priority):加載 fd 所對應的文件的offset開始、長度爲length的聲音。
int load(AssetFileDescriptor afd, int priority):從afd 所對應的文件中加載聲音。
int load(String path, int priority):從path 對應的文件去加載聲音。
上面4個方法中都有一個priority參數,該參數目前還沒有任何作用,Android建議將該 參數設爲1,保持和未來的兼容性。
上面4個方法加載聲音之後,都會返回該聲音的的ID,以後程序就可以通過該聲音的ID 來播放指定聲音。
SoundPool提供的播放指定聲音的方法:
int play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate):該方法的第一個參數指定播放哪個聲音;leftVolume、rightVolume指定左、右的音量:priority指定播放聲音的優先級,數值越大,優先級越高;loop指定是否循環,0爲不循環,-1爲循環;rate指定播放的比率,數值可從0.5到2, 1爲正常比率。
爲了更好地管理SoundPool所加載的每個聲音的1D,程序一般會使用一個HashMap對象來管理聲音。
歸納起來,使用SoundPool播放聲音的步驟如下:
- 調用SoundPool的構造器創建SoundPool的對象
- 調用SoundPool對象的load()方法從指定資源、文件中加載聲音。最好使用HashMap< Integer, Integer>來管理所加載的聲音
調用SoundPool的play方法播放聲音
下面的程序示範瞭如何使用SoundPool來播放音效。
SoundPool應用
一般在res下新建一個raw文件夾,將提示音放入其中。根據版本高低來判斷SoundPoold的創建方法。
if(Build.VERSION.SDK_INT>=21){
SoundPool.Builder builder=new SoundPool.Builder();
builder.setMaxStreams(2);
AudioAttributes.Builder attrBuilder=new AudioAttributes.Builder();
attrBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);
builder.setAudioAttributes(attrBuilder.build());
soundPool=builder.build();
}else {
soundPool=new SoundPool(2,AudioManager.STREAM_MUSIC,0);
}
版本大於等於21時獲得SoundPool的方法。。。好麻煩
SoundPool.Builder builder=new SoundPool.Builder();//創建SoundPool.Builder對象
builder.setMaxStreams(2);//設置可同時播放的流的數目的最大值。
AudioAttributes.Builder attrBuilder=new AudioAttributes.Builder();//創建AudioAttributes.Builder對象
attrBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);//設置流類型,傳遞的參數是AudioManager中的靜態常量
builder.setAudioAttributes(attrBuilder.build());;//設置AudioAttributes
soundPool=builder.build();//初始化soundpool
全部代碼
public class MainActivity extends Activity implements View.OnClickListener{
private Button mBtnSoundPool;
private SoundPool soundPool;
private int voiceID;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtnSoundPool= (Button) findViewById(R.id.btn_soundpool);
// 初始化需要一定的時間
voiceID=IntSoundPool();
mBtnSoundPool.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_soundpool:
playPool();
break;
default:
break;
}
}
public void playPool(){
soundPool.play(voiceID,1,1,0,-1,1);
}
private int IntSoundPool(){
if(Build.VERSION.SDK_INT>=21){
SoundPool.Builder builder=new SoundPool.Builder();
builder.setMaxStreams(2);
AudioAttributes.Builder attrBuilder=new AudioAttributes.Builder();
attrBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);
builder.setAudioAttributes(attrBuilder.build());
soundPool=builder.build();
}else {
soundPool=new SoundPool(2,AudioManager.STREAM_MUSIC,0);
}
return soundPool.load(getApplicationContext(),R.raw.outgoing,1);
}
}