音訊驅動程式串流介面

本文件說明音訊驅動程式公開的音訊串流介面 。方便您同時參考其他使用者 以及明確定義驅動程式的介面合約 而且使用者必須確實遵守

總覽

音訊串流是指驅動程式庫服務發布的裝置節點,用於這類節點 以便擷取或算繪音訊至 Fuchsia 裝置。 系統中的每個串流 (輸入或輸出) 都代表一整組數位音訊串流 可能由裝置接收或傳輸的資訊。交流區 並且隨時可能由系統建立或毀損。哪些直播 以及可控管其生命週期的因素 是音訊政策和轉碼器管理方面的問題, 這項差異此外,音訊中的資訊 輸出內容串流專屬於串流的應用程式擁有者。混合 並非音訊串流介面提供的服務。

定義

字詞 定義
範例 這是以 單一說話者,或是由單一喇叭拍攝 同步運作
LPCM 線性脈搏程式碼調變:具體來說 代表訓練資料中的 所有的 Fuchsia 未壓縮音訊串流。LPCM 「音訊樣本」指的是 即時的音訊訊號振幅 時間值呈現 編碼音訊是線性散佈的 都能反映 或擷取裝置相對於 A-Law 和 μ-aw 編碼 將數值和非線性對應關係 振幅濃度
頻道 在音訊串流中, 會在轉譯前 單一喇叭,或是錄音 僅串流傳輸單個麥克風
框架 每個 在單一 Pod 擷取/算繪的音訊串流 即時處理
畫面更新率 a.k.a.「取樣率」。比率 (以 Hz 為單位) 產生的音訊影格數量 常見的取樣率包括 44.1 KHz、48 KHz、96 KHz 等。
用戶端、使用者或應用程式 這些字詞可相互替換 文件。指的是使用 能與 音訊驅動程式庫/裝置

基本作業

系統會透過以下方式傳送的訊息,與音訊串流裝置通訊 頻道。應用程式會開啟裝置節點 並透過發出 FIDL 要求取得管道。取得 管道裝置節點可能已關閉。與 多半透過頻道進行串流

串流管道用於大多數的命令和控制工作,包括:

  • 能力審訊
  • 格式協商
  • 硬體增益控制
  • 判斷外板延遲時間
  • 插頭偵測通知
  • 存取權控管能力偵測和訊號

為了在串流中確實傳送或接收音訊資訊, 必須先設定要使用的特定格式對成功 CreateRingBuffer 作業會包含新的「ring-buffer」頻道。環形緩衝區 管道可用於向串流要求共用緩衝區 ( 這類 VMO 形式,可能會對應到位址中 的運算空間,並用於視情況傳送或接收音訊資料。 一般而言,環形緩衝區管道執行的作業包括:

  • 要求共用緩衝區
  • 開始及停止播放及擷取串流
  • 接收播放和擷取進度通知
  • 在音訊輸出時鐘的情況下接收時鐘復原資訊 是以不同的振盪器為基礎 單調時鐘

作業詳細資料

裝置節點

音訊串流裝置節點必須由驅動程式採用通訊協定發布 上表中的預先處理工具符號。這麼做會導致串流裝置 發布在資料表內指定位置的節點應用程式可以 監控這些目錄,在發布新串流時發掘新內容 駕駛人

串流類型 通訊協定 位置
輸入 ZX_PROTOCOL_AUDIO_INPUT /dev/class/audio-input
輸出 ZX_PROTOCOL_AUDIO_OUTPUT /dev/class/audio-output

建立直播管道

開啟裝置節點後,用戶端應用程式可能會取得串流管道 進行後續通訊 fuchsia.hardware.audio.Device/GetChannel FIDL 訊息。

用戶端終止串流管道

用戶端可隨時終止與串流之間的連線,方法為直接 呼叫串流上的 zx_handle_close(...) 頻道。駕駛必須關閉任何已建立運作中的環形緩衝區頻道 使用這個串流管道,並且必須盡全力以循序漸進的方式 任何進行中的串流作業。

在串流和環形緩衝區頻道上傳送及接收訊息

可能傳送或接收的所有訊息和訊息酬載 會定義串流和環形緩衝區頻道的 stream_config.fidlring_buffer.fidl 建立。 系統可能會使用 zx_channel_write(...) syscall。如果回覆 該變數可能是使用 zx_channel_read(...) syscall。最佳做法 但會將管道的封包排入佇列 通訊埠使用 zx_port_queue(...) syscall,然後使用 zx_port_wait(...) 系統呼叫以判斷您的設定 的管道中有訊息 (預期回應或非同步) 通知)。 有不同語言的繫結,可輕鬆收發郵件 FIDL 訊息,尤其是針對 C++ 驅動程式 有助於建立作業的 SimpleAudioStream 但這個程式庫會使用 用於傳送及接收的新 C++ 繫結 FIDL 訊息。

格式協商

範例格式

Format 相關的通訊協定訊息可讓驅動程式庫列出支援的通訊協定 複製到用戶端支援的格式可能包含多種費率、每個樣本的位元、 等。每位驅動程式庫宣傳自身可支援的內容,並要求客戶要求使用何種格式 每位驅動程式庫使用的 CPU 限制

如要找出特定驅動程式庫支援的格式,用戶端會使用 GetSupportedFormats 函式。駕駛人回覆的向量 SupportedFormats,其中每個 SupportedFormats 都含有一個 PcmSupportedFormats,其中包含:

  • 頻道數量的向量。這份清單會列出支援的管道 驅動程式庫,例如 <2,4,6,8>。支援兩個或 四個管道回報一個包含兩個元素 <2,4> 的向量。必須依遞增順序排列。
  • 範例格式的向量,例如PCM_SIGNED
  • 稅率向量。影格速率,例如 44100、48000 和 96000。必須依遞增順序排列。
  • 每個樣本的位元組數。必須依遞增順序排列。
  • 每個樣本的位元向量。範例寬度,可能小於 可用的總位元組數,例如4 位元組樣本中的 24 位元必須依遞增順序排列。

當驅動程式庫支援的組合無法全部描述時 PcmSupportedFormats,驅動程式庫會傳回多個 PcmSupportedFormats 傳回的向量舉例來說,如果一個 PcmSupportedFormats 允許在以下位置提供 16 或 32 位元樣本 48KHz 和 16 位元樣本 (96 KHz),但沒有 32 位元樣本 (96 KHz),然後是驅動程式庫 有 2 則PcmSupportedFormats<<16bits,32bits>,<48KHz>><<16bits>,<96KHz>>。為求簡單起見,本範例會忽略 每個樣本的位元率和位元數如果是驅動程式庫支援 16 或 32 位元取樣率為 48 或 96KHz,驅動程式庫將以 1 PcmSupportedFormats<<16bits,32bits>,<48KHz,96KHz>>

此外,假設每個樣本的位元一律小於或等於 每個樣本 8 * 位元組。因此,驅動程式庫可以回報 <<2bytes_per_sample,4bytes_per_sample>,<16bits_per_sample,32bits_per_sample>> 但不代表它會回報每個樣本在 2 位元組 32 位元 樣本有效,其中僅指定 3 個有效的組合:

  • 含 16 位元有效位元的 2 位元組樣本頻道
  • 含 32 位元有效位元的 4 位元組樣本
  • 含 16 位元有效位元的 4 位元組樣本

用戶端會根據CreateRingBuffer 驅動程式庫在 GetSupportedFormats 回覆中提供的資訊 以及所有其他規定此函式使用的參數可指定:

  • 多個頻道。此為緩衝區中可用的頻道數量。
  • 可使用的頻道位元遮罩,以下是緩衝區中要使用的頻道 驅動程式。舉例來說,立體聲執行個體必須使用支援 2 位元的位元遮罩 0x3, 亦即管道 0 和 1 皆使用。
  • 範例格式。
  • 畫面更新率。
  • 每個樣本的位元組數。
  • 每個樣本的位元數。

注意:

  • 根據預設,多位元組範例格式會假設使用的是主機端。
  • PCM_FLOAT 編碼特別採用 IEEE 754 浮點 這種表示法
  • 根據預設,非浮點 PCM 編碼會假設為 2 個互補符號 整數值。例如:16 位元 PCM 範例格式的位元值介於 [0x8000, 0x7FFF],0x0000 代表零喇叭輻射。如果 使用 PCM_UNSIGNED 範例格式,位元值的範圍介於 [0x0000, 0xFFFF] 中的 0x8000 代表零抗辯。
  • 在大型管道中對較小的樣本大小進行編碼時 (例如將 20 或 24 位元的 32),則會使用 32 位元容器中最重要的位元,而 最低有效位元將遭到忽略 (靠左對齊)。例如:系統會對應 20 位元樣本 位於 32 位元容器的 [12,31] 範圍內 (將忽略 [0,11])。

設定所需的串流格式

為了選取串流格式,應用程式會透過CreateRingBuffer訊息 直播管道。應用程式會在訊息中指定要使用的格式。

用戶端會指定新的環形緩衝區管道, 串流作業會進行如果先前的環形緩衝區管道 啟動後仍為活躍狀態,驅動程式庫必須關閉這個管道, 請務必在每個 Pod 中, 在整個過程中 相關資訊與洞察也能儲存至知識庫

判斷外部延遲時間

音訊串流的外部延遲時間的定義為持續時間 處理輸出音訊從系統互連網路傳輸到揚聲器 或輸入音訊 (從麥克風傳輸到系統的系統) 以及 Google Cloud Interconnect舉例來說,假設是連接系統的外部轉碼器 或是使用 TDM 互連網路:如果這個互連網路引入 4 個影格延遲 與影格轉譯速度較快 那麼這個音訊路徑的外部延遲時間就是 相當於 4 個音訊影格的播放時間

外部延遲時間會回報至 DelayInfoexternal_delay 欄位 回應 WatchDelayInfo。駕駛應盡可能 正確報告驅動程式庫知道的所有誤點來源總數。 如需這類延遲的相關資訊,通常可以在轉碼器資料工作表中取得 使用 Intel HDA 等通訊協定,動態回報為轉碼器的屬性 USB Audio 規格,或是由下游裝置回報的 評估機制,例如 EDID。

正在判斷開啟延遲時間

音訊串流的 turn_on_delay 定義為可能出現的時間長度 參考環形緩衝區的音訊樣本,就能在 揚聲器Start核發的喇叭,或是來自麥克風的音訊 才開始錄製到環狀緩衝區中,也在 Start 之後 指令舉例來說,如果我們在連接系統的外部轉碼器 我們已關閉該功能以節省電力,收到 Start 指令後, 提供環形緩衝區的驅動程式庫會回覆 start_time,指出 環形緩衝區開始移動,而音訊樣本已開始 外部轉碼器。不過,與 external_delay 無關 (請參閱 以上 Determining external latency),外部轉碼器可能仍在開機 以降低耗電量模式。turn_on_delay,指定 RingBufferProperties 資料表,是驅動程式庫的最佳判斷上限 取得外部轉碼器輸出音訊所花費的時間 樣本。延遲也可能是其他原因造成,例如轉碼器的 內建的增加延遲時間以避免故障或驅動程式庫對藍牙進行抽象處理 通知遠端裝置開始播放音訊的延遲時間 樣本。由於 turn_on_delay 是估計值上限,因此音訊可能會開始 所以在 turn_on_delay 結束之前就開始玩或拍攝,所以這就是為什麼 如未取得播放的初始音訊樣本,則必須將延遲時間納入考量 或擷取螢幕畫面

external_delay 代表音訊樣本延遲的時間 或麥克風收音。turn_on_delay 不會延遲 並不表示任何緩衝處理,而是 系統可能無法實際播放/錄製音訊樣本的時間長度。 turn_on_delay 不會影響簡報時間的計算結果,但會受到影響 是否會影響簡報的進行狀態。針對播放作業,我們能以視覺化方式 將音訊樣本輸出至喇叭時,會有以下延遲情形:

                   |<--- external delay --->|
             |S|--|T|----------------------|P|----|O|
                   |<------- turn on delay ------->|

其中 S 表示核發 Start 的時間,T 表示時間 環形緩衝區中的位置開始移動時,亦即 start_timeStart 指令傳回的傳回資訊。P 表示 喇叭,O 表示擴大器完成開啟和音訊的時間 就能完全認真由於O超過P,因此這裡的turn_on_delay影響了實際 演講。

隨著時間過去,我們能以視覺化方式呈現環形緩衝區的目前位置 C 講者將看到樣本資料, P 「過去」是在O開啟擴大器時開啟。

                     |<--- external delay --->|
   |S|--|T|---------|C|-----------------|O|--|P|
         |<------- turn on delay ------->|

                                            |<--- external delay --->|
   |S|--|T|-----------------------------|O|-|C|---------------------|P|
         |<------- turn on delay ------->|

硬體增益控制

硬體增益控制能力回報

為了判斷串流的增益控制功能 (如果串流作業尚未執行完畢) 所以,應用程式會透過串流管道傳送 GetProperties 訊息。 這則訊息不需要提供參數。駕駛人使用 StreamProperties,包括取得其他功能。所有串流驅動程式 無論直播與否,都必須回應這則訊息 可以 任何增益控制所有獲利值會以 32 表示 位元浮點數,以 dB 表示。

駕駛人會以代表目前串流 以獲得控制能力目前增益設定會以布林值表示 ,用於指出串流是否可靜音 串流可以使用 AGC、增加和最大增益設定,以及 gain_step_dbgain_step_db 表示最小遞增單位 受到控制的因素影響。

舉例來說,如果擴大器的增益步數為 5 步,每個增重 7.5 分貝,最大為 0 dB 增益表示範圍大小為 (-30.0, 0.0),步距為 7.5。 能夠使用功能連續增益控制的擴大器可能會將 增加步數大小為 0.0。

無論靜音功能為何,固定收益串流的驅動因素都必須回報 最小增益為 (0.0, 0.0)。在這個例子中,gain_step_db 毫無意義 但駕駛應回報為 0.0。

設定硬體增益控制層級

為了變更串流目前的增益設定,應用程式會傳送 來自直播管道的 SetGain 訊息。這則訊息包含參數 GainState:表示要設定的取得參數,包括該值的 dB 增益值 都必須適用於串流、靜音和啟用 AGC

假設要求有效,驅動程式應將要求四捨五入至 最接近支援的增減步數大小例如,如果串流可以控制增益 範圍介於 -60.0 到 0.0 dB 之間,使用增益步大小 0.5 分貝, 要求將增益設為 -33.3 分貝,結果應可得出 -33.5 已套用。如果要求取得 -33.2 dB,而傳送到同一串流的要求,應該就會 可獲得 -33.0 美元

接收狀態通知

用戶端可能會要求串流將非同步通知 使用 WatchGainState 指令取得狀態變更。駕駛人會回覆 第一 |WatchGainState|而未回應後續 客戶 |WatchGainState|呼叫,直到取得狀態從最近的變更 。

插頭偵測

此外,為因應 與公車連線/中斷連線,直播功能或許能 在任何時間點插入或拔除電源例如一組 USB 耳機連上 USB 時可能會發布新的輸出串流,不過您可以選擇 是「mmwired」插入插座偵測的階段其他 USB 音訊轉接器 標準 3.5mm phono 耳機插孔可能會在連接後發布輸出串流 ,但選擇在使用者插入/拔除電源時,變更插入/未插電狀態 將 3.5 公釐耳機插孔拔下類比裝置。

查詢串流目前插上/未插電狀態的功能,以及 註冊以便註冊插頭狀態變更的非同步通知 (如果支援的話) 是透過插頭偵測訊息處理

插頭偵測功能

以便判斷串流的插頭偵測功能 (如果並未執行) 所以,應用程式會透過串流管道傳送 GetProperties 指令。 駕駛人使用 StreamProperties 回覆,包括插頭偵測功能 。plug_detect_capabilities

目前定義的有效外掛程式偵測功能旗標如下:

  • 串流硬體符合條件時,系統會設定 HARDWIRED 「hardwired」。也就是說,系統會將該串流視為 裝置仍會保持鎖定狀態例如 喇叭、一對 USB 耳機,或一個沒有插頭的外接式音訊裝置 來監控使用者行為
  • CAN_ASYNC_NOTIFY如果串流硬體同時有功能 以非同步方式偵測裝置的插頭狀態已變更,並且將 如果客戶要求這些通知,系統會顯示通知訊息。

插頭狀態通知

用戶端可能會要求串流將非同步通知 插入狀態變更,方法是使用 WatchPlugState 指令 (如果 CAN_ASYNC_NOTIFY) 標記由驅動程式庫在 StreamProperties 中傳送。例如:單據 未設定 CAN_ASYNC_NOTIFY 旗標,可以忽略先前傳送的 WatchPlugState 依應用程式的需求已設定CAN_ASYNC_NOTIFY的駕駛會回覆第一個人 |WatchPlugState|而不會回應後續用戶端 |WatchPlugState|,直到插頭狀態從最近回報的內容變更為止。

串流目的與關聯

Ring-Buffer 頻道

總覽

應用程式成功設定串流的格式後,即會在 回應的新管道代表關係 到串流的環形緩衝區用戶端會使用環形緩衝區管道建立 共用記憶體緩衝區,以及開始播放及停止播放及擷取音訊串流資料。

環形緩衝區內容是由用戶端 (播放) 產生, 。因此,客戶是播放的生產端和取用端 ,這位驅動程式庫是錄製內容的生產端,同時也是播放程式的人。 環形緩衝區內容可直接使用或由音訊硬體產生;或 可能經過軟體處理,由驅動程式庫完成每個樣本

環形緩衝區資料產生作業會從時間點開始以顯著速率執行 提供給 Start 指令使用。請注意,環形緩衝區 幾乎都會有某種形式的 FIFO 緩衝區 並在記憶體匯流排和音訊硬體之間進行 事先透過串流讀取的資訊 (在播放情況下),或 資料 (在擷取資料時)。用戶端查詢 進入此緩衝區,再開始進行 作業,讓他們知道串流的名詞推測距離有多遠/之後 讀取/寫入位置,以免音訊故障。 另請注意,由於系統的共用緩衝區特性, 驅動程式可能直接由這個緩衝區處理 DMA 並處理硬體 對執行於非自動架構的架構用戶端而言相當重要 確保快取一致, 將播放資料寫入緩衝區,或在讀取前使快取失效 擷取的資料查看「RingBufferProperties」中的driver_transfer_bytesring_buffer.fidl

取得共用緩衝區

如要傳送或接收音訊,應用程式必須先建立共用記憶體 緩衝區。方法是透過CreateRingBuffer 環形緩衝區管道。只有在環形緩衝區停止時才能做到。

如果使用 CreateRingBuffer 建立的管道遭到驅動程式庫關閉 這是因為緩衝區已建立,且環形緩衝區已 則必須不得停止環形緩衝區或捨棄 來擷取現有共用回憶集錦如果應用程式在取得新的緩衝區後, 已建立緩衝區,而環形緩衝區停止時, 假設現有緩衝區 ii 無效,舊的緩衝區現在已經消失。

應用程式要求環形緩衝區時必須指定兩個參數: 《min_frames》和《clock_recovery_notifications_per_ring》。

min_frames

用戶端需要為環形配置的音訊影格數量下限 緩衝區。驅動程式可能會配合硬體需求放大這個緩衝區。 用戶端必須使用傳回的 VMO 大小 (以位元組為單位) 來判斷 環形緩衝區的大小。用戶端不得假設緩衝區大小 (由驅動程式庫決定) 完全符合要求的大小。驅動因素 必須確保環形緩衝區的大小為整數值 相輔相成。

clock_recovery_notifications_per_ring

用戶端希望驅動程式庫接收的位置更新通知 (選用) 數量 每個週期經由環形緩衝區傳送,這些通知僅供時鐘使用 以及災難復原駕駛人只能回覆 WatchClockRecoveryPositionInfo 要求時傳送這些內容。 駕駛應設法在整個環環中等位同位通知;無論如何 不得完全仰賴更新通知的間距。

ring_buffer

如果要求成功,驅動程式庫必須傳回控制代碼, 具備可讓應用程式對應權限的 VMO 透過 zx_vmar_map 將 VMO 新增至位址空間 以及在播放的情況下讀取/寫入緩衝區中的資料,或單純用來讀取 在擷取的情況下,緩衝區中的資料

num_frames

如果要求成功,驅動程式庫也會傳回實際的音訊內容影格數 會在緩衝區中使用傳回的 VMO 大小 (如報告內容所示) zx_vmo_get_size() 的值) 不得大於 所需的影格數 (轉換為位元組時)。這個數字可能較大 而非用戶端的 min_frames 要求,但不得小於這個數字。

啟動及停止環形緩衝區

用戶端可能會使用 StartStop,要求啟動或停止環形緩衝區 指令正在嘗試開始直播 若是已啟動,則視為失敗正在嘗試阻止 已經停止的串流應視為成功。環形緩衝區 除非共用緩衝區已啟動,否則不能停止或啟動 透過 CreateRingBuffer 作業建立。

成功啟動串流後,駕駛必須針對 硬體開始傳輸或擷取串流時 回應的 start_time 欄位。這個時間戳記必須取自時鐘 暴露在 zx_clock_get_monotonic() syscall。以及環形緩衝區的 FIFO 深度屬性,以及這個時間戳記 讓應用程式不需定期存取 取得驅動程式庫的更新位置。並搭配外板延遲時間估算 這項時間戳記可讓應用程式 同步處理多個串流的音訊資訊呈現方式, 多部裝置 (前提是外部時間同步通訊協定為 同步處理的 單調時間軸 同步裝置的同類群組)。

成功啟動串流後,駕駛必須保證沒有人會的位置 系統會在開始回應排入佇列前傳送通知 環形緩衝區管道。

成功停止串流後,駕駛必須保證沒有人會的位置 停止後,通知就會排入環形緩衝區管道 已將回應排入佇列。

位置通知

如果用戶端透過clock_recovery_notifications_per_ring CreateRingBuffer 運算作業時,驅動程式 定期傳送更新給用戶端,告知用戶端目前的正式版 或是緩衝區中消耗的位置此位置以位元組為單位, 傳送至 RingBufferPositionInfo 結構體的 position 欄位 回覆「WatchClockRecoveryPositionInfo」訊息。 訊息也包含包含時間的 timestamp 欄位 (如 zx::time) 這個位元組位置是有效的值。WatchClockRecoveryPositionInfo 只有在要求 clock_recovery_notifications_per_ring 後才能傳送 在 GetVmo 函式中指定的,並傳回 GetVmo 函式。注意: 這些位置 通知會指出驅動程式庫在緩衝區的可用或產生位置 「而不是」名詞播放或擷取位置 (有時稱為 「write 遊標」或「朗讀遊標」)。抵達目的地的時間為 不保證完全一致,不應用來影響時鐘效果 以及災難復原但會參照配對組合 (timestampposition) 數值本身 ARE 的用途是復原音訊時鐘 串流。如果用戶端發現驅動程式庫耗用的時間超過 環狀緩衝區 (其中用戶端寫入播放資料;音訊顯示位置為 未定義。客戶應增加時鐘前置時間,並保持警覺 再提高這個時間點同樣地,擷取 音訊不應嘗試讀取超過環形緩衝區的時間點 會指出驅動程式庫最近傳送的位置通知。

驅動程式播放和擷取位置「一律」必須從環狀緩衝區位元組 0 開始。 立即執行成功的 Start 指令。響起時 緩衝區位置到達 VMO 的結尾 (如 zx_vmo_get_size(...),環形緩衝區位置 符記可能回到零駕駛不需要在 音訊影格的倍數評估串流位置的用戶端 取決於位置通知,請謹慎要求 每個鈴聲的通知數量 (至少 2 個),以快速處理 就不會出現別名的問題

時鐘復原與同步

收到「AUDIO_STREAM_CMD_GET_CLOCK_DOMAIN」訊息後,驅動程式庫必須 以包含該裝置的時鐘網域 ID 回應。如果 音訊裝置已鎖定為本機系統單調時鐘,而且不會公開 微調頻率,則應該傳回值 0 代表本機 CLOCK_MONOTONIC 網域。客戶可能會使用 資訊 (和 AUDIO_RB_POSITION_NOTIFY 訊息以外的資訊),以簡化 取消音訊裝置時鐘的程序。

錯誤通知

意外終止用戶端

如果環形緩衝區控制管道的用戶端因任何原因關閉, 駕駛必須立即關閉控制管道並關閉調整環 緩衝區,這樣系統就不會發送及擷取其他音訊。雖然駕駛人 所鼓勵下去,除了能夠優雅地緩和 就必須確保音訊串流無聲,而非循環播放。一次 靜音模式已完成準備,並提供與播放作業 驅動程式庫可能會釋出並重複使用

如此一來,如果播放用戶端意外終止,系統將關閉 用戶端頻道,讓音訊停止播放,而非繼續循環播放。