本文回顾了 Android 对 USB 数字音频和相关的基于 USB 的协议的支持。
观众
本文的目标读者是 Android 设备 OEM、SoC 供应商、USB 音频外设供应商、高级音频应用程序开发人员,以及其他寻求详细了解 Android 上 USB 数字音频内部结构的人员。
Nexus 设备的最终用户应该在Nexus 帮助中心看到文章使用 USB 主机模式录制和播放音频。尽管本文不面向最终用户,但某些发烧友消费者可能会发现感兴趣的部分。
USB概述
通用串行总线 (USB) 在维基百科文章USB中进行了非正式描述,并由USB Implementers Forum, Inc发布的标准正式定义。为方便起见,我们在这里总结了关键的 USB 概念,但标准才是权威参考。
基本概念和术语
USB 是一种总线,具有单一的数据传输操作发起者,称为主机。主机通过总线与外设通信。
注意:术语设备和附件是外围设备的常见同义词。我们在这里避免使用这些术语,因为它们可能会与 Android设备或称为附件模式的 Android 特定概念混淆。
一个关键的主机角色是枚举:检测哪些外围设备连接到总线,并查询它们通过描述符表达的属性的过程。
一个外设可能是一个物理对象,但实际上实现了多种逻辑功能。例如,网络摄像头外围设备可以同时具有摄像头功能和麦克风音频功能。
每个外设功能都有一个接口,该接口定义了与该功能通信的协议。
主机通过管道与外围设备通信到端点,数据源或外围设备功能之一提供的接收器。
有两种管道:消息和流。消息管道用于双向控制和状态。流管道用于单向数据传输。
主机启动所有数据传输,因此术语输入和输出是相对于主机表示的。输入操作将数据从外设传输到主机,而输出操作将数据从主机传输到外设。
主要有三种数据传输模式:中断、批量和等时。同步模式将在音频上下文中进一步讨论。
外围设备可能具有连接到外部世界的终端,超出外围设备本身。通过这种方式,外围设备可以在 USB 协议和“现实世界”信号之间进行转换。终端是功能的逻辑对象。
Android USB 模式
发展模式
自 Android 最初发布以来,开发模式就已经存在。对于运行 Linux、Mac OS X 或 Windows 等桌面操作系统的主机 PC,Android 设备显示为 USB 外围设备。唯一可见的外围功能是Android fastboot或Android Debug Bridge (adb) 。 fastboot 和 adb 协议在 USB 批量数据传输模式上分层。
主机模式
主机模式是在 Android 3.1(API 级别 12)中引入的。
由于 Android 设备必须充当主机,并且大多数 Android 设备都包含一个微型 USB 连接器,该连接器不直接允许主机操作,因此通常需要一个移动 ( OTG ) 适配器,例如:

图 1.移动 (OTG) 适配器
Android 设备可能无法提供足够的电力来运行特定的外围设备,具体取决于外围设备需要多少电力,以及 Android 设备能够提供多少电力。即使有足够的电量,Android 设备的电池充电时间也可能会大大缩短。对于这些情况,请使用像这样的有源集线器:

图 2.动力集线器
饰品模式
配件模式在 Android 3.1(API 级别 12)中引入,并向后移植到 Android 2.3.4。在这种模式下,Android 设备作为 USB 外围设备运行,在另一个设备(例如用作主机的扩展坞)的控制下。开发模式和附件模式的区别在于,除了 adb 之外,主机还可以看到额外的 USB 功能。 Android 设备从开发模式开始,然后通过重新协商过程转换到配件模式。
附件模式在 Android 4.1 中扩展了附加功能,特别是下面描述的音频。
USB音频
USB类
每个外围功能都有一个关联的设备类文档,该文档指定该功能的标准协议。这使得类兼容主机和外围功能能够互操作,而无需详细了解彼此的工作原理。如果主机和外围设备由不同的实体提供,则类别合规性至关重要。
术语无驱动是类兼容的常见同义词,表示可以使用此类外围设备的标准功能,而无需安装特定于操作系统的驱动程序。人们可以假设,对于主要台式机操作系统来说,标榜为“无需驱动程序”的外围设备将符合类标准,尽管可能会有例外。
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 和放大器的移动设备,也带有耳机。

图 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 调试桥的无线使用部分。
实现 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 的名称,“codename”应替换为设备代号。
此处显示了一个示例条目:
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 验证程序测试。