【Android 高性能音频】AAudio 状态机 ( 创建 | 打开 Open | 开始 Started | 暂停 Paused | 刷写 Flushed | 停止 Stopped | 关闭 )
文章目錄
- I . AAudio 音頻流 創建 配置 使用 銷毀 流程
- II . AAudio 音頻流 穩定狀態 與 過渡狀態
- III . AAudio 音頻流 狀態改變 監聽
- IV . AAudio 音頻流 狀態改變 監聽 實例 ( 暫停操作 )
- V . AAudio 音頻流 狀態改變 監聽 注意事項
I . AAudio 音頻流 創建 配置 使用 銷毀 流程
紅色標題是本博客講解的內容 , 黑色是前幾篇講過的內容 ;
使用 AAudio 音頻庫 , 首先需要導入 AAudio.h 頭文件 ;
#include <AAudio.h>創建 AAudio 音頻流 , 需要先創建 AAudio 音頻流構建器 , 然后在通過該構建器創建音頻流 ;
//創建構建器 , AAudio 音頻流通過該構建器創建//聲明 AAudio 音頻流構建器 指針AAudioStreamBuilder *builder = nullptr;//創建 AAudio 音頻流構建器 , 注意傳入二維指針aaudio_result_t result = AAudio_createStreamBuilder(&builder);設置音頻設備 ID ;
// 設置音頻流設備 IDAAudioStreamBuilder_setDeviceId(builder, playbackDeviceId_);設置音頻流方向 ;
// 設置音頻流方向AAudioStreamBuilder_setDirection(builder, AAUDIO_DIRECTION_OUTPUT);設置音頻設備共享模式 ;
// 設置共享模式 , 獨占模式性能更高 , 延遲更低 ; 如果 該音頻設備正在被使用 , 設置失敗會自動設置成 共享模式AAudioStreamBuilder_setSharingMode(builder, AAUDIO_SHARING_MODE_EXCLUSIVE);設置性能模式 ;
// 設置性能模式AAudioStreamBuilder_setPerformanceMode(builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);設置 AAudio 音頻流通道數 :
// 設置通道個數AAudioStreamBuilder_setChannelCount(builder, sampleChannels_);設置 AAudio 音頻流樣本格式 :
// 設置音頻格式AAudioStreamBuilder_setFormat(builder, sampleFormat_);設置 AAudio 音頻流緩沖區大小 : 這里的緩沖區是播放器的緩沖區 , 單位是幀 , 每幀的采樣數就是通道數 , 單聲道 每幀 1 個采樣, 雙聲道立體聲每幀 2 個采樣 , 分別對應左右聲道的采樣 ;
// 設置每幀的緩沖區大小 , 可以通過該設置達到盡可能低的延遲AAudioStream_setBufferSizeInFrames(playStream_, framesPerBurst_);創建 AAudio 音頻流 : 創建 AAudio 音頻流 , 就是打開音頻流 , 注意要在音頻流參數設置完畢后才能打開音頻流 ;
// 打開音頻流 ( 該步驟就是創建音頻流 )aaudio_result_t result = AAudioStreamBuilder_openStream(builder, &playStream_);銷毀 AAudio 音頻流構建器 : 在音頻流創建 ( 打開 ) 完畢后 , 應該馬上銷毀 AAudio 音頻流構建器 ;
//銷毀音頻流構建器AAudioStreamBuilder_delete(builder);使用 AAudio 音頻流 進行 錄音 或 播放操作 , 使用完畢后需要 銷毀 AAudio 音頻流 ;
停止 AAudio 音頻流 : 如果 AAudio 音頻流不再使用 , 需要馬上銷毀 AAudio 音頻流 , 銷毀前需要先將音頻流停止 , 然后才能銷毀 ;
//先停止音頻流 , 然后才能關閉aaudio_result_t result = AAudioStream_requestStop(playStream_);關閉 AAudio 音頻流 : 如果 AAudio 音頻流不再使用 , 需要馬上銷毀 AAudio 音頻流 , 該流會占據音頻設備資源 , 不用應馬上銷毀 ;
//關閉音頻流 , 關閉后 , 該音頻流就徹底釋放了 , 如果在使用 , 必須重新創建result = AAudioStream_close(playStream_);II . AAudio 音頻流 穩定狀態 與 過渡狀態
1 . AAudio 音頻流有 6 種穩定狀態 :
- ① Open : 音頻流打開后的狀態 , 就是 Open 狀態 , 該狀態時間很短 , 馬上回自動轉到下一狀態 ;
- ② Started : 音頻流打開后 , 會自動從 Open 狀態轉為 Started 狀態 , 該狀態下音頻流的音頻數據 , 處于流動狀態 , 這個過程占生命周期的 99.999% 的時間 ;
- ③ Paused : 暫停狀態 , 在 Started 狀態下 , 如果調用 AAudioStream_requestPause() 方法 , 就會進入該狀態 ; 此時播放器是暫停的 , 可以隨時恢復播放 , 調用 AAudioStream_requestStart() 方法 , 可以恢復播放 , 進入 Started 狀態 ;
- ④ Flushed : 刷寫狀態 , 在 Paused 狀態下 , 調用 AAudioStream_requestFlush() 方法 , 就會進入該狀態 , 這是將播放器緩沖區中的數據播放完畢 , 可以清空緩沖區 ; 調用 AAudioStream_requestStart() 方法 , 可以恢復播放 , 進入 Started 狀態 ;
- ⑤ Stopped : 停止狀態 , 在 Started 狀態下 , 如果調用 AAudioStream_requestStop() 方法 , 就會進入該狀態 ; 此時如果要恢復成 Started 狀態 , 需要調用 AAudioStream_requestStart() 方法 ;
- ⑥ Closed : 關閉狀態 , 在 Stopped 狀態下 , 如果調用 AAudioStream_close() 方法 , 就會進入 Closed 狀態 ; 該狀態意味著 AAudio 音頻流被銷毀 , 無法再繼續使用 ;
總結 :
處于 暫停 ( Paused ) , 停止 ( Stopped ) , 刷寫 ( Flushed ) 狀態下 , 可以調用 AAudioStream_requestStart() 方法 , 恢復成 Started 狀態 ;
刷寫 ( Flushed ) 狀態 必須 有前置狀態 暫停狀態 ( Paused ) 才能進入該狀態 , 其它狀態下是無法進入 刷寫狀態的 ;
2 . AAudio 音頻流有 5 種 過渡狀態 : 過渡狀態是兩種穩定狀態之間的狀態 ;
- ① Starting 狀態 : Open 狀態 與 Started 狀態 之間的 過渡狀態 ;
- ② Pausing 狀態 : Started 狀態 與 Paused 狀態之間的 過渡狀態 ;
- ③ Flushing 狀態 : Paused 狀態 與 Flushed 狀態之間的 過渡狀態 ;
- ④ Stopping 狀態 : Started 狀態 與 Stopped 狀態 之間的過渡狀態 ;
- ⑤ Closing 狀態 : Stopped 狀態 與 Closed 狀態 之間的過渡狀態 ;
3 . 11 個狀態之間的狀態機轉化關系如下圖 :
III . AAudio 音頻流 狀態改變 監聽
1 . AAudio 音頻流狀態監聽簡介 :
- ① 沒有回調函數 : AAudio 沒有提供 監聽 音頻流狀態的 回調函數 ;
- ② 等待變更方法 : 目前只能使用 AAudioStream_waitForStateChange() 方法 , 該方法調用后 , 開始阻塞 , 等待 AAudio 音頻流變更成 不同于 開發者指定的狀態 的 其它狀態后 , 繼續執行下面的代碼 ;
2 . AAudioStream_waitForStateChange 方法簡介 :
- ① 函數原型 : 調用該函數時 , 當前狀態應該是 inputState 狀態 , 之后一直阻塞 , 該函數會等待 當前狀態 , 不是 inputState 狀態時 , 接觸阻塞 , 繼續執行下面的代碼 ;
- ② 參數 1 AAudioStream *stream : 狀態機所屬的 AAudio 音頻流 ;
- ③ 參數 2 aaudio_stream_state_t inputState : 初始狀態 , 調用該方法時的狀態 ; 當 AAudio 音頻流狀態不是該狀態時 , 方法阻塞解除 ;
- ④ 參數 3 aaudio_stream_state_t *nextState : 下一個狀態的指針 , 指向一個狀態值 , 該值是 解除阻塞的時刻的 AAudio 音頻流狀態 ; 用于在后續執行時獲取當前是什么狀態 ;
- ⑤ 參數 4 int64_t timeoutNanoseconds : 超時時間 , 該方法不可能一直阻塞代碼執行 , 當超過一定時間后 , 繼續執行后續的代碼 ;
- ⑥ 返回值 aaudio_result_t : 如果成功 , 返回 AAUDIO_OK , 如果失敗會返回對應的錯誤碼 ;
IV . AAudio 音頻流 狀態改變 監聽 實例 ( 暫停操作 )
1 . 監聽暫停操作 : 在 Started 狀態下 , 調用 AAudioStream_requestPause() 方法 , 設置 AAudio 音頻流暫停操作 ;
2 . 理論上的狀態改變 : 方法調用后 , AAudio 音頻流 會立刻進入 Pausing 過渡狀態 , 然后處理過渡操作 , 處理完畢后 , 進入 Paused 狀態 ;
3 . 代碼實現 :
- ① 申請暫停 : 調用 AAudioStream_requestPause() 方法之后 ;
- ② 當前狀態 : 申請暫停后 , 當前狀態馬上切換成了 Pausing 狀態 ;
- ③ 阻塞程序 : 此時 立刻調用 AAudioStream_waitForStateChange() 方法 , 其中的 第二個參數 inputState 設置成 Pausing 狀態 , 該方法阻塞了程序運行 ;
- ④ 解除阻塞 : 當狀態由 Pausing 轉為其它狀態 ( 一般是 Paused 狀態 ) , 或者超時 , 阻塞解除 , 繼續執行下面的代碼 ;
V . AAudio 音頻流 狀態改變 監聽 注意事項
1 . 申請關閉 操作 無法監聽狀態 : 當前如果是 Stopped 狀態 , 調用 AAudioStream_close() 方法后 AAudio 音頻流會直接被刪除 , 無法調用 AAudioStream_waitForStateChange 方法監聽 音頻流 狀態 ;
2 . 監聽時不要關閉流 : 如果調用了 AAudioStream_waitForStateChange () 方法監聽 AAudio 音頻流 狀態 , 當前線程雖然在阻塞狀態 , 無法操作 , 但是不要在另外的線程中關閉該 AAudio 音頻流 ;
總結
以上是生活随笔為你收集整理的【Android 高性能音频】AAudio 状态机 ( 创建 | 打开 Open | 开始 Started | 暂停 Paused | 刷写 Flushed | 停止 Stopped | 关闭 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 高性能音频】AAudi
- 下一篇: 【Android 高性能音频】AAudi