日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

【Android 高性能音频】AAudio 音频流 PCM 采样 的 采样 缓冲 播放 的 连续机制 ( 数据回调机制 | 数据回调函数指针 | 实现数据回调函数 | 设置数据回调函数 )

發布時間:2025/6/17 47 豆豆

文章目錄

        • I . AAudio 音頻流 采樣 緩沖 播放 的連續機制
        • II . AAudio 音頻流 數據回調函數 函數指針類型定義
        • III . AAudio 音頻流 數據回調函數 實現
        • IV . AAudio 音頻流 數據回調函數 設置



I . AAudio 音頻流 采樣 緩沖 播放 的連續機制



1 . AAudio 音頻流的 采樣 緩沖 播放 流程 : 樣本采樣完成后 , 存入緩沖區 , 然后將其通過 AAudio 播放出來 , 采樣階段采集 nnn 個樣本 , 然后將其放入緩沖區 , 將緩沖區的數據 寫出到 AAudio 音頻流中播放出來 ;


2 . 采樣速度高于播放速度 : 如果采樣采集多了 , 不能立刻播放 , 此時就會產生延遲 , 并且如果超出緩沖區大小 , 超出部分采樣就會溢出 , 造成數據損失 , 樣本不連續 , 就會產生電流 ;


3 . 采樣速度低于播放速度 : 如果采樣少了 , 不能向 AAudio 音頻流中寫入足夠的數據 , 就會造成電流雜音等情況 ;


4 . 數據回調函數 引入 : 數據回調函數就是為了解決上述問題 , 引入的機制 ;


5 . 數據回調函數 簡介 :

  • ① 采樣緩沖 : 采樣后 , 將采集的樣本存入緩沖區 ;
  • ② 播放采樣 : 將緩沖區中的樣本寫入 AAudio 音頻流 ;
  • ③ 調用回調函數 : AAudio 音頻流如果播放完當前數據 , AAudio 就會自動調用 開發者按照 規范開發的 回調函數 申請后續采樣數據 ;
  • ④ 回調函數內容 : 開發者自己實現該回調函數 , 在這個函數中實現采樣 并將采樣設置給 AAudio 音頻流 , 之后繼續播放音頻采樣 ;

之后如果采樣播放完畢 , 繼續調用回調函數 ;


下面會著重講解該數據回調函數的細節



II . AAudio 音頻流 數據回調函數 函數指針類型定義



數據回調函數原型 : AAudio 只定義了一個函數類型 , 該函數的實際內容需要開發者自己開發 , 一般是 采樣 , 然后 設置數據給 AAudio 音頻流 的操作 ;

typedef aaudio_data_callback_result_t (*AAudioStream_dataCallback)(AAudioStream *stream,void *userData,void *audioData,int32_t numFrames);
  • ① 函數類型 : 該數據回調函數類型如下 , 其返回值是 aaudio_data_callback_result_t 類型 , 四個參數分別如下 ;
aaudio_data_callback_result_t (*)(AAudioStream *stream,void *userData,void *audioData,int32_t numFrames)
  • ② 函數別名 : 使用 typedef 關鍵字為 上述函數指針類型 賦予一個類型別名 AAudioStream_dataCallback ;
  • ③ 參數一 AAudioStream *stream : AAudio 音頻流指針 ;
  • ④ 參數二 void *userData : 該參數用于傳遞一些額外數據 , 與 AAudioStreamBuilder_setCallback() 中的 第三參數 void *userData 參數指向的地址一致 ;
  • ⑤ 參數三 void *audioData : 指向音頻采樣數據的指針 , AAudio 會自動將該數據輸出或輸入到音頻流中 ;
  • ⑥ 參數四 int32_t numFrames : 要處理的幀數 , 需要將多少幀的 audioData 指針指向的音頻采樣數據 , 輸入 或 輸出到 AAudio 音頻流中 ;


III . AAudio 音頻流 數據回調函數 實現



aaudio_data_callback_result_t (*)(AAudioStream *stream,void *userData,void *audioData,int32_t numFrames)

1 . 數據回調函數設置給 AAudio 音頻流 : AAudio 中通過 AAudioStreamBuilder_setDataCallback() 函數 , 將用戶自己實現的 AAudioStream_dataCallback 回調函數的函數指針設置給 AAudio 音頻流 , 當 AAudio 音頻流需要數據時會自動回調該函數 ;


2 . 輸出流回調函數實現內容 : 在該函數中需要 按照 AAudio 音頻流的當前數據格式 ( 通道數/每幀樣本數 , 采樣率 ) , 采集 numFrames 幀的 PCM 音頻樣本數據 ( 每幀的采樣數與通道數一致 ) , 將這些樣本數據寫出到 void *audioData 指針指向的內存中 , 之后這些數據會被自動輸出到 AAudio 音頻流中 ;


3 . 輸入流回調函數實現內容 : 在函數中需要從 void *audioData 指針指向的內存中 , 讀取 numFrames 幀 ( 每幀的采樣數與通道數一致 ) 的采樣數據 , 注意需要按照當前的 采樣格式 ( 通道數/每幀樣本數 , 采樣率 ) 計算讀取的字節大小 ;


4 . 采樣數據自動傳輸 ( 不需要手動干預 ) : 在回調函數中 , 將 numFrames 幀的數據傳遞給 void *audioData , AAudio 在該回調函數執行完畢后 , 會自動將這些數據 讀/寫 到 AAudio 音頻流中 , 不需要 開發者 手動調用 AAudioStream_read() 或 AAudioStream_write() 方法 , 一調用必出錯 ;


5 . 每次讀寫的幀數 int32_t numFrames :

  • ① 固定幀數 : 通過調用 AAudioStreamBuilder_setFramesPerDataCallback() 方法可以設置每次回調都讀寫固定幀數的音頻采樣 ;
  • ② 自由幀數 : 如果用戶沒有指定幀數 , 那么在每次回調函數中的 numFrames 幀數可以由用戶自己設置 ;

6 . 不能執行耗時操作 : 在該回調函數中 , 不能執行太耗時的操作 或 阻塞操作 , 如果阻塞時間超過了采樣播放的時間 , 就會造成后續采樣無法及時 讀取 或 寫入 到 AAudio 音頻流中 , 出現音頻故障 ;


7 . 回調函數中不能執行的操作 : 該回調函數的回調頻率很高 , 可能達到每秒幾百到幾千次 , 因此有很多 耗時操作 或 訪問本地資源 的邏輯不能再該函數中運行 , 盡可能只對內存數據進行操作 ;

  • ① 內存操作 : 使用 malloc() 或 new 分配堆內存 , 極大可能造成內存泄漏或內存溢出 ;
  • ② 文件操作 : 打開 open , 關閉 close , 讀取 read , 寫出 write 等針對文件的操作 ;
  • ③ 網絡操作 : 訪問網絡操作 , 從網絡中讀取數據 , 或向遠程端口發送數據 ;
  • ④ 同步線程 : 線程間的同步操作會造成阻塞 ;
  • ⑤ 休眠阻塞 : sleep 方法不能執行 , 會造成阻塞 ;
  • ⑥ 關音頻流 : 停止 或 關閉 流操作 會造成不可預知故障 ;
  • ⑦ 讀寫操作 : 該函數中不用刻意調用 AAudioStream_read() 和 AAudioStream_write() 方法進行讀寫操作 ;

8 . 回調函數中可以進行的操作 :

  • ① 調用 AAudioStream_getXXX() 類方法 : 如下圖中列舉的方法可以直接調用 , 獲取 AAudio 音頻流的各種屬性 ;
  • ② 調用 AAudio_convertResultToText() 方法 : 將返回值轉為對應的 ASCII 字符 ;

9 . 非阻塞技術 : 如果需要在回調函數中 讀取 或 輸出 數據 , 建議使用非阻塞技術 , 如 FIFO 技術 ;



IV . AAudio 音頻流 數據回調函數 設置



1 . 數據回調函數設置方法 :

  • ① 函數原型 : 該方法用于設置 AAudio 音頻流回調函數 , 當 AAudio 需要 讀取 / 寫出數據時 , 會自動回調該 AAudioStream_dataCallback 類型 函數 ;
AAUDIO_API void AAudioStreamBuilder_setDataCallback(AAudioStreamBuilder *builder,AAudioStream_dataCallback callback,void *userData )
  • ② 參數 一 AAudioStreamBuilder *builder : AAudio 音頻流指針 ;
  • ③ 參數 二 AAudioStream_dataCallback callback : AAudioStream_dataCallback 是函數指針類型 , 開發者自己實現該函數 , 然后將函數的地址當做參數設置到此處 ;
typedef aaudio_data_callback_result_t (*AAudioStream_dataCallback)(AAudioStream *stream,void *userData,void *audioData,int32_t numFrames);
  • ④ 參數 三 void *userData : 該指針 與 AAudioStream_dataCallback 函數指針類型的第二個參數指向的地址是相同的 , 相當于傳入一個用戶自定義的指針 , 可以是任意類型任意數據任意變量 ;

2 . 音頻數據傳遞方式 : 在 AAudioStream_dataCallback 函數指針類型的回調函數中 , 音頻流的數據不是通過 AAudioStream_read 或 AAudioStream_write 方法進行讀寫的 , 只要將音頻采樣數據設置給函數的第三個參數 audioData 指針即可 , 第四個參數 numFrames 用于說明讀寫數據的幀數 , 每幀的采樣數 就是 采樣的通道數 ;

3 . 數據回調函數工作機制 :

  • ① 第一次回調 : 在 AAudio 音頻流調用 AAudioStream_requestStart() 方法后 , 會立刻回調該數據回調函數 , 然后第一次 讀寫采樣數據到 AAudio 音頻流中 ;
  • ② 循環回調 : 當 AAudio 音頻流 讀取或寫出數據完畢后 , 會自動回調該數據回調函數 , 在回調函數中準備下一次的采樣 , 讀寫到 AAudio 音頻流中 , 之后繼續循環 , 直到 AAudio 音頻流關閉銷毀 ;
  • ③ 實時線程 : AAudio 擁有一個實時線程 , 該數據回調函數就是運行在這個線程上的 ;
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的【Android 高性能音频】AAudio 音频流 PCM 采样 的 采样 缓冲 播放 的 连续机制 ( 数据回调机制 | 数据回调函数指针 | 实现数据回调函数 | 设置数据回调函数 )的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。