在无线音频的世界里,一场静默却深刻的革命正在进行。

它,就是LE Audio。

这不仅仅是一次技术迭代,而是从底层重新定义声音如何被创造、传输和体验的范式转移。其复杂性令人敬畏——它并非单一技术,而是一套精密的生态系统:全新的LC3编解码器以超凡效率重塑音质与功耗的平衡,多重串流音频让真无线立体声达到前所未有的稳定与同步,而音频广播功能则打破了“一对一”连接的百年窠臼,让声音如电台般自由播撒。

然而,正是这种复杂性,构成了我们必须深入学习它的不可辩驳的理由。未来的声音图景将由它绘制:从下一代真无线耳机、无障碍助听设备到公共场所的沉浸式音频导览、多语言广播,乃至元宇宙中清晰无缝的语音交互。不了解LE Audio,将意味着在即将到来的音频浪潮中失去对话的基石。

这不仅仅关乎技术本身,更关乎我们如何连接彼此,如何感知世界。让我们共同开启这段探索之旅,揭开LE Audio的复杂面纱,看清它为何必将成为未来数年里,每一个科技从业者、音频爱好者乃至普通用户都无法忽视的关键命题。

接下来的系列文章,我们将逐步拆解这座精妙的技术大厦。

同时我也录制了一系列的Le audio视频,有兴趣的可以咨询,我会带领你们入门Le audio!翻过大山,眼下皆是风景!!!

------------------------------------------------------------------------------------------------------------------------------------------

视频链接:https://item.taobao.com/item.htm?id=1001969040805&mi_id=000032T4qZX9WZoRwX6YbxlNUaZOfOI6XoxDx0jxsfnwlEc&spm=a21xtw.29178619.0.0

---------------------------------------------------------------------------------------------------------------------------------

本文力争给大家讲明白几个核心点:

  • ASCS config codec的作用是什么?
  • ASCS config codec的流程是什么?

带着这两个疑问我们就开始文本的介绍!

一. Config Codec的作用

LE Audio 核心控制服务 (ASCS) 里的 “Config Codec” 操作,理解起来很简单:它就像音频流正式传输前,客户端(如手机)和服务器(如耳机)之间一次关于“用什么语言(编解码器)交流以及具体怎么说”的标准化握手和准备工作。

简单来说,它的核心作用是:为音频流选择一个双方都支持的编解码器(Codec),并配置好具体的参数,从而确保后续音频数据传输的顺利进行和高质量回放

➡️ Config Codec 操作的三大关键作用

  • 协商并锁定“专业音频语言”:Config Codec像一个专业的翻译配置过程。它会从双方都支持的语言库中,比如 LE Audio 标准中的 LC3(低复杂度通信编解码器),选定一。对于开发者而言,这一过程的核心是向对方设备的一个“音频能力库”对象(ASE)写入所需的 Codec 配置信息。
  • 进行“唇形设计”,优化体验:选定 Codec 后,Config Codec 会敲定具体的性能参数,如采样率和比特率。这种灵活性是实现高音质、低功耗和低延迟的基础,能让游戏、通话体验更佳,耳机续航更长-。
  • 建立统一标准,避免协商死锁:通过 Config Codec,客户端只需从预设的已发布音频能力服务(PACS)能力集中选择服务器明确支持的值,避免了传统蓝牙可能出现的反复协商和配置冲突,确保了设备间的良好兼容性。

🧠 弄清楚这几个基本概念,就更好理解了

  • ASCS (音频流控制服务)与客户端/服务器:ASCS 是 LE Audio 单播传输的“控制中心”,其中手机、电脑等发起连接一端称为单播客户端 (Unicast Client),而耳机、音箱等提供服务的一端称为单播服务器 (Unicast Server)
  • ASE (音频流端点):可以把它理解成服务器(如耳机)上负责管理一个独立音频流的一个“音频能力库”对象。
  • PACS (已发布音频能力服务):可以理解为服务器的“功能说明书”,它详细列出了这个服务器支持的所有音频格式和配置参数。

💁‍♀️ 一个典型的操作流程

下面是一个简化的 Config Codec 操作流程示例:

前置条件:服务器已部署 ASCS 和 PACS 服务。

  1. 发现并读取 PACS 服务(获取 Codec 支持能力)
    单播客户端(手机)发现并读取服务器的 PACS 服务,获取服务器支持的编解码器能力。
  2. 发现并读取 ASCS 服务(获取 ASE 状态信息)
    单播客户端发现并读取 ASCS 服务,获取当前 ASE 的状态信息。
  3. 根据 PACS 信息,决策并准备 Codec 配置
    客户端根据已获取的 PACS 能力信息,选择双方支持的编解码器及参数,并准备好配置内容。
  4. 发起 Config Codec 操作(包含选定的 Codec ID 和配置参数)
    客户端通过 ASE Control Point 发起 Config Codec 操作,将选定的编解码器 ID 和配置参数发送给服务器。
  5. 校验请求的 Codec 和参数是否在 PACS 能力列表内
    服务器收到请求后,校验客户端提交的编解码器和参数是否在其 PACS 公布的能力范围内。
  6. 通知(Notify)操作结果(成功)
    服务器通过 ASE Control Point 返回操作成功的通知。
    ASE 状态从 Idle 变为 Codec Configured
  7. 更新并通知 ASE 的 Codec Configured 状态
    服务器更新 ASE 状态特性,并通过通知将 Codec Configured 状态(包含服务器偏好的 QoS 范围参数)发送给客户端。

结果:Config Codec 成功,可以进入下一阶段(Config QoS)。

二. 流程介绍

1. 状态机管理

我们在这个之前已经介绍过了ASCS的状态机,对应的Source/Sink流转如下:

从这个表格中可以看到在什么时机可以发送Config Codec,并且发起的角色分别是什么,一目了然,下面我们就来介绍下Config Codec的流程

2. 流程介绍

我们在前面已经介绍过流程了,跟下面的基本没有区别,下面的是BAP协议的sample流程示意图:

有了这个流程图,我们就结合btsnoop来说明下每个命令或者通知的格式

a. client发送config codec

格式如下:

字段 (Field)

大小 (Octets)

描述 (Description)

Opcode

1

0x01= Config Codec

Parameters

大小 (Octets)

描述 (Description)

Number_of_ASEs

1

本次 Config Codec 操作涉及的 ASE 总数,须 ≥ 1

ASE_ID[i]

1

该 ASE 的标识符

Target_Latency[i]

1

为目标延迟提供的上下文,供服务器在 Codec Configured 状态返回有意义的 QoS 偏好值。
0x01= 低延迟优先
0x02 = 延迟与可靠性平衡
0x03= 高可靠性优先

Target_PHY[i]

1

为实现 Target_Latency 值而目标的 PHY 参数。
0x01= LE 1M PHY
0x02= LE 2M PHY
0x03= LE Coded PHY

Codec_ID[i]

5

编解码器标识符:
• Octet 0:Coding_Format(数值见蓝牙分配编号文档)
• Octet 1–2:Company_ID(见 [2],若 Octet 0 ≠ 0xFF 则须为 0x0000)
• Octet 3–4:Vendor-specific codec_ID(若 Octet 0 ≠ 0xFF 则须为 0x0000)

Codec_Specific_Configuration_Length[i]

1

该 ASE 的 Codec_Specific_Configuration 值的长度(八位位组数)

Codec_Specific_Configuration[i]

可变 (Varies)

该 ASE 的编解码器特定配置。仅当 Codec_Specific_Configuration_Length[i] ≠ 0x00时才存在。

我们来找个btsnoop来加深理解

操作码(Opcode)
值为 Config Codec(命令码 0x01),表明这是一条“配置编解码器”操作。

ASE 数量(Num ASEs)
值为 1,表示本次只对 1 个音频流端点进行配置。

ASE 编解码配置(ASE Codec Config)

  • ASE ID = 1:被配置的 ASE 标识符为 1。
  • 目标延迟(Target Latency) = Higher:根据规范,Higher 对应 0x03,表示“高可靠性优先”。这是一个建议值,告诉服务器客户端希望尽量保证传输可靠,可以接受较高的延迟。
  • 目标 PHY(Target PHY) = 2M:对应规范值 0x02,即建议使用 LE 2M PHY 来达到上述延迟/可靠性目标。

编解码器(Codec)

  • Coding Format = LC3:规范中 LC3 对应 0x06,这是 LE Audio 的强制编解码器。
  • Company ID = 0x0000:由于使用的是标准 LC3,而非厂商特定编码,因此 Company ID 填 0。
  • Vendor-Specific Codec ID = 0x0000:同样因为非厂商专用,填 0。

编解码器特定信息(Codec Specific Information)
这部分采用 TLV(类型-长度-值)格式,总长度为 19 字节,依次包含以下参数:

  • 采样频率(Sampling Frequency)
    • 长度 = 2 bytes,类型字段指示采样率。
    • 值 = 48000 Hz:表示音频采样率为 48 kHz,属于 LC3 支持的高音质模式。
  • 帧时长(Frame Duration)
    • 长度 = 2 bytes,类型指示帧时长。
    • 值 = 10 ms:每个 LC3 编解码帧的时长为 10 毫秒。较短的帧(如 7.5ms)延迟更低,10ms 是常见的平衡选择。
  • 音频通道分配(Audio Channel Allocation)
    • 长度 = 5 bytes,类型指示声道分配。
    • 值 = FL FR:表示左前声道和右前声道,即标准的立体声配置。
    • (底层掩码通常为 0x0003,表示 front left 和 front right)
  • 每个编解码帧的字节数(Octets Per Codec Frame)
    • 长度 = 3 bytes
    • 值 = 120:每个 LC3 帧的载荷大小为 120 字节。该值通常与采样率、帧时长和目标比特率有关。对于 48kHz / 10ms 帧,120 字节对应大约 192 kbps 的比特率(双声道时需乘以 2)。
  • 每个 SDU 的编解码帧块数(Codec Frame Blocks Per SDU)
    • 长度 = 2 bytes
    • 值 = 1:表示每个 SDU(服务数据单元,即通过 ISO 通道发送的数据包)中包含 1 个编解码帧块。这意味着一个 SDU 就是一个 LC3 帧,没有进行帧打包。

b. 通知(Notify)操作结果(成功)

格式如下:

字段 (Field)

大小 (Octets)

描述 (Description)

Opcode

1

本次响应对应的客户端发起的 ASE 控制操作的操作码(例如 Config Codec 的 Opcode 为 0x01)

Number_of_ASEs

1

服务器提供响应的 ASE 总数。
若 Response_Code 值为 0x01 或 0x02,则此字段应设为 0xFF。

ASE_ID[i]

1

该 ASE 的标识符。
若 Response_Code 值为 0x01 或 0x02,则 ASE_ID 应设为 0x00,且循环索引 i 设为 0(即仅有一个虚拟项)。

Response_Code[i]

1

若服务器成功完成客户端发起的 ASE 控制操作,则设为 0x00;否则设为表 5.1 中定义的错误码。

Reason[i]

1

若服务器成功完成操作,则设为 0x00;否则设为表 5.1 中定义的原因值。
若 Response_Code 值为 0x01 或 0x02,则循环索引 i 设为 0(即无实际 ASE 项)。

c. 更新并通知 ASE 的 Codec Configured 状态

格式如下:

字段 (Field)

大小

描述 (Description)

Framing

1

服务器对无帧结构 ISOAL PDU 的支持情况:
0x00:支持无帧结构 ISOAL PDU
0x01:不支持无帧结构 ISOAL PDU
• 其他值:RFU

Preferred_PHY

1

服务器偏好的 PHY 参数(客户端在 Config QoS 操作中写入),格式为位域:
0b00000001:偏好 LE 1M PHY
0b00000010:偏好 LE 2M PHY
0b00000100:偏好 LE Coded PHY
• 可同时设置多个位(表示偏好其中之一)
• 对于不支持的 PHY,该位不得设为 1
0x00表示无偏好
• 其他位:RFU

Preferred_Retransmission_Number

1

服务器偏好的重传次数(客户端在 Config QoS 中写入)。
• 范围:0x000xFF

• 若值不为 0xFF,服务器应支持所有 ≤ 该值的重传次数。
0xFF= 无所谓(Don't care)

Max_Transport_Latency

2

服务器支持的 最大传输延迟 的最大值(客户端在 Config QoS 中写入)。
• 范围:0x00050x0FA0(单位:ms)
• 其他值:RFU

Presentation_Delay_Min

3

服务器支持的 最小呈现延迟(单位:µs)

Presentation_Delay_Max

3

服务器支持的 最大呈现延迟(单位:µs)

Preferred_Presentation_Delay_Min

3

服务器偏好的 最小呈现延迟(单位:µs)。服务器可用此字段及 Preferred_Presentation_Delay_Max

表示其更偏好工作的较窄延迟范围。
• 若非零,则须 ≥ Presentation_Delay_Min

0x000000 表示无偏好

Preferred_Presentation_Delay_Max

3

服务器偏好的 最大呈现延迟(单位:µs)。服务器可用此字段及 Preferred_Presentation_Delay_Min

表示其更偏好工作的较窄延迟范围。
• 若非零,则须 ≤ Presentation_Delay_Max
0x000000 表示无偏好

Codec_ID

5

编解码器标识符:
• Octet 0:Coding_Format(见蓝牙分配编号 [2])
• Octet 1–2:Company_ID(见 [2];若 Octet 0 ≠ 0xFF 则须为 0x0000)
• Octet 3–4:Vendor-specific codec_ID(若 Octet 0 ≠ 0xFF 则须为 0x0000)

Codec_Specific_Configuration_Length

1

该 ASE 的 Codec_Specific_Configuration字段的长度(八位位组数)

Codec_Specific_Configuration

可变

该 ASE 的编解码器特定配置。仅当 Codec_Specific_Configuration_Length ≠ 0x00 时才存在。

ASE 标识与状态

  • ASE ID1 —— 该 ASE 的编号为 1。
  • ASE StateCodec Configured —— 当前 ASE 已成功完成编解码器配置,处于“编解码器已配置”状态,等待后续 Config QoS 操作。

Framing(帧结构支持)

  • 取值Unframed ISOAL PDUs supported
  • 对应规范0x00 表示服务器支持无帧结构的 ISOAL PDU。
  • 含义:在后续的 ISO 数据通道中,可以直接发送不带额外帧封装的应用数据,简化了打包处理。

Preferred_PHY(偏好物理层)

  • 取值
    • 1M:No
    • 2M:Yes
    • Coded:No
  • 对应位域:二进制 0b00000010,即只偏好 LE 2M PHY。
  • 含义:服务器希望客户端在后续 Config QoS 操作中优先选择 LE 2M PHY,因为它能提供更高的空中数据速率,降低传输延迟。

Preferred_Retransmission_Number(偏好重传次数)

  • 取值2
  • 规范范围0x000xFF,非 0xFF 表示有明确偏好。
  • 含义:服务器建议客户端在配置 QoS 时,将重传次数设为 2。同时,服务器也保证支持所有 ≤2 的重传次数(即 0,1,2)。

Max_Transport_Latency(最大传输延迟)

  • 取值10 ms
  • 规范范围0x00050x0FA0(5 ms ~ 4000 ms)。
  • 含义:服务器所支持的最大传输延迟上限为 10 ms。客户端在配置 QoS 时写入的 Max_Transport_Latency 不得超过此值。

Presentation Delay 相关参数

  • Presentation_Delay_Min20 ms
    服务器支持的最小呈现延迟为 20 ms。
  • Presentation_Delay_Max40 ms
    服务器支持的最大呈现延迟为 40 ms。
  • Preferred_Presentation_Delay_Min20 ms
    服务器偏好的最小呈现延迟为 20 ms。
  • Preferred_Presentation_Delay_Max40 ms
    服务器偏好的最大呈现延迟为 40 ms。

分析:服务器将偏好范围直接设为它所支持的整个范围 [20 ms, 40 ms],表示它没有任何更窄的偏好区间,希望客户端在这个范围内任意选择(通常客户端会选择一个具体的延迟值,例如 30 ms)。


Codec 相关配置(服务器确认/暴露的编解码器参数)

  • Coding FormatLC3 —— 确认使用 LC3 编解码器。
  • 采样频率48000 Hz —— 采用 48 kHz 采样率。
  • 帧时长10 ms —— 每个 LC3 帧时长 10 ms。
  • 音频通道分配FL FR —— 立体声(左前+右前)。
  • 每个编解码帧的字节数120 —— 每帧 120 字节,对应双声道时总比特率约为 192 kbps(120 × 8 / 0.01 = 96 kbps 单声道,立体声 ×2)。
  • 每个 SDU 的编解码帧块数1 —— 每个 SDU 携带一个 LC3 帧。

注意:这些参数与客户端之前 Config Codec 请求中的参数完全一致(客户端也请求了 48kHz / 10ms / 立体声 / 120 字节 / 1 块)。服务器没有进行任何调整,直接采纳了客户端的建议。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐