Files
Obsidian-Main/03. 專注Study/Android/AudioTrack.md
Awin Huang 6ea67bc02c vault backup: 2022-09-30 22:03:03
Affected files:
03. 專注Study/Android/AudioTrack.md
2022-09-30 22:03:03 +08:00

2.1 KiB
Raw Blame History

AudioTrack 和 MediaPlayer 都可以播放聲音,主要差別是 AudioTrack 沒有 decode 的能力,只能播放 PCM。

底層原理

每一個 audio stream 對應著一個 AudioTrack 類的一個實例,每個 AudioTrack 會在建立時會註冊到 AudioFlinger 中,由 AudioFlinger 把所有的 AudioTrack 進行混合Mixer然後輸送到 AudioHardware中 進行播放,目前 Android 同時最多可以創建32個音頻流也就是說Mixer 最多會同時處理32個 AudioTrack 的資料。

建立 AudioTrack 物件

const val SAMPLE_RATE = 44100  
const val CHANNEL_OUT_FORMAT = AudioFormat.CHANNEL_OUT_STEREO  
const val AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT
var audioBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_OUT_FORMAT, AUDIO_FORMAT)

audioTrack = AudioTrack(
    AudioManager.STREAM_MUSIC,
    SAMPLE_RATE,  
    CHANNEL_OUT_FORMAT,  
    AUDIO_FORMAT,  
    audioBufferSize,
    AudioTrack.MODE_STREAM)
audioTrack?.play()

其中需要注意的是最後一個參數AudioTrack 有兩種模式,分別是 AudioTrack.MODE_STREAM 與 AudioTrack.MODE_STATIC。

AudioTrack.MODE_STREAM

這個模式會邊讀邊播,必須不停的使用 AudioTrack.write() 來將資料寫入,若是來不及寫入會造成斷音,可以先呼叫 AudioTrack.play(),然後開始填資料。

AudioTrack.MODE_STATIC

這個模式中audioBufferSize 就是你要播放的聲音長度,一樣要透過 AudioTrack.write() 來寫入資料,寫完之後呼叫 AudioTrack.play() 開始播放。

狀態判斷

getState()

getState() 來取得目前的狀態。

  • STATE_INITIALIZED 表示AudioTrack 已經是可以使用了。
  • STATE_UNINITIALIZED 表示AudioTrack 創建時沒有成功地初始化。
  • STATE_NO_STATIC_DATA 表示當前是使用MODE_STATIC 但是還沒往緩衝區中寫入數據。當接收數據之後會變為STATE_INITIALIZED 狀態。

getPlayState()

getPlayState() 來取得目前的播放狀態。

  • PLAYSTATE_STOPPED 停止
  • PLAYSTATE_PAUSED 暫停
  • PLAYSTATE_PLAYING 正在播放

暫停

pause() 可以暫停播放,但是暫存區不會被清空