windows蓝牙驱动开发-BLE音频(三)

embedded/2025/1/19 14:36:52/

序列

音频驱动程序初始化

当 IHV ACX 流式处理驱动程序加载并确定它支持蓝牙 LE 音频流式处理时,它应通过以下方法来显示对该技术的支持:创建 ACXFACTORYCIRCUIT 对象,并使用音频终结点模板绑定 ID 中定义的 ID 向 ACX 注册蓝牙模板绑定。

415e3ce63c9b493dbd35c9fc8bbd4d6c.png

终结点创建

1. 当 LE 音频设备与系统配对时,蓝牙 LE 音频配置文件会:

 

  • 读取远程设备的已发布音频功能。
  • 通过发送 HCI_Read_Local_Support_Codecs [v2] 和 HCI_Read_Local_Supported_Codec_Capabilities 命令来发现控制器支持的功能。
  • 使用基于蓝牙控制器和远程音频设备支持的编解码器功能设置的受支持格式创建 ACXCIRCUIT。 如果控制器不支持任何编解码器(因为编解码器支持位于音频 DSP 或音频驱动程序中),则受支持的格式将设置为远程音频设备所支持的格式。

2. 创建 ACXCIRCUIT 后,ACX 会请求 IHV ACX ACX 流式处理驱动程序的 ACX 线路工厂创建 ACXCIRCUIT 进行流处理。


3. 收到创建线路的请求时,IHV ACX 流式处理驱动程序会:

 

  • 创建 ACXCIRCUIT、ACXPIN、ACXOBJECTBAG 和 ACXSTREAMBRIDGE 对象。
  • 如果 LC3 或供应商专用编解码器托管在音频驱动程序或 DSP 中,则 IHV ACX 流式处理驱动程序会在 ACXOBJECTBAG 上设置 BluetoothLEAudio_CodecCapabilities 属性。
  • IHV ACX ACX 流式处理驱动程序可能会在 ACXOBJECTBAG 上设置 Bluetooth_DatapathID 或 Bluetooth_DatapathConfiguration(如果目前已知)。

4. 创建两条线路后,ACX 将在 IHV ACX 驱动程序的桥接引脚上调用 EvtAcxPinConnected 回调;
5. 调用 EvtAcxPinConnected 时,IHV ACX 流式处理驱动程序会:

 

  • 使用 AcxTarget... API 检索配置文件线路的桥接引脚,以检索该线路支持的格式。
  • 循环访问配置文件线路设置的 ACXDATAFORMAT 列表。 如果蓝牙音频编解码器托管在音频驱动程序或音频 DSP 中,则 IHV 音频驱动程序会使用编解码器和配置文件线路支持的格式更新其 ACXDATAFORMAT。 否则,所有格式都将复制到 IHV ACX ACX 流式处理驱动程序的主机引脚。
  • 如果为卸载流式处理创建了音频引擎,则在桥接引脚上设置更新后的格式列表。

6. 更新这些格式后,ACX 会启用这两个接口,并创建音频终结点。

 6f72b41d0ebc49e2a469ce41308cbf9a.png

流创建

1. 当应用程序请求创建音频流时,ACX 会为每个线路调用已注册的 EvtCircuitCreateStream 回调,从 IHV ACX 流式处理驱动程序开始。

2. 调用 EvtCircuitCreateStream 回调时,IHV ACX 流式处理驱动程序会:

 

  • 设置或更新 ACXOBJECTBAG 上附加到 ACXSTREAMBRIDGE 的 Bluetooth_DatapathId 和 Bluetooth_DataPathConfiguration 属性。
  • 创建一个 ACXSTREAM,其中包含为流状态转换和 RT 流处理设置的回调
  • 如果音频管道支持卸载流,请在流中创建音频引擎元素。
  • 将 ACXSTREAM 添加到其流桥。 这会调用蓝牙 LE 音频配置文件的 EvtCircuitCreateStream 回调。

3. 调用 EvtAcxCircuitCreateStream 回调时,蓝牙 LE 音频配置文件会:

 

  • 从 IHV ACX ACX 流式处理驱动程序设置的 ACXOBJECTBAG 本地保存属性,以用于将来的流转换回调。
  • 如果音频终结点用于单播流式传输蓝牙 LE 音频配置文件:
  • 执行 BAP 规范中定义的配置编解码器操作。 该操作的参数派生自 EvtAcxCircuitCreateStream 回调中指定的 ACXDATAFORMAT,以及 ACXOBJECTBAG 中的其他流参数或蓝牙控制器支持的编解码器功能。
  • 使用用于配置远程音频设备的值设置 ACXOBJECTBAG 上的 BluetoothLEAudio_CodecConfiguration 属性。

4. 如果 IHV ACX 流式处理驱动程序需要根据配置文件设置的对象包值更新其数据路径 ID 或数据路径配置,则它可以调用 KSPROPERTY 集操作来更新配置文件线路所存储的值。
创建一个 ACXSTREAM,其中包含为流状态转换设置的回调。

6b494bf294184e968457a2e9d4360ed2.png

流状态转换

ACX 根据音频流决定流状态转换的线路顺序,以及状态是转换为更活跃还是不太活跃的状态。

  • 对于从不太活跃的状态转换为更活跃的状态的呈现流,配置文件线路首先接收事件,然后是流式传输线路。
  • 对于从更活跃的状态转换为不太活跃的状态的呈现流,流式传输线路首先接收事件,然后是配置文件线路。 
  • 对于从不太活跃的状态转换为更活跃的状态的捕获流,流式传输线路首先接收事件,然后是配置文件线路。 
  • 对于从更活跃的状态转换为不太活跃的状态的捕获流,配置文件线路首先接收事件,然后是流式传输线路。

准备流

调用 EvtAcxStreamPrepareHardware 回调时,蓝牙 LE 音频配置文件会:

1. 通过以下方式为单播流分配资源:

  • 使用 HCI_LE_Set_CIG_Parameters 命令配置 CIG。
  • 发送 ASCS 配置 QoS 操作以将设置与远程设备同步。

424e280e56a640ebba6b7dfe8f3312fe.png

调用 EvtAcxStreamPrepareHardware 回调时,IHV ACX 流式处理驱动程序会分配必要的流式处理资源,并初始化要处于获取状态的音频管道。

20abc7c4ba13485f95c31f6382375609.png

启动流

调用 EvtAcxStreamRun 回调时,蓝牙 LE 音频配置文件会:

1. 使用 HCI_Configure_Data_Path 命令在流创建过程中应用 ACX 流式处理驱动程序设置的所有数据路径配置设置。
2. 通过以下方式开始流启动过程:
执行单播流的 BAP 单播流启用过程:
将“启用”操作发送到远程终结点。
如果尚未使用 HCI_LE_Create_CIS 命令创建 CIS,则创建 CIS。
3. 如果尚未配置数据路径,蓝牙 LE 音频配置文件会:
使用 HCI_LE_Setup_ISO_Data_Path 命令建立 ISO 数据路径
如果 IHV ACX 流式处理驱动程序设置 BluetoothLEAudio_CodecCapabilities 属性,则 HCI_LE_Setup_ISO_Data_Path 中 Codec_ID 字段的值应设置为透明 (0x3),如蓝牙分配号码中定义。 否则,该值应与流创建过程中配置编解码器操作中使用的编解码器 ID 相同。
4. 如果音频流是单播捕获流,则蓝牙 LE 音频配置文件会执行 BAP 接收器启动就绪操作。

db84ca3932204e65905b6bce83264300.png

调用 EvtAcxStreamRun 回调时,IHV ACX 流式处理驱动程序将开始处理来自 Windows 音频系统(呈现)或蓝牙控制器(捕获)的传入音频数据。

eebff44054cc4b1cb7f8455079cf0248.png

暂停流

调用 EvtAcxStreamPause 回调时,蓝牙 LE 音频配置文件会:

  • 执行 BAP 单播流禁用过程。
  • 使用 HCI_LE_Remove_ISO_Data_Path 命令移除 ISO 数据路径。
  • 如果音频流是单播捕获流,则执行 ASCS 接收器停止就绪过程。

f52beea77abe47ba9d5e07d7256832d5.png

调用 EvtAcxStreamPause 回调时,IHV ACX 流式处理驱动程序会暂停其音频处理管道。

9409b5ae01bc4ae1b9f4a63468c40ab1.png

发布流

调用 EvtAcxStreamReleaseHardware 回调时,蓝牙 LE 音频配置文件会通过以下方式执行 BAP 单播流发布过程:

  • 将 ASCS 发布操作发送到远程蓝牙 LE 音频设备
  • 如果 CIS 未由另一个活动流使用,则断开 CIS 的连接。
  • 如果所有 CIS 均已断开连接,则移除 CIG。

b8d56e58a8254712be4448c00346a243.png

调用 EvtAcxStreamReleaseHardware 回调时,IHV ACX ACX 流式处理驱动程序会释放其音频管道资源 

0a4e32f2df5a420ab69c085e363b9dbc.png

终结点断开连接

在以下情况下,Windows 蓝牙 LE Audio 配置文件会更新终结点的连接状态:远程单播设备没有与电脑的 LE-ACL 连接,或者它正在通过其 PACS 可用的音频上下文报告它无法进行流式处理。 当终结点断开连接时,Windows 音频服务会使终结点的所有活动流失效。 这会导致流暂停和释放序列。

终结点移除

当配置文件线路或流式传输线路被销毁时,将从系统中移除蓝牙 LE 音频终结点。 从 Windows 中移除远程单播设备的配对或禁用蓝牙无线电时,可能会移除配置文件线路。

  • 当 Windows 蓝牙 LE 音频配置文件移除其线路时,ACX 会禁用其终结点接口,以向 Windows 音频服务发出指示应移除该终结点的信号。
  • 禁用这些接口后,Windows 音频服务会使蓝牙 LE 音频终结点的所有活动流失效,此操作会导致在流式传输线路上调用流暂停和释放回调。
  • 若要完成终结点移除,ACX 会使 IHV ACX 流式处理驱动程序的线路失效,这会导致 WDF 调用线路的清理回调。
  • 调用清理回调时,IHV ACX 流式处理驱动程序会释放其线路。

5735d3211af64cdcbface62caae7a4e6.png

 


http://www.ppmy.cn/embedded/155240.html

相关文章

python爬取Boss直聘,分析北京招聘市场

一、引言 在当前的经济环境下,整体市场发展出现了低迷的趋势,许多求职者面临着找工作困难的局面。尤其是在深圳这样的大城市,竞争异常激烈,求职者需要更加精准地寻找与自己能力相匹配的工作岗位。让自己的能力和需求得到最大化的…

Android 后台线程

ExecutorService executor Executors.newSingleThreadExecutor(); executor.execute(new Runnable() {Overridepublic void run() {Bitmap bitmap getBitmapFromUrl(url); // 网络请求runOnUiThread(new Runnable() {Overridepublic void run() {imageView.setImageBitmap(bi…

【LeetCode】力扣刷题热题100道(31-35题)附源码 搜索二维矩阵 岛屿数量 腐烂的橙子 课程表 实现 Trie (前缀树)(C++)

一、搜索二维矩阵 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性: 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 可以使用 从右上角开始搜索 的方法来有效地找到目标值。 选择起始位置: 从矩…

C++实现设计模式---装饰器模式 (Decorator)

装饰器模式 (Decorator) 装饰器模式 是一种结构型设计模式,它允许动态地将责任附加到对象上,既可以在运行时给一个对象添加功能,又不会影响其他对象的功能。 意图 动态地扩展对象的功能。避免创建过多的子类,通过装饰器来“包装…

unity——Prejct3——背景音乐

1.音乐数据结构类 using System.Collections; using System.Collections.Generic; using UnityEngine;//音乐数据结构类 public class MusicData {//背景音乐 音效 开关public bool musicOpen true;public bool soundOpen true;//背景音乐 音效 大小public float musicValu…

LabVIEW与WPS文件格式的兼容性

LabVIEW 本身并不原生支持将文件直接保存为 WPS 格式(如 WPS 文档或表格)。然而,可以通过几种间接的方式实现这一目标,确保您能将 LabVIEW 中的数据或报告转换为 WPS 可兼容的格式。以下是几种常见的解决方案: ​ 导出…

解决Element Plus el-date-picker组件清空时,触发两次change的问题

问题 el-date-picker 组件在选择日期范围时会触发两次 change 事件。当用户选择了范围的开始时&#xff0c;会立即触发一次 change 事件。而当用户选择了范围的结束时&#xff0c;又会触发一次 change 事件。 解决方法 1. 延迟更新 <template><div>选择日期--{…

LeetCode 热题 100 | 矩阵

矩阵基础 使用哈希数组来标记当前行或者列是否出现0按层模拟旋转90度可以先水平翻&#xff0c;然后再对角线翻 73. 矩阵置零 题目讲解&#xff1a;LeetCode 重点&#xff1a; 使用标记数组&#xff1a;用两个标记数组分别记录每一行和每一列是否有零出现。使用两个标记变量&…