1. 程式人生 > >安卓的SoundPool(音效池)播放聲音(及具體引數解析)

安卓的SoundPool(音效池)播放聲音(及具體引數解析)

SoundPool一般用來播放的檔案特點有:聲音短,檔案小,延時慢(不像使用MediaPlayer類播放音樂時,需要等待一段時間),因此常用來播放遊戲時的音效,解鎖時的鈴聲等。注意:該類不適合播放太大的檔案資源,我測試了個900K左右的檔案,播放不了

使用SoundPool一般需要下面幾個步驟:

1、將音樂檔案拷貝到工程下;

2、新建一個SoundPool例項;

3、使用load()方法,讓SoundPool例項載入音效資源,該方法會返回一個整型的soundID,在第四步需要用到;

4、使用play()方法播放音效,該方法會返回一個整型的streamID,這個返回值可以儲存起來,在需要暫停 /  恢復播放時需要用到。

具體實現以及引數如下:

1、新建一個工程,我取名SoundPoolDemo,在res資料夾下新建一個raw資料夾,將.mp3檔案拷貝到其中

2、新建一個SoundPool例項。SoundPool只有一個構造方法,

(int maxStreams, int streamType, int srcQuality)

引數如下:

int  maxStreams:在聲音池中允許同時存在的聲音數量。當池子中的聲音超過這個數量時,優先順序(後面會提到)最低、或者最早(Oldest,原諒我可憐的翻譯水平)放進池中的,將被移除。這個數值不是越大越好,因為越大也就意味著,Android會給你預分配一個更大的空間,如果不需要使用會造成浪費。

int  streamType:聲音流的型別,有STREAM_RING、STREAM_MUSIC等等,一般都是使用後者,即AudioManager.STREAM_MUSIC。

int srcQuality:官網解釋為“取樣速率轉化器的質量”(再次原諒我的翻譯),這個引數目前沒有什麼實際意義(可能還沒實現這個功能),所以設定什麼數值都無所謂,官方建議用0;

3、載入資源方法:

public int load(Context context, int resId, int priority)

引數如下:

Context  context:這個不必多解釋,一般都是設定為getApplicationContext()獲取

int resId:想要載入的音效資源ID,我用的是R.raw.XXX

int priority:音效播放時的優先順序,官方解釋這個引數在這個方法中不起作用,建議用1暫時代替(Currently has no effect. Use a value of 1 for future compatibility.

注:該方法會返回一個soundID,在以後使用中需要使用

4、播放

07-08注:在load聲音資源後,並不能立即呼叫play,否則無法播放聲音,因為聲音資源還沒載入完成,應該給足夠時間讓它載入完成,比如在onCreate中load,在onclick中play

public final int play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)

引數如下:

int  soundID:在第3步中提到了。

float  leftVolume:左聲道音量大小,這是一個相對值,大小在0.0f - 1.0f之間,具體計算方法為:你想要的聲音大小 / 最大音量,比如取值0.8f表示最大音量的80%

float  rightVolume:右聲道音量大小,具體如上

int  priority:優先順序,值越大優先順序越高,0的優先順序最低。之前在第3步中也有一個優先順序引數,但是那裡無效,而現在這裡的這個引數是正兒八經有效果的。

int loop:是否需要迴圈播放,取值不限。其中負數表示無窮迴圈(官方建議,如果無窮迴圈,用-1,當然-2、-3等也行),非負數表示迴圈次數,比如0表示迴圈0次,也就是播放一次就不再迴圈了,總共就只播放一次;1則表示迴圈1次(總共播放2次)。

float  rate:這個引數有點意思,可以理解為播放速率(就是快進、快退啥的),取值0.5f - 2.0f,其中0.5表示播放速度為正常的0.5倍。1表示正常速率播放。

下面開始正式編碼:

1、資原始檔如下圖:


2、佈局檔案不解釋了,只有一個簡單的Button。下面是MainActivity.java的程式碼(總共就一個類)

  1. package com.exam.soundpooldemo;  
  2. import android.app.Activity;  
  3. import android.media.AudioManager;  
  4. import android.media.SoundPool;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9. publicclass MainActivity extends Activity {  
  10.     Button playButton;  
  11.     SoundPool sp;  
  12.     int soundID_1,soundID_2;  
  13.     int streamID_1,streamID_2;  
  14.     @Override
  15.     protectedvoid onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.activity_main);  
  18.         sp=new SoundPool(10, AudioManager.STREAM_MUSIC,0);  
  19.         soundID_1=sp.load(getApplicationContext(), R.raw.lingsheng, 1);  
  20.         soundID_2=sp.load(getApplicationContext(), R.raw.moon, 1);  
  21.         playButton=(Button)findViewById(R.id.play);  
  22.         playButton.setOnClickListener(new OnClickListener() {  
  23.             @Override
  24.             publicvoid onClick(View v) {  
  25.                 streamID_1=sp.play(soundID_1, 0.8f, 0.8f,1, -11.0f);  
  26.                 streamID_2=sp.play(soundID_2, 0.8f, 0.8f,1, -11.0f);  
  27.             }  
  28.         });  
  29.     }  
  30. }  

發現按下按鈕,可以聽到兩種音效同時播放(因為我的程式碼中是播放2種)。

尾聲:

前面提到播放音效的方法play()會返回一個streamID,這個返回值在暫停 / 恢復時需要用到,比如恢復:

  1. publicfinalvoid resume (int streamID)  
看到了吧,所以最好用一些變數將他們儲存起來。


如果還有不懂的,可以直接參考API:

http://www.android-doc.com/reference/android/media/SoundPool.html