本文回顧了 Android 對 USB 數字音頻和相關基於 USB 的協議的支持。
觀眾
本文的目標受眾是 Android 設備 OEM、SoC 供應商、USB 音頻外設供應商、高級音頻應用程序開發人員以及其他尋求詳細了解 Android 上的 USB 數字音頻內部結構的人員。
Nexus 設備的最終用戶應該在Nexus 幫助中心查看文章使用 USB 主機模式錄製和播放音頻。儘管本文並非面向最終用戶,但某些發燒友可能會發現感興趣的部分。
USB 概述
通用串行總線 (USB) 在 Wikipedia 文章USB中進行了非正式描述,並由USB Implementers Forum, Inc發布的標準正式定義。為方便起見,我們在這裡總結了關鍵的 USB 概念,但標準是權威參考。
基本概念和術語
USB 是具有單個數據傳輸操作發起者的總線,稱為主機。主機通過總線與外圍設備通信。
注意:術語設備和附件是外圍設備的常見同義詞。我們在這裡避免使用這些術語,因為它們可能會與 Android設備或稱為配件模式的 Android 特定概念混淆。
一個關鍵的主機角色是枚舉:檢測哪些外圍設備連接到總線,並查詢它們通過描述符表達的屬性的過程。
外圍設備可能是一個物理對象,但實際上實現了多個邏輯功能。例如,網絡攝像頭外圍設備可以同時具有攝像頭功能和麥克風音頻功能。
每個外圍功能都有一個接口,該接口定義了與該功能通信的協議。
主機通過管道與外圍設備通信,該管道通向端點、由外圍設備的功能之一提供的數據源或接收器。
有兩種管道:消息和流。消息管道用於雙向控制和狀態。流管道用於單向數據傳輸。
主機啟動所有數據傳輸,因此術語輸入和輸出是相對於主機表示的。輸入操作將數據從外設傳輸到主機,而輸出操作將數據從主機傳輸到外設。
有三種主要的數據傳輸模式:中斷、批量和等時。同步模式將在音頻的上下文中進一步討論。
外圍設備可能具有連接到外部世界的終端,而不是外圍設備本身。通過這種方式,外設用於在 USB 協議和“現實世界”信號之間進行轉換。接線端是函數的邏輯對象。
安卓 USB 模式
發展模式
自 Android 最初發布以來,開發模式一直存在。 Android 設備顯示為運行 Linux、Mac OS X 或 Windows 等桌面操作系統的主機 PC 的 USB 外圍設備。唯一可見的外圍功能是Android fastboot或Android Debug Bridge (adb) 。 fastboot 和 adb 協議在 USB 批量數據傳輸模式上分層。
主機模式
主機模式在 Android 3.1(API 級別 12)中引入。
由於 Android 設備必須充當主機,並且大多數 Android 設備都包含一個不能直接允許主機操作的微型 USB 連接器,因此通常需要像這樣的移動 ( OTG ) 適配器:
![OTG](https://source.android.google.cn/static/devices/audio/images/otg.jpg?authuser=0000&hl=zh-tw)
圖 1. On-the-go (OTG) 適配器
Android 設備可能無法提供足夠的電力來運行特定的外圍設備,具體取決於外圍設備需要多少電力,以及 Android 設備能夠提供多少電力。即使有足夠的電量,Android 設備的電池電量也可能會顯著縮短。對於這些情況,請使用有源集線器,例如:
![動力集線器](https://source.android.google.cn/static/devices/audio/images/hub.jpg?authuser=0000&hl=zh-tw)
圖 2.有源集線器
配件模式
附件模式在 Android 3.1(API 級別 12)中引入,並向後移植到 Android 2.3.4。在這種模式下,Android 設備作為 USB 外圍設備運行,受另一個設備(例如用作主機的擴展塢)的控制。開發模式和附件模式的區別在於,除了 adb 之外,主機可以看到額外的 USB 功能。 Android 設備從開發模式開始,然後通過重新協商過程轉換到附件模式。
附件模式在 Android 4.1 中通過附加功能進行了擴展,特別是下面描述的音頻。
USB 音頻
USB 類
每個外圍功能都有一個關聯的設備類文檔,該文檔指定該功能的標準協議。這使得符合類的主機和外圍功能可以互操作,而無需詳細了解彼此的工作原理。如果主機和外圍設備由不同的實體提供,則類合規性至關重要。
術語driverless是class compliant的常見同義詞,表示可以使用此類外圍設備的標準功能,而無需安裝操作系統特定的驅動程序。人們可以假設,被宣傳為主要桌面操作系統“無需驅動程序”的外圍設備將是類兼容的,儘管可能有例外。
USB音頻類
在這裡,我們只關心實現音頻功能的外圍設備,因此遵守音頻設備類。 USB 音頻類規範有兩個版本:1 類 (UAC1) 和 2 類 (UAC2)。
與其他類別的比較
USB 包括許多其他設備類,其中一些可能與音頻類混淆。大容量存儲類(MSC) 用於面向扇區的媒體訪問,而媒體傳輸協議(MTP) 用於對媒體的完整文件訪問。 MSC 和 MTP 都可以用於傳輸音頻文件,但只有 USB 音頻類適用於實時流傳輸。
音頻終端
音頻外圍設備的端子通常是模擬的。在外設輸入端呈現的模擬信號由模數轉換器(ADC) 轉換為數字信號,並通過 USB 協議傳輸給主機使用。 ADC 是主機的數據源。同樣,主機通過 USB 協議向外圍設備發送數字音頻信號,其中數模轉換器(DAC) 進行轉換並呈現給模擬輸出終端。 DAC 是主機的接收器。
頻道
具有音頻功能的外圍設備可以包括源終端、宿終端或兩者。每個方向可能有一個通道(單聲道)、兩個通道(立體聲)或更多。具有兩個以上通道的外設稱為多通道。通常將立體聲流解釋為由左聲道和右聲道組成,並且通過擴展將多聲道流解釋為具有對應於每個聲道的空間位置。但是,不為每個通道分配任何特定的標準空間含義也是非常合適的(尤其是對於 USB 音頻,而不是HDMI )。在這種情況下,由應用程序和用戶定義如何使用每個通道。例如,四通道 USB 輸入流可能將前三個通道連接到房間內的各種麥克風,最後一個通道接收來自 AM 收音機的輸入。
同步傳輸模式
USB 音頻因其實時特性而使用等時傳輸模式,但代價是錯誤恢復。在同步模式下,帶寬得到保證,並且使用循環冗餘校驗 (CRC) 檢測數據傳輸錯誤。但是在發生錯誤時沒有數據包確認或重新傳輸。
同步傳輸發生在每個幀開始 (SOF) 週期。 SOF 週期對於全速是 1 毫秒,對於高速是 125 微秒。每個全速幀最多承載 1023 字節的有效載荷,一個高速幀最多承載 1024 字節。將這些放在一起,我們計算出最大傳輸速率為每秒 1,023,000 或 8,192,000 字節。這設置了組合音頻採樣率、通道數和位深度的理論上限。實際限制更低。
在等時模式下,有三種子模式:
- 自適應
- 異步
- 同步
在自適應子模式中,外圍接收器或源適應主機可能變化的採樣率。
在異步(也稱為隱式反饋)子模式中,接收器或源確定採樣率,主機適應。異步子模式的主要理論優勢是源或接收 USB 時鐘在物理和電氣上更接近(實際上可能與驅動 DAC 或 ADC 的時鐘相同或源自)。這種接近意味著異步子模式應該不易受時鐘抖動的影響。此外,DAC 或 ADC 使用的時鐘可以設計為比主機時鐘具有更高的精度和更低的漂移。
在同步子模式下,每個 SOF 週期傳輸固定數量的字節。音頻採樣率有效地來自 USB 時鐘。同步子模式不常用於音頻,因為主機和外圍設備都受 USB 時鐘的支配。
下表總結了同步子模式:
子模式 | 字節數 每包 | 採樣率 取決於 | 用於音頻 |
---|---|---|---|
自適應 | 多變的 | 主持人 | 是的 |
異步 | 多變的 | 外圍設備 | 是的 |
同步 | 固定的 | USB時鐘 | 不 |
在實踐中,子模式當然很重要,但也應考慮其他因素。
Android 對 USB 音頻類的支持
發展模式
開發模式不支持 USB 音頻。
主機模式
Android 5.0(API 級別 21)及更高版本支持 USB 音頻 1 類 (UAC1) 功能的子集:
- Android 設備必須充當主機
- 音頻格式必須為 PCM(接口類型 I)
- 位深度必須是 16 位、24 位或 32 位,其中 24 位有用的音頻數據在 32 位字的最高有效位內左對齊
- 採樣率必須為 48、44.1、32、24、22.05、16、12、11.025 或 8 kHz
- 通道數必須為 1(單聲道)或 2(立體聲)
仔細閱讀 Android 框架源代碼可能會顯示超出支持這些功能所需的最低限度的其他代碼。但此代碼尚未經過驗證,因此尚未聲明更高級的功能。
配件模式
Android 4.1(API 級別 16)向主機添加了對音頻播放的有限支持。在附件模式下,Android 會自動將其音頻輸出路由到 USB。也就是說,Android 設備充當主機的數據源,例如擴展塢。
附件模式音頻具有以下功能:
- Android 設備必須由知識淵博的主機控制,該主機可以首先將 Android 設備從開發模式轉換為附件模式,然後主機必須從適當的端點傳輸音頻數據。因此,Android 設備不會對主機顯得“無驅動”。
- 必須輸入方向,相對於主機表示
- 音頻格式必須是 16 位 PCM
- 採樣率必須為 44.1 kHz
- 通道數必須為 2(立體聲)
附件模式音頻尚未被廣泛採用,目前不推薦用於新設計。
USB數字音頻的應用
顧名思義,USB 數字音頻信號是由數字數據流來表示的,而不是常見的 TRS 迷你耳機連接器使用的模擬信號。最終,任何數字信號都必須轉換為模擬信號才能被聽到。在選擇放置轉換的位置時需要權衡取捨。
兩個 DAC 的故事
在下面的示例圖中,我們比較了兩種設計。首先,我們有一個帶有應用處理器 (AP)、板載 DAC、放大器和連接到耳機的模擬 TRS 連接器的移動設備。我們還考慮使用 USB 連接到外部 USB DAC 和放大器的移動設備,以及耳機。
![DAC比較](https://source.android.google.cn/static/devices/audio/images/dac.png?authuser=0000&hl=zh-tw)
圖 3.兩個 DAC 的比較
哪個設計更好?答案取決於您的需求。每個都有優點和缺點。
注意:這是人為的比較,因為真正的 Android 設備可能會同時提供這兩個選項。
第一個設計 A 更簡單,更便宜,使用更少的功率,並且將是一個更可靠的設計,假設其他方面同樣可靠的組件。但是,與其他要求相比,通常需要權衡音頻質量。例如,如果這是一款大眾市場設備,它的設計可能是為了滿足普通消費者的需求,而不是為發燒友而設計。
在第二種設計中,外部音頻外設 C 可以設計為更高的音頻質量和更大的功率輸出,而不會影響基本大眾市場 Android 設備 B 的成本。是的,這是一個更昂貴的設計,但成本僅由那些想要它的人。
移動設備因擁有高密度電路板而臭名昭著,這可能會導致更多的串擾機會,從而降低相鄰模擬信號的質量。數字通信不易受噪聲影響,因此將 DAC 從 Android 設備 A 移至外部電路板 C 可以使最終的模擬級與密集且嘈雜的電路板進行物理和電氣隔離,從而獲得更高保真度的音頻。
另一方面,第二種設計更複雜,隨著複雜性的增加,失敗的機會也更多。 USB 控制器還有額外的延遲。
主機模式應用程序
典型的 USB 主機模式音頻應用包括:
- 聽音樂
- 電話
- 即時消息和語音聊天
- 記錄
對於所有這些應用程序,Android 會檢測兼容的 USB 數字音頻外圍設備,並根據音頻策略規則自動適當地路由音頻播放和捕獲。立體聲內容在外圍設備的前兩個通道上播放。
沒有特定於 USB 數字音頻的 API。對於高級用途,自動路由可能會干擾支持 USB 的應用程序。對於此類應用程序,請通過Settings / Developer Options的 Media 部分中的相應控件禁用自動路由。
在主機模式下調試
在 USB 主機模式下,通過 USB 進行 adb 調試不可用。有關替代方法,請參閱Android Debug Bridge的無線使用部分。
實現 USB 音頻
對音頻外設供應商的建議
為了與 Android 設備互操作,音頻外設供應商應該:
- 音頻類合規性設計;目前 Android 以 1 類為目標,但為 2 類做計劃是明智的
- 避免怪癖
- 測試與參考和流行 Android 設備的互操作性
- 清楚地記錄支持的功能、音頻等級合規性、電源要求等,以便消費者做出明智的決定
針對 Android 設備 OEM 和 SoC 供應商的建議
為了支持 USB 數字音頻,設備 OEM 和 SoC 供應商應該:
- 設計硬件以支持 USB 主機模式
- 通過
android.hardware.usb.host.xml
功能標誌在框架級別啟用通用 USB 主機支持 - 啟用所需的所有內核功能:USB 主機模式、USB 音頻、同步傳輸模式;請參閱Android 內核配置
- 與最新的內核版本和補丁保持同步;儘管類合規性是崇高的目標,但現存的音頻外圍設備具有怪癖,並且最近的內核具有針對此類怪癖的解決方法
- 啟用 USB 音頻策略,如下所述
- 將 audio.usb.default 添加到 device.mk 中的 PRODUCT_PACKAGES
- 測試與常見 USB 音頻外設的互操作性
如何啟用 USB 音頻策略
要啟用 USB 音頻,請在音頻策略配置文件中添加一個條目。這通常位於此處:
device/oem/codename/audio_policy.conf
路徑名組件“oem”應替換為製造Android設備的OEM名稱,“代號”應替換為設備代號。
此處顯示了一個示例條目:
audio_hw_modules { ... usb { outputs { usb_accessory { sampling_rates 44100 channel_masks AUDIO_CHANNEL_OUT_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_USB_ACCESSORY } usb_device { sampling_rates dynamic channel_masks dynamic formats dynamic devices AUDIO_DEVICE_OUT_USB_DEVICE } } inputs { usb_device { sampling_rates dynamic channel_masks AUDIO_CHANNEL_IN_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_IN_USB_DEVICE } } } ... }
源代碼
USB 音頻的音頻硬件抽象層 (HAL) 實現位於此處:
hardware/libhardware/modules/usbaudio/
USB 音頻 HAL 嚴重依賴tinyalsa ,音頻術語中對此進行了描述。儘管 USB 音頻依賴於同步傳輸,但 ALSA 實現將其抽象化了。所以 USB 音頻 HAL 和 tinyalsa 不需要關心這部分 USB 協議。
測試 USB 音頻
有關 USB 音頻 CTS 測試的信息,請參閱USB 音頻 CTS 驗證程序測試。