本文件說明音訊驅動程式公開的音訊串流介面 。方便您同時參考其他使用者 以及明確定義驅動程式的介面合約 而且使用者必須確實遵守
總覽
音訊串流是指驅動程式庫服務發布的裝置節點,用於這類節點 以便擷取或算繪音訊至 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.fidl 和 ring_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 個音訊影格的播放時間
外部延遲時間會回報至 DelayInfo
的 external_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_time
從 Start
指令傳回的傳回資訊。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_db
。
gain_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_bytes
:
ring_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
要求,但不得小於這個數字。
啟動及停止環形緩衝區
用戶端可能會使用 Start
和 Stop
,要求啟動或停止環形緩衝區
指令正在嘗試開始直播
若是已啟動,則視為失敗正在嘗試阻止
已經停止的串流應視為成功。環形緩衝區
除非共用緩衝區已啟動,否則不能停止或啟動
透過 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 遊標」或「朗讀遊標」)。抵達目的地的時間為
不保證完全一致,不應用來影響時鐘效果
以及災難復原但會參照配對組合 (timestamp
、position
)
數值本身 ARE 的用途是復原音訊時鐘
串流。如果用戶端發現驅動程式庫耗用的時間超過
環狀緩衝區 (其中用戶端寫入播放資料;音訊顯示位置為
未定義。客戶應增加時鐘前置時間,並保持警覺
再提高這個時間點同樣地,擷取
音訊不應嘗試讀取超過環形緩衝區的時間點
會指出驅動程式庫最近傳送的位置通知。
驅動程式播放和擷取位置「一律」必須從環狀緩衝區位元組 0 開始。
立即執行成功的 Start
指令。響起時
緩衝區位置到達 VMO 的結尾 (如
zx_vmo_get_size(...),環形緩衝區位置
符記可能回到零駕駛不需要在
音訊影格的倍數評估串流位置的用戶端
取決於位置通知,請謹慎要求
每個鈴聲的通知數量 (至少 2 個),以快速處理
就不會出現別名的問題
時鐘復原與同步
收到「AUDIO_STREAM_CMD_GET_CLOCK_DOMAIN
」訊息後,驅動程式庫必須
以包含該裝置的時鐘網域 ID 回應。如果
音訊裝置已鎖定為本機系統單調時鐘,而且不會公開
微調頻率,則應該傳回值
0 代表本機 CLOCK_MONOTONIC 網域。客戶可能會使用
資訊 (和 AUDIO_RB_POSITION_NOTIFY
訊息以外的資訊),以簡化
取消音訊裝置時鐘的程序。
錯誤通知
意外終止用戶端
如果環形緩衝區控制管道的用戶端因任何原因關閉, 駕駛必須立即關閉控制管道並關閉調整環 緩衝區,這樣系統就不會發送及擷取其他音訊。雖然駕駛人 所鼓勵下去,除了能夠優雅地緩和 就必須確保音訊串流無聲,而非循環播放。一次 靜音模式已完成準備,並提供與播放作業 驅動程式庫可能會釋出並重複使用
如此一來,如果播放用戶端意外終止,系統將關閉 用戶端頻道,讓音訊停止播放,而非繼續循環播放。