音訊轉碼器介面

當編解碼器是控制器驅動程式庫的次要項目時,就適合使用編解碼器介面。這個介面是由編解碼器驅動程式公開的 FIDL 通訊協定。在此配置中,轉碼器驅動程式不會直接公開串流介面,而是由控制器透過轉碼器介面進行設定。這是驅動程式庫作者的參考資料,定義編解碼器驅動程式必須實作的介面合約,以及控制器可使用的介面合約。

標記法和術語

本文內容:

  • 所有索引都從 0 開始。
  • n 個元素的向量會以 <x0,x1,...,xn-1> 表示,例如含有兩個元素 (5 和 6) 的向量會以 <5,6> 表示。
  • 向量可以巢狀結構表示,也就是 <<5,6>,<7,8>> 代表含有 2 個向量的向量。
字詞 定義
頻道 音訊樣本的單一來源或目的地,通常由單一揚聲器算繪或由單一麥克風擷取。在 DAI 中,每個影格都會在固定數量的頻道中,包含固定數量的樣本。
轉碼器 可將信號從數位/類比編碼/解碼為類比/數位 (包括所有組合,例如數位到數位) 的實體或虛擬裝置。例如 DAC 放大器組合和 ADC 轉換器。
控制器 系統中管理音訊信號的部分,例如 SOC 的音訊子系統或獨立音效卡。
DAI 數位音訊介面。音訊硬體之間的介面,例如控制器與編解碼器之間的 TDM 或 PDM 連結。
Frame 在資料中代表單一時間點,例如 DAI 中的影格同步和 sclk。
影格同步 標記影格邊界的 DAI 信號,又稱 LRCLK、SYNC。
影格格式 影格的資料、影格同步和 sclk 排列方式,例如影格同步相對於資料線中樣本的位置。
Mclk 主時脈,有時需要 DAI 信號為編解碼器提供時脈。有時 Sclk 會做為 Mclk 使用 (或 Mclk 是從編解碼器內的 Sclk 衍生而來)。
PDM 脈衝密度調變。用於表示類比訊號的調變形式,例如用於數位麥克風介面。
範例 在特定時間擷取的聲音數位表示法。
Sclk 用來標記資料線位元傳輸的 DAI 信號: 時脈,又稱 SCK、BCLK。
運算單元 影格內保留給樣本的位元。插槽可能比保存樣本所需的空間更大,例如保存 24 位元或 16 位元樣本的 32 位元插槽。
TDM 分時多工。將不同資料串流多工處理至一個音訊介面,包括 Sclk、Frame Sync,以及輸入和輸出資料訊號。

基本操作

編解碼器提供的功能可分為:

控制器負責設定及控制轉碼器。編解碼器會宣傳功能,控制器則會決定如何使用這些功能,詳情如下。控制器可以控制轉碼器的狀態,例如透過重設函式。必須重設編解碼器,才能將其恢復為初始狀態。 請注意,編解碼器驅動程式應自行關閉,就像任何其他驅動程式庫一樣。

轉碼器是複合裝置,可為控制器提供轉碼器通訊協定。預期只有一個控制器會使用轉碼器的通訊協定,而一個控制器可能會同時使用多個轉碼器。

simple-codec 程式庫可協助您編寫及使用實作編解碼器通訊協定的簡單編解碼器驅動程式。

通訊協定定義

編解碼器通訊協定定義於 codec.fidl 的 FIDL 中。

請注意,由於 FDF 目前無法直接取得 FIDL 通訊管道,因此我們定義了透過 Banjo 在 fuchsia.hardware.audio 取得管道的方式。

許多編解碼器通訊協定作業都是「啟動後便不須控制」,也就是說,這些作業不需要回覆。如果編解碼器通訊協定作業有回覆,則必須收到函式回覆才算完成,且回覆必須包含狀態 ZX_OK 才算成功。

主要控制項

控制器隨時可以發出 Reset 函式來重設轉碼器。

GetInfo 函式會從轉碼器擷取資訊,包括:

  1. 編解碼器單元的專屬永久 ID,例如序號或連線路徑。
  2. 製造商名稱。
  3. 產品名稱。

您隨時可以使用 StartStop 函式啟動及停止轉碼器作業。編解碼器狀態預設為停止,因此必須至少發出一次「開始」指令,編解碼器才能完全運作。舉例來說,停止轉碼器作業可安全地變更 DAI 設定,避免轉碼器作業發生故障或錯誤。

橋接模式

在開機時,驅動程式庫可能會設定裝置為橋接模式,也可能不會。驅動程式只會宣傳目前設定模式支援的 DAI 格式。因此,支援的 DAI 格式清單可能會因驅動程式庫啟動設定而異。

DAI 格式

DAI 格式相關的通訊協定函式可讓轉碼器列出 DAI 支援的格式。支援的格式可能包含多種範例格式、速率等。每個轉碼器都會宣傳支援的格式,而控制器會為每個轉碼器強制規定要使用的 DAI 格式。

如要瞭解特定轉碼器支援的格式,控制器會使用 GetDaiFormats 函式。編解碼器會回覆 DaiSupportedFormats 向量,其中每個 DaiSupportedFormats 包含:

  1. 聲道數的向量。這會列出編解碼器支援的聲道數量,例如 <2,4,6,8>。立體聲編解碼器會回報含有一個元素 <2> 的向量。請注意,如果轉碼器採用一個管道,並在所有輸出內容中輸出該聲道的內容 (例如立體聲擴音器為 2),則會回報含有一個元素 <1> 的向量。如果轉碼器支援一或兩個輸入聲道,則會回報含有兩個元素 <1,2> 的向量。
  2. 樣本格式的向量。DAI 範例格式,例如 PCM_SIGNED
  3. 影格格式向量,例如 STEREO_LEFTSTEREO_RIGHT
  4. 費率向量。畫面更新率,例如 44100、48000 和 96000。
  5. 每個時段的位元數。DAI 中每個時段的位元數,例如每個時段 32 位元。
  6. 每個樣本的位元向量。樣本寬度,例如每個樣本 24 位元。

如果無法使用單一 DaiSupportedFormats 描述編解碼器支援的所有組合,編解碼器會在傳回的向量中傳回多個 DaiSupportedFormats

舉例來說,如果某個 DaiSupportedFormats 允許 48KHz 的 32 位元樣本和 96KHz 的 16 位元樣本,但不允許 96KHz 的 32 位元樣本,則編解碼器會回覆 2 個 DaiSupportedFormats<<32bits>,<48KHz>><<16bits>,<96KHz>>。為求簡單起見,本範例會忽略速率和每個樣本的位元以外的參數。如果轉碼器支援 48 或 96KHz 的 16 或 32 位元樣本,轉碼器會回覆 1DaiSupportedFormats<<16bits,32bits>,<48KHz,96KHz>>

此外,我們假設每個樣本的位元數一律小於或等於每個時段的位元數。因此,轉碼器可以回報 <<16bits_per_slot,32bits_per_slot>,<16bits_per_sample,32bits_per_sample>> 這並不代表轉碼器回報的 16 位元樣本中,每個樣本 32 位元是有效的,而是指明 3 種有效組合:

  1. 16 位元樣本的 16 位元時段
  2. 32 位元樣本的 32 位元時段
  3. 32 位元時段,16 位元樣本

控制器會根據編解碼器在 IsBridgeableGetDaiFormat 中提供的資訊、控制器支援的項目,以及任何其他需求,使用 SetDaiFormat 函式指定要在 DAI 中使用的格式。這個函式會採用指定下列項目的參數:

  1. 頻道數量。這是 DAI 中要使用的通道數 (例如 TDM 匯流排上的通道數,也就是「在線路上的通道數」)。如果是 I2S,這項值必須為 2。
  2. 要使用的管道向量。這些是編解碼器使用的 DAI 管道。如果是 I2S,這必須是具有 2 個索引 <0,1> 的向量,也就是使用左右聲道。在橋接模式中,這只會列出編解碼器要使用的單一管道,例如橋接至 I2S DAI 右管道單一電子單聲道輸出的編解碼器立體聲放大器輸出,只會列出管道 <1>。如果未橋接,設定為單一管道的編解碼器有多個電子輸出,預期會在所有輸出上複製這個單聲道輸入中的樣本。SetDaiFormat
  3. 範例格式。
  4. 影格格式。
  5. 影格率。
  6. 每個時段的位元數。
  7. 每個樣本的位元數。

SetDaiFormat 成功後,系統會視為 DAI 格式設定完成,並可透過 DAI 傳送樣本。

增強控制

編解碼器會回應 GainFormat 結構中的 GetGainFormat 函式,傳回任何指定編解碼器支援的相關支援。控制器可以使用 SetGainState 函式,控制轉碼器中的增益、靜音和 AGC 狀態。

用戶端可以使用 WatchGainState 指令,要求轉碼器傳送增益狀態變更的非同步通知。驅動程式會回覆用戶端傳送的第一個 |WatchGainState|,且不會回應後續的用戶端 |WatchGainState| 呼叫,直到增益狀態與最近回報的狀態不同為止。

偵測插頭

如果驅動程式庫在 GetPlugDetectCapabilites 中傳送 CAN_ASYNC_NOTIFY 旗標,用戶端可以使用 WatchPlugState 指令,要求編解碼器傳送插頭狀態變更的非同步通知。如果編解碼器驅動程式未設定 CAN_ASYNC_NOTIFY 標記,可以忽略用戶端傳送的 WatchPlugState。驅動程式會回覆用戶端傳送的第一個 CAN_ASYNC_NOTIFY|WatchPlugState|,且不會回應後續的用戶端 |WatchPlugState| 呼叫,直到外掛程式狀態與最近回報的狀態不同為止。

信號處理

定義請參閱「音訊信號處理」。