news 2026/9/8 14:37:26

基于BT2106C的Auracast广播音频设计与实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于BT2106C的Auracast广播音频设计与实践

1. 内容整体设计与思路拆解

1.1 这次项目要解决的问题是什么

做蓝牙开发这么久,我一直觉得“一对一连接”这件事限制了蓝牙的想象力。无论耳机、音箱还是助听器,蓝牙音频走的基本都是经典蓝牙A2DP,或者现在的LE Audio点对点连接。两个设备之间必须先握手、配对、建立连接,然后才能传声音。这个链路稳定是稳定,但在某些场景里真的不够用——比如一群人想同时听同一段广播,比如观众席里想听同传翻译,比如机场里想听某个登机口的最新通知,靠点对点连接完全没戏。

Auracast就是补上这个短板的方案。它是LE Audio里的广播音频技术,核心是把音频流以广播的形式发出去,周围任何支持Auracast的设备都可以“订阅”收听,不需要配对,不需要握手,来多少设备就能服务多少设备。BT2106C就是一颗支持这套协议栈的蓝牙SoC模组,我们要做的这块板子,就是让音频信号通过模组转换成Auracast广播,再用手机或耳机验证实际收听效果。

这个项目适合谁看?一个是正在做音频类硬件、想把广播音频加进来的嵌入式工程师,另一个是想评估Auracast能不能落地到自己产品里的产品经理或技术负责人。我会把从模块选型、硬件设计、协议栈配置到实测踩坑的完整过程都过一遍,很多细节是单看datasheet和SDK文档发现不了的。

1.2 为什么选BT2106C而不是自研方案

先说结论:这个项目的时间窗口很紧张,自研方案的第一版流片风险完全不可控,所以直接选了模组方案。BT2106C这块模组的核心优势,首先是协议栈完整度,Auracast必须依赖LE Audio的同步广播链路,也就是BIS(Broadcast Isochronous Stream),模组SDK里已经把同步广播的收发链路封装好了,省掉了从零啃协议栈的周期;其次是射频性能,PCBA上的天线匹配和生产一致性已经调好,比自己做板子再花两周调天线要省心得多。

模块党还有个隐藏好处在于认证。产品要做BQB认证和各类无线认证,用模组可以直接继承模组厂做过的射频认证报告,自己整板只需要关注产品层面的EMC和音频指标。这是很多团队第一次做蓝牙音频品类时容易忽略的成本项,别小看这份报告,它能省下好几万认证费和两三周整改时间。

模块本身主要关注这几个维度就够了:内核主频和Flash/RAM大小决定功能扩展空间,是否内置音频Codec或者需要外挂,以及SDK是否支持后续OTA升级。我这边因为要同时兼顾低功耗和后期算法迭代,所以选了性能稍高一点的版本,Flash留余量很重要,后期想加个EQ、降噪算法都方便,别把存储卡太死。

2. 核心细节解析与实操要点

2.1 硬件层容易被低估的三个地方

第一是晶振精度。Auracast广播依赖接收设备在指定时间窗口内同步接收数据包,如果发射端晶振漂移太厉害,接收端同步就会断续甚至丢包。BLE音频相关模块一般要求32.768kHz的RTC晶振和32MHz的主晶振精度尽量做到±20ppm以内,这个不能贪便宜,普通晶振贴上去,实测距离一拉开就掉同步,很难排查。

第二是射频周边。Wi-Fi/BLE共存的天线布局要提前想清楚,BT2106C这类模组一般引出RF pin,外接天线或者直接使用板载PCB天线。如果产品里还有4G模组或者WLAN模块,注意分时控发以及天线隔离度,否则互扰情况下Auracast广播会周期性丢失,表现就是“滋滋啦啦”。

第三是音频输入链路。我这块板子的输入源是Line In和板载驻极体麦克风,两颗都进了一颗外置Audio Codec(I2S接口),再送给BT2106C编码广播。这个链路里最容易踩坑的是模拟地分割和Codec供电纹波,Codec的模拟Vref如果贴着DCDC的开关噪声,SNR会被吃掉好几个dB,听感上就是底噪明显。第一次打板我把Codec供电直接挂在系统3.3V上,底噪达到了难以接受的水平,后来换成独立LDO再加磁珠隔离,才把底噪压下去。

硬件上还有一个好习惯:预留Type-C接口的USB调试串口。Auracast开发过程中需要反复看协议栈日志,没串口等于瞎调。我把UART和SWD都引到了Type-C座,一根线供电、烧录、看日志全搞定,开发效率提升非常明显。

2.2 协议栈配置里最容易踩的坑

Auracast的协议栈分层可以简单理解为一个“发广播”的外层广播加一个“传音频”的内层同步流。设备首先要周期性广播一组“音频广播的元数据”,内容包括广播名、语言、音频参数等,接收端(比如手机)扫描到之后,才会去同步对应的BIS流。

关键配置在于三个地方。

第一个是广播与同步广播的数据包间隔。这个影响的是端到端延迟与抗干扰能力。间隔越大延迟越高,但同时功耗越低、抗同频干扰能力也相对好。我们最后采用广播间隔100ms、BIS同步间隔10ms的配置,延迟体感大约在100~200ms之间,这个规格我认为是目前功耗、延迟、稳定性比较平衡的一组值。

第二个是LC3编码器参数。Auracast广播音频统一用LC3编码,我们用的是48kHz采样、单声道、80ms帧间隔、96kbps码率。这个码率在语音广播和音乐广播里都够用,单声道也合理——耳机端本来就是双耳接收同一路广播,没必要发双声道浪费带宽。如果想提升听感可以上128kbps,但距离和抗干扰余量会小一点。

第三个是广播元数据的规范命名。你不起一个规范的广播名和分类,手机上的Auracast扫描界面很难把频道识别成“公开广播”还是“私人广播”。演示给别人看的时候,一个乱码的广播名会显得很不专业。我建议把广播名设置成产品名加语言代码,比如“Meeting Room CN”,方便后续对接Auracast App等工具的过滤。

2.3 用到的测试工具与整体环境

调试阶段强烈建议准备三样东西:一台支持LE Audio的Android手机(Android 13以上)、一台iPhone(iOS 17以上),以及一台支持Auracast接收的TWS耳机。Android这边我用的nRF Connect做底层广播观测,再加Auracast官方的Scratch app做订阅收听;iPhone的Experience Auracast app也可以,两者功能差异不大,但Android能看到更多底层参数,所以我主力用安卓调试。

有人会问没有Auracast耳机怎么办,其实不完全依赖耳机也能验证链路。先用能接收的耳机确认“广播音频依然可用”,再用手机App确认“扫描并订阅Auracast广播”,这两个能力基本能覆盖链路的主要节点。耳机端如果提示“广播暂时不可用”,多半是接收端兼容性问题,跟发射端链路不一定直接相关,要独立排查。

3. 实操过程与核心环节实现

3.1 开发环境搭建与工程结构

BT2106C的SDK是厂商基于Zephyr RTOS定制的,编译工具链用west + GNU Arm Embedded Toolchain。这个组合对于用惯了STM32裸机开发的人会有点陡峭,但别慌,本质上就是“配置设备树 + 写应用层回调”。

我这边工程结构大致是这样:board目录放板级设备树,改I2S、GPIO、电源引脚;audio目录放Codec驱动适配层;broadcast目录放Auracast广播参数配置和应用回调。编译一次大约两分钟,迭代效率完全能接受。

烧录方式两种:一种是用J-Link通过SWD直接烧,另一种是生成量产固件后用串口OTA。OTA一定要在开发早期就接入,否则每次改参数都得开壳接线,会让人崩溃。

3.2 广播配置核心代码思路

下面是广播链路初始化的关键配置思路,我注释了每个参数在实测中的表现影响,大家可以根据自己场景改数值。代码只是示意简化版,完整实现还是要看SDK里的broadcast_demo。

/* 周期性广播参数:决定接收端能否稳定发现广播 */ static const struct bt_le_adv_param adv_param = { .id = BT_ID_DEFAULT, .options = BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_EXT_ADV, .interval_min = 100, /* 广播间隔,实测100ms比较稳 */ .interval_max = 100, }; /* BIS同步流参数:决定音频数据包发送节奏 */ static struct bt_audio_broadcast_create_param broadcast_param = { .subgroup_count = 1, .subgroup = &subgroup_param, .stream_param = &stream_param, /* framing = BT_AUDIO_FRAMING_LE, LC3配置见stream_param */ }; /* LC3编码参数:48kHz/单声道/80ms帧/96kbps */ static struct bt_audio_codec_cap codec_cap = { .id = BT_AUDIO_CODEC_LC3, .data = lc3_preset_data, };

这里有三个细节:

  • 广播间隔别贪小,曾经为了“被扫描到更快”改成30ms,结果功耗飙升,接收端在嘈杂环境里反而更容易丢同步;
  • BT_LE_ADV_OPT_CONNECTABLE这一步不是必须的,但如果之后想用手机App做参数配置或固件升级,保留连接广播能给后续开发留口子;
  • 音频帧间隔80ms和LC3编码器内部的帧长度是配套的,改动要同时看两端,只改一边会直接起不了流。

3.3 广播启动与音频采集联动

音频采集侧我单独跑了一个线程,从Codec的I2S RX读PCM数据,经过重采样和增益处理后塞进环形缓冲区,广播任务再从缓冲区取数据交LC3编码并送入协议栈。这里最核心的联动是缓冲区的容量设计和回调节奏,不能让音频任务写溢出,也不能让广播任务长时间读空。

我调试时用了一个笨但有效的办法:先在缓冲区写一个固定的正弦波序列,不接真实音源,广播后用耳机听播放出来的音调正不正常。如果音调对了,说明整条链路时序正常;如果音调变调或出现“嚓嚓”声,说明采样率或帧长度设置有偏差。这个方法强烈推荐,它能在没有音频分析仪器的情况下快速区分是“数字链路问题”还是“模拟前端问题”。

音频数据从PCM到LC3是固定码率的,所以网络带宽很稳定。下面这段是实际运行时开启广播音频流的关键调用顺序,缺少任何一步都会导致“广播发出来了但耳机收不到声音”。

/* 1. 创建广播音频流并注册回调 */ bt_audio_broadcast_create(&create_param, &bcast); /* 2. 启动周期性广播,接收端才能发现广播 */ bt_le_adv_start(&adv_param, adv_data, adv_data_len, NULL, 0); /* 3. 更新广播元数据(广播名、语言等) */ bt_audio_broadcast_update_base(bcast, &base_param); /* 4. 提交音频数据到编码器 */ while (1) { pcm_read(&buf); /* 从I2S取得PCM数据 */ lc3_encode(&buf, out_packet); bt_audio_broadcast_send(bcast, out_packet, size); }

出错最多的就是第3步:有人把所有步骤都写了但没更新广播Base信息,结果手机App能看到一个空广播,没有音频参数,订阅按钮是灰的。排查这类问题看SDK日志里的base update status,基本一查一个准。注解里写的需求我尽量给了直接可用的代码,但不同SDK版本API名会有差异,还是以你的SDK版本文档为准。

3.4 性能实测数据

测试场地在一块相对空旷的办公区,手机和模块之间没有金属隔断。实测数据如下:

测试项测试条件结果
广播发现距离空旷区域,手机扫描约25米内稳定可见
音频播放距离空旷区域,Auracast耳机接收18米内无断续
穿越一堵隔墙5米距离,隔混凝土墙可听但偶有卡顿
延迟体感播放节拍器信号约120ms,感知明显但可接受
连续播放稳定性1小时持续播放无掉线、无同步丢失

空旷区域能跑到18米其实已经超出预期,但穿墙衰减依然明显,这是蓝牙2.4G频段的物理特性决定的。如果产品定位是公共广播,发射端功率可以再往上调,但注意当地法规对蓝牙发射功率的上限要求,不要盲目加大。中等距离下的稳定性优先级高于绝对距离,我的建议是先保证20米内极稳定,再去挑战30米。

4. 常见问题与排查技巧实录

4.1 手机完全搜不到Auracast广播

这个问题出现频率最高。先别怀疑模块,从接收端开始排查:手机是否支持LE Audio,Android手机对Auracast的支持受厂商定制影响很大,系统更新之后也有可能被砍功能;手机系统设置里是否开启了“扫描附近设备”权限;如果你用的是国行手机,部分品牌默认没有开启蓝牙广播扫描的功能,需要在开发者选项里单独打开。

排除了手机之后,用nRF Connect看模块有没有发出周期性广播。如果能看到周期性广播但看不到Audio Broadcast就说明广播扩展包有问题,重点检查bt_audio_broadcast_update_base。如果周期性广播都没有,回到配置来看adv是否启动成功,这个一般日志里能看出来。

4.2 能搜索到广播但耳机没声音

能搜到广播说明元数据链路是通的,耳机没声音大概率是BIS流同步或音频格式不匹配。最典型的例子是LC3采样率和帧间隔不匹配。耳机端如果只支持48kHz/10ms帧,你SDK里配了48kHz/80ms帧,常规情况下它也会尝试解码,但耳机的软件实现可能对长帧支持并不完整。

另外检查是不是把双声道数据发到了单声道接收的链路。有些TWS耳机在Auracast模式下默认按单声道解析,你发了立体声LC3,它会解出来但声音很奇怪。我的建议是广播一律用单声道,兼容性比立体声好太多。如果之后必须做立体声,一定要用支持对应参数的耳机测试。

4.3 播放一会儿后周期性卡顿

这种“间歇性卡顿”我排查了好几天,最终定位到两个原因。

第一个是周围Wi-Fi频段干扰。2.4G Wi-Fi的20MHz带宽信道和蓝牙广播信道的频率存在交叠可能,尤其办公区路由器密集。解决办法是通过产品配置软件把广播信道调整到相对干净的信道上,或者开启模组的共存机制,让Wi-Fi和蓝牙分时调度。硬件上如果天线位置冲突,干扰会比软件更严重,需要检查天线布局。

第二个是缓冲区水位管理问题。我的音频采集线程和广播发送线程速率如果有微小偏差,长时间运行后缓冲区要么溢出要么读空,听起来就是每隔几十秒卡一下。解决方法是把环形缓冲区加大到能容纳400ms以上的音频数据,并做动态水位补偿:水位低于20%时发送端把帧间隔适当拉长,水位高于80%时加快读取。这个策略调好之后,连续播放1小时再没出现卡顿。业余条件下可以用长时播放录音来定位卡顿的周期,再结合日志确认是不是水位触发。

4.4 手机App显示订阅成功但延迟很大

延迟取决于整条链路:采集端缓冲、LC3编码器算法延迟、BIS广播间隔、接收端解码与耳机缓冲。模块这边的可调项主要是BIS同步间隔。如果应用场景是口译广播,延迟超过150ms就建议改成5ms或更密的广播间隔,但功耗会上升,抗干扰余量也会下降。取舍逻辑很简单:延迟敏感场景优先保延迟,稳定优先场景保间隔。

接收端耳机的缓冲策略你控制不了,有的耳机为了抗干扰故意做了较大的缓冲,这会造成一部分延迟。所以做延迟对比测试时,用同一副耳机测不同模块参数才有横向可比性,千万别拿一副耳机延迟去对标另一副耳机的数据,产品实测时对这个差异要保持清醒。

4.5 想要产品化还需要做什么

开发板跑通只是第一步。真正要落地成产品,还要做这些事情:第一,整合低功耗策略,Auracast广播如果一直满功率发送,功耗会比较可观,需要考虑触发式广播、多状态电源管理;第二,把配置工具从调试串口升级成BLE连接配置,用户通过App改广播名、改语言、调整音量增益都走无线通道;第三,申请BQB认证时产品清单里明确用到的模块型号和固件版本,模组认证能简化流程但不能完全替代产品认证;第四,量产测试不能只测射频指标,建议产线上增加“广播能被手机搜索到”的功能测试项,避免个别模组贴歪天线或焊接不良导致出厂就哑火。

我自己的体会是,这个项目最大的收获不在Auracast本身,而在于它让我把Zephyr的协议栈、设备树、音频数据通路完整贯通了一遍。Auracast目前还处于早期应用阶段,接收端生态正在快速补齐,手机上原生的广播扫描已经是标配,后续这个方向的应用会越来越多。如果你手头正好有BT2106C或者其他支持LE Audio的模组,强烈建议先按我上面的思路跑通一版广播,然后加上自己场景里的音频源和交互逻辑,你会很快看到这项技术在产品中的真正价值。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 14:36:16

UE5 UMG图表插件开发实战:从曲线图到柱状图的自绘方案

简介:这是一套面向Unreal Engine 5的UMG图表控件插件,专为游戏开发与虚拟现实应用提供数据可视化方案,完全基于UMG构建,不依赖WebBrowser或WebUI嵌套,采用纯C与蓝图结合的方式,可绘制曲线图、饼图、环状图和…

作者头像 李华
网站建设 2026/9/8 14:35:35

[AutoSar]状态管理(四)单核BswM(二)流程、配置、 代码

目录关键词平台说明一、BswM的模式处理流程图二、stand state handling三、配置、代码、状态转移3.1 initial -> wakeup   3.2 WakeUp -> Run3.3 Run -> PostRun (first step)3.4 Run -> PostRun (second step)3.5 …

作者头像 李华
网站建设 2026/9/8 14:26:58

DL388 Gen10装Windows Server看不到硬盘?S100i驱动加载与ZIP解压全流程

简介:针对HP ProLiant DL388 Gen10服务器的阵列卡驱动合集,面向服务器运维与系统部署人员,用于解决安装操作系统时无法识别硬盘空间的问题。该服务器依赖Smart Array智能阵列控制器管理RAID,若缺少对应驱动,Windows或L…

作者头像 李华
网站建设 2026/9/8 14:24:11

火山方舟Agent Plan实战:模型选型与成本控制全攻略

做AI应用的人,最近肯定绕不开“Agent”这个词。从单轮对话到多步任务拆解,从工具调用到结果反思,Agent正在把大模型从聊天框里拽出来,真正落到业务流程里。不过,真正动手接Agent的时候,很多人第一个遇到的问…

作者头像 李华
网站建设 2026/9/8 14:20:07

内网离线安装Docker与Docker Compose全流程实战指南

简介:面向中初级运维工程师及容器平台实施人员,这份资源包针对无外网、内网隔离的部署环境,集中解决了离线安装Docker引擎与Docker Compose时依赖包缺失、下载困难的问题。包体包含22个文件,主要由20个RPM格式的系统依赖与Docker组…

作者头像 李华