使用AudioTrack播放PCM
為什么只播放PCM不播放Mp3呢怒医?因?yàn)锳udioTrack是基礎(chǔ)API昧碉,沒(méi)有解碼功能,而MediaPlayer是有解碼功能的踱启。所以要播放Mp3俏讹,還需要自行添加解碼功能,把Mp3解碼為PCM再播放纵势。
只要做好兩件事情:
- AudioTrack的初始化參數(shù)的含義
- AudioTrack的播放流程:play->write->stop
1. 初始化AudioTrack
//獲取最小緩沖區(qū)大小
int minBufferSize = AudioTrack.getMinBufferSize(SAMPLE_RATE, //采樣率
AudioFormat.CHANNEL_OUT_STEREO, //雙聲道
AudioFormat.ENCODING_PCM_16BIT //采樣格式
);
//初始化AudioTrack對(duì)象
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, //媒體類型
SAMPLE_RATE, //采樣率
AudioFormat.CHANNEL_IN_STEREO, //雙聲道
AudioFormat.ENCODING_PCM_16BIT, //采樣格式
minBufferSize, //緩沖區(qū)大小
AudioTrack.MODE_STREAM //流式加載
);
參數(shù)詳解:
- 參數(shù)一:streamType
Android手機(jī)上提供了多重音頻管理策略(例如按一下手機(jī)側(cè)面音量鍵踱阿,會(huì)出現(xiàn)多個(gè)音量管理,這其實(shí)就是不同音頻策略的音頻控制展示)钦铁,當(dāng)系統(tǒng)有多個(gè)進(jìn)程需要播放音頻的時(shí)候软舌,管理策略會(huì)決定最終的呈現(xiàn)效果,該參數(shù)的可選值將以常量的形式定義在類AudioManager中牛曹,主要包括以下內(nèi)容:
public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_
public static final int STREAM_SYSTEM = AudioSystem.STREAM_SYSTEM;
public static final int STREAM_RING = AudioSystem.STREAM_RING;
public static final int STREAM_MUSIC = AudioSystem.STREAM_MUSIC;
public static final int STREAM_ALARM = AudioSystem.STREAM_ALARM;
- 參數(shù)二:sampleRateInHz
采樣率佛点,即播放的音頻每秒鐘會(huì)有多少次采樣,可選用的采樣頻率列表為:8000躏仇、16000恋脚、22050、24000焰手、32000糟描、44100、48000等书妻,要根據(jù)播放的PCM的采樣率來(lái)決定初始化AudioTrack時(shí)的具體值船响,否則可能導(dǎo)致聲音變快或者變慢 - 參數(shù)三:channelConfig
聲道數(shù)(通道數(shù))配置躬拢,可選值以常量形式配置在類AudioFormat中,常用的是CHANNEL_IN_MONO(輸入單聲道)见间,CHANNEL_IN_STEREO(輸入雙聲道)聊闯。(因?yàn)楝F(xiàn)在大多數(shù)手機(jī)的麥克風(fēng)都是偽立體聲采集,為了性能考慮米诉,建議使用單聲道進(jìn)行音頻采集菱蔬,而轉(zhuǎn)變?yōu)榱Ⅲw聲的過(guò)程可以在聲音的特效處理階段來(lái)完成)。 - 參數(shù)四:audioFormat
該參數(shù)是用來(lái)配置數(shù)據(jù)位寬史侣,表示了采樣精度拴泌,可選值以常量的形式定義在類AudioFormat中,分別為ENCODING_PCM_16BIT和ENCODING_PCM_8BIT惊橱,注意蚪腐,前者是可以兼容安卓所有手機(jī)的。 - 參數(shù)五:bufferSizeInBytes
它配置的是AudioTrack內(nèi)部緩沖區(qū)的大小税朴,AudioTrack類提供了一個(gè)靜態(tài)方法getMinBufferSize
來(lái)幫忙開(kāi)發(fā)者確定緩沖區(qū)的大小回季,在實(shí)際開(kāi)發(fā)中,強(qiáng)烈建議使用該方法正林,而不是自己手動(dòng)計(jì)算泡一。 - 參數(shù)六:mode
AudioTrack提供了兩種播放模式,可選的值以常量的形式定義在類AudioTrack中卓囚,分別為:
- MODE_STREAM 按照一定的時(shí)間間隔不間斷地定入音頻數(shù)據(jù)瘾杭,理論上它可以應(yīng)用于任何音頻播放的場(chǎng)景
- MODE_STATIC 需要一次性將所有的數(shù)據(jù)都寫(xiě)入播放緩沖區(qū)中,簡(jiǎn)單高效哪亿,通常用于播放鈴聲粥烁、系統(tǒng)提醒的音頻片段。
2. 啟動(dòng)播放
//先啟動(dòng)播放
audioTrack.play();
3. write音頻數(shù)據(jù)
//分配緩沖區(qū)
byte[] buffer = new byte[minBufferSize * 3];
is = getAssets().open(pcmFilePath);
dis = new DataInputStream(is);
int readCount = 0;
while (dis.available() > 0) {
//讀取PCM
readCount = dis.read(buffer);
Log.d(MainActivity.class.getSimpleName(), "readCount=" + readCount);
if (readCount == AudioTrack.ERROR_INVALID_OPERATION || readCount == AudioTrack.ERROR_BAD_VALUE) {
continue;
}
if (readCount != 0 && readCount != -1) {
//寫(xiě)入AudioTrack
audioTrack.write(buffer, 0, readCount);
}
}
...
audioTrack.stop();