ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Auracast蓝牙广播音频开发实战:BT2106C模块与LC3编码详解

Auracast蓝牙广播音频开发实战:BT2106C模块与LC3编码详解 手头这块BT2106C Auracast蓝牙广播模块我前后折腾了差不多两周。从最初拿到开发板只能看到AT指令回显到后来能稳定地把Line-in输入的模拟音频以LC3编码广播出去手机、TWS耳机都能直接搜到并加入收听整个过程里踩得最深的一个坑是“广播音频”和普通蓝牙音频完全是两套设计逻辑。这篇分享就围绕BT2106C的Auracast模块开发重点聊聊方案选型、广播音频链路背后的机制、SDK里的关键配置以及实测排查中那些容易被忽略的细节给正在评估Auracast方案或者准备在产品里加广播音频功能的工程师做个参考。1. 模块选型与方案准备1.1 为什么用BT2106C做广播发射端Auracast广播音频对芯片的要求和传统蓝牙音频芯片不太一样。传统蓝牙音频SoC的核心是A2DP、HFP这类连接型协议一对一的音频流是重头而Auracast要求芯片至少支持蓝牙5.2以上的LE Audio规范内部要有完整的LC3编解码器还要能管理BIS这种广播同步流。市面上很多老款蓝牙音频芯片即使射频性能不错也无法通过软件升级支持Auracast因为底层controller和protocol stack根本不支持同步广播channel。我在选型时把BT2106C列入第一批评估对象主要看中几点它是一颗面向音频广播场景的SoC硬件上直接集成蓝牙射频、基带、协议栈和音频接口外围不需要额外挂蓝牙芯片支持LC3编码采样率覆盖16k/24k/32k/48kHz能对应不同音质档位工作电压3.0V到3.6V典型功耗控制得不错适合做便携式音频发射器。模块化之后PCB天线、晶振、电源电路都帮你做完了工程师不需要从零开始啃射频布局开发周期能缩短一大截。另外比较关键的一点是BT2106C的SDK里直接提供了Auracast broadcast的示例工程不需要你自己从blank project开始拼协议栈。对于做产品的人来说有能跑的demo和没有能跑的demo开发成本完全是两个量级。示例工程里已经包含了广播初始化、BIG配置、BIS数据发送的完整链路你要做的是改参数、接音频源、调效果而不是把时间花在底层协议移植上。1.2 开发板的硬件接口和测试环境我手上的测试板是标准模块评估板板载资源比较全实际做产品时可以只保留最小系统。简单列一下评估板上用到的接口USB接口5V供电同时也有串口功能板载USB转串口芯片方便看日志和发AT指令。模拟音频输入3.5mm Line-in端子可以直接接手机、电脑、音频播放器的耳机口芯片内部做ADC采样。I2S接口以排针形式引出可以外接数字音频codec比如接高精度DAC做高质量广播源或者接HDMI音频分离器输出。按键和LED一个复位键一个功能键LED状态灯用来指示广播状态、配对状态、音频输入状态。天线默认板载PCB天线预留了ipex座子方便外接天线做距离测试。开发环境方面主机建议用Ubuntu 20.04或Windows 10/11SDK里有对应的编译脚本和IDE工程。编译工具链是芯片原厂提供的交叉编译工具链烧录工具支持J-Link和串口下载两种方式我实测串口下载最省事但要先让芯片进入下载模式。串口调试波特率默认115200日志输出级别可以在SDK里配置。接收端测试设备不能随便拿一台蓝牙耳机就上必须确认设备支持Auracast接收。目前iPhone 17及以上系统配合AirPods Pro 2、部分Android旗舰配合自家TWS耳机可以支持还有一些蓝牙音箱、电视音频发射器也开始支持Auracast接收。我测试时主要用了一副支持LE Audio的TWS耳机、一台iPad外加一个Auracast接收测试盒三个接收端对照测试能更快定位问题是出在发射端还是接收端兼容性。1.3 SDK目录结构和编译准备SDK解压之后代码量不算小但框架很清晰。我常用的几个目录值得先看一眼apps/应用层代码广播音频demo就在这个目录下面你要改的配置参数也主要在这里。drivers/外设驱动包括ADC、I2S、GPIO、UART等如果自定义音频输入通道可能动这里的代码。stack/蓝牙协议栈包括LE Audio相关实现一般不用改但出问题时要进来查日志和事件定义。tests/各种自测用例参考价值不小。tools/编译脚本、烧录工具、日志解析工具。第一次编译demo时不要急着改代码先用默认配置编译一遍确认工具链、SDK依赖都正常。我的操作流程是cd apps/broadcast_audio_demo make clean make -j8编译完成后在输出目录里会生成固件文件通常带.bin扩展名。然后启动烧录工具选择对应的串口按住开发板上的下载键再插USB进入下载模式烧录完成后复位开发板。如果串口日志能正常打印boot信息说明环境已经OK了。这里有个小白容易踩的坑SDK路径不能带中文和空格否则make脚本会挂而且报错信息不直观排查半天才发现是路径问题。建议直接放在根目录或者~/workspace下。2. Auracast核心机制广播音频不是普通蓝牙的“高级模式”2.1 三个角色和两种广播形态Auracast的完整业务模型里有三个角色广播音频发射端Broadcast Audio Source、广播音频接收端Broadcast Audio Receiver和辅助管理端Auracast Assistant。发射端做的事情很简单采集音频编码成LC3然后通过BLE的同步广播机制把数据发出去。接收端做的事情是扫描到广播请求同步然后持续接收音频数据并解码播放。辅助管理端通常是一部手机或者平板它不直接收发音频而是帮助用户发现附近的广播源、展示广播名称和二维码甚至可以远程帮耳机加入私密广播。这里要强调一下Auracast的“广播”和我们常说的BLE beacon广播完全是两码事。Beacon广播里塞的是几字节到几十字节的状态数据数据速率极低而Auracast广播承载的是实时音频流一个BIS的码率可能到64kbps甚至更高。所以Auracast使用的不是传统广播信道而是蓝牙5.2引入的等时信道数据在空中按调度精准发送接收端按调度精准接收这样既保证音频连续性又能省电。两种广播形态也需要区分开。公开广播不需要任何认证接收端扫描到就能加入收听适合公共场所的讲解、通知、电视音频分享。私密广播则要求接收端提供Broadcast Code广播码32位才能解密音频流适合会议室、同传翻译这类需要控制听众范围的场景。BT2106C的SDK里两种模式都有示例切换很频繁但协议处理逻辑差异不小开发时不要想当然地以为只是加个密码。2.2 BIS与BIG广播音频的“数据公共汽车”理解Auracast的关键是先搞清楚BIS和BIG这两个概念。BIS全称Broadcast Isochronous Stream就是一条广播等时流承载一路音频数据。多条BIS可以组合成一个BIGBroadcast Isochronous Group就像一个广播电台集团下面可以同时开多个频道。打个比方把Auracast广播想象成公交系统。BIG是公交线路网络BIS是其中一条具体线路音频数据就是公交车上的乘客。接收端要做的是先通过站牌周期性广播PA知道有哪些线路然后选择一条线路乘车上车后就能持续收到乘客直到中途下车或者线路停运。多个BIS在一个BIG里支持不同的内容这是Auracast特别有价值的地方。比如机场广播同一个BIG里可以同时开三个BISBIS 0播中文登机通知BIS 1播英文登机通知BIS 2播日文登机通知。乘客用自己的耳机选择对应语言频道互相不干扰。博物馆导览、演唱会多语言同传也都是这个用法。在BT2106C的SDK里配置BIG和BIS是通过一个广播配置结构体完成的。你要指定BIG里面有多少个BIS、每个BIS对应哪一路音频输入、LC3参数是什么。开发时最需要注意的是接收端耳机通常会尝试同步BIG里第一个可用的BIS如果你把BIS排序搞错了用户听到的可能不是你想让他听的那一路音频。2.3 LC3编码与参数选择LC3是LE Audio指定的音频编解码器取代了传统蓝牙音频里的SBC。LC3在相同码率下音质比SBC好是公认的而且支持更多采样率和帧间隔组合。BT2106C内部集成了LC3编码器你只需要通过SDK配置参数不需要自己写算法。LC3有几个关键参数采样率8k/16k/24k/32k/48kHz、帧间隔7.5ms/10ms部分实现还支持20ms、声道数、码率。参数组合直接决定音质、延迟和功耗没有绝对最优要根据场景权衡。我测试时常用的几组配置采样率帧间隔典型码率适用场景48kHz10ms128kbps高音质音乐广播32kHz10ms96kbps语音轻音乐16kHz10ms64kbps清晰人声、通知播报24kHz20ms72kbps低功耗语音广播我自己做公共广播类产品时默认先用32kHz/10ms音质够用延迟也能控制在100ms以内。如果接收端设备性能一般比如一些低端TWS耳机可以降到16kHz稳定性会明显提升因为解码压力小了缓冲不容易溢出。要注意的是LC3参数必须和接收端匹配很多接收设备只支持固定的采样率和帧间隔组合配置不当会导致耳机搜到广播但加不进去。2.4 广播事件调度与功耗问题Auracast发射端的射频行为是事件驱动的。芯片不是连续不断地发数据而是按照BIG事件的时间表在每个广播事件里发送一段音频数据其余时间可以睡大觉。这个设计让发射端功耗远低于你想象中“一直开着蓝牙广播”的功耗水平。但有个容易忽略的问题接收端必须始终监听广播事件它不知道发射端什么时候发数据所以要保持接收窗口打开。这意味着接收端尤其是耳机的功耗压力其实不小。开发Auracast发射端时如果你把事件间隔调得太短比如每个BIG事件都安排得密密麻麻接收端解码功耗会高反过来事件间隔太长音频延迟就会变大而且接收端更容易丢同步。BT2106C的SDK里有广播事件配置项可以设置每个事件包含的音频帧数、事件间隔等。我的经验是如果目标接收端是耳机事件间隔不宜设置得太大否则耳机在移动或切换环境时容易出现瞬间断音如果目标接收端是固定设备比如音频接收盒、音箱可以适当拉大间隔省发射端功耗。3. 实操过程从SDK例程到稳定广播3.1 把广播demo跑起来拿到BT2106C开发板后第一步不是急着改功能而是把SDK里的broadcast_audio_demo原封不动编译烧录确认链路是通的。我这次的板子SDK版本里demo默认使用模拟音频输入也就是说从Line-in口灌音频芯片ADC采样后编码广播出去。这个默认配置非常适合快速验证因为不需要外接任何数字音频源拿手机播放音乐接到Line-in就能测。编译前要确认几件事。第一确认选择的固件配置支持Auracast有些SDK封装了多个profile默认构建出来的固件可能只支持经典蓝牙音频需要检查Makefile里的宏开关。第二确认串口日志打印功能打开方便后续调试。第三确认烧录工具能识别到开发板如果提示找不到设备多半是驱动没装好或者USB线不支持数据传输。烧录完成后开发板上电串口日志会出现初始化的信息。按一下功能键日志里如果出现类似“broadcast start”的提示说明发射端已经开始广播了。此时把手机或耳机的蓝牙打开在系统蓝牙设置里找到“广播音频”或者Auracast相关入口正常情况下能看到广播名称点击加入就能听到Line-in输入的声音。我这边第一次跑demo时就遇到了一个现象手机能搜到广播名但点击加入后一直转圈最后提示“无法加入”。后来排查发现是接收端耳机固件版本太老不支持48kHz的LC3把demo里的采样率改成32kHz后问题消失。这个现象后面在问题排查章节会再展开。3.2 关键配置参数逐项解读SDK里广播demo的核心配置通常集中在一个配置结构体里位置在app_config.h或者broadcast_demo.c里。我贴一个简化版的关键配置片段注意这不是某个特定SDK的原样代码而是梳理出共性的配置项方便你对照自己的工程broadcast_config_t g_bcast_cfg { .adv_name BT2106C_Aura, .bih_count 1, // BIG中的BIS数量 .bis_channel_map {0}, // BIS索引映射 .audio_input_source AUDIO_IN_ADC, // 模拟输入 .sample_rate 32000, // LC3采样率 .frame_duration_ms 10, // LC3帧间隔 .bitrate 96000, // LC3目标码率 .encryption_enable false, // 是否开启私密广播 .broadcast_code {0}, // 广播码加密时使用 .tx_power RF_POWER_0dBm, };这些参数逐个说广播名称adv_name接收端扫描时显示的名字也是用户在手机上看到的条目。实测下来名称尽量用纯ASCII字符中文通常能显示但部分接收端设备固件对UTF-8支持不完整会显示成乱码甚至导致加入失败。建议产品上使用英文字母数字的命名规范。BIS数量bih_count一个BIG里开几条流。如果只是单路广播填1就行。需要多语言或多路音源时填2以上同时要配置多个音频输入通道和LC3编码任务。BIS数量越多单个BIG占用的射频时间越长对CPU和射频调度压力也越大不建议盲目堆数量。采样率和帧间隔前面的表格已经对比过了。开发时把sample_rate和frame_duration看作一组官方SDK一般会提供几个预设组合比如LC3_PRESET_32K_10MS。直接用预设能避免参数组合不合法导致初始化失败的问题。发射功率tx_power0dBm到8dBm之间可调。产品做认证时发射功率通常和实际测试绑定开发阶段直接用默认值等整机调试好之后再做功率校准。3.3 加入音频输入和事件处理音频输入是很多工程师第一次调Auracast时卡住的地方。BT2106C支持模拟输入ADC和数字输入I2S两种方式demo里默认ADC。你要理解ADC采集进来的PCM数据不是直接发送的而是先经过LC3编码器压缩成一帧一帧的LC3数据包然后才封装到BIS事件里发出去。在代码层面数据流大概是这样的// 音频采集回调ADC DMA搬完一段数据后触发 void on_audio_capture_complete(uint8_t *pcm_buf, uint32_t len) { lc3_encode_frame(pcm_buf, encoded_buf, encoder_ctx); // 把编码后的数据交给广播堆栈 broadcast_send_bis_packet(encoded_buf, encoded_len, bis_index); }这个流程里我踩过的坑是编码速度跟不上采集速度。之前我把LC3采样率改成48kHz后忘记调整编码器的内部帧长度导致编码耗时超过帧间隔DMA数据一直在覆盖最终广播出的声音明显卡顿。排查办法很笨但有效在编码回调函数入口和出口各放一个GPIO翻转用示波器量编码耗时如果编码时间接近甚至超过帧间隔就要优化编码配置或者降码率。广播事件处理也值得关注。SDK会以事件回调的形式通知你广播启动、接收端同步、广播停止等状态。实际产品里你需要在“有接收端同步”时点亮一个LED在“无接收端”一段时间后自动停止广播省电。这些逻辑都放在事件回调里实现。void on_broadcast_event(broadcast_event_t evt) { switch (evt) { case BROADCAST_EVT_STARTED: led_set(LED_GREEN, ON); break; case BROADCAST_EVT_RECEIVER_SYNCED: // 有接收端加入 break; case BROADCAST_EVT_RECEIVER_LOST: // 接收端离开判断是临时离开还是结束 break; case BROADCAST_EVT_STOPPED: led_set(LED_GREEN, OFF); break; default: break; } }3.4 用手机和耳机做接收端验证发射端跑起来之后接收验证环节有几个容易踩的坑。先说说iOS这边iOS 17以上的设备系统蓝牙设置界面里新增了“广播音频”入口扫描到Auracast广播后会列出可加入的广播源。你点进去会看到广播名称和音频流信息点击“加入”即可开始收听。如果使用的是AirPods Pro 2配合iPhone加入成功后耳机里会直接播放广播音频不需要额外打开App。Android端的情况稍微复杂。Android 13开始系统层面支持LE Audio但Auracast广播音频的入口并不统一有些厂商放在“蓝牙设置-其他设备-音频广播”有些则只在自家自有耳机App里展示。实测下来Google原生系统的“蓝牙广播音频”菜单最标准第三方定制系统有的阉割了这个入口导致广播源扫描不到。这里有个小技巧可以用Auracast Assistant类的第三方App来辅助发现和加入广播它绕过系统设置菜单直接通过扫描PM和PA事件找到广播源配合测试盒使用效果更好。接收端测试时我通常会做三轮验证第一轮是1米内静态接收确认音频基本功能第二轮是10米内走动接收模拟真实使用场景第三轮是带遮挡测试比如隔一堵墙记录丢包率和卡顿现象。每一轮都要记录接收端的系统日志或芯片日志方便后续定位射频问题。如果你手头有蓝牙抓包工具比如Ellisys、Frontline这类带LE Audio解析能力的协议分析仪一定要在功能调试初期就用上。通过抓包你能直观看到PA广播事件、BIG事件、每个BIS的序号和数据包到达时间排查问题的效率会高出非常多。没有抓包器的话至少要会用芯片自身的射频测试指令确认发射端功率和频偏在正常范围。4. 常见问题与排查技巧实录4.1 搜不到广播先分清“搜不到”和“加不进”这个问题是出现频率最高的而且大多数人一开始会把两件事混在一起。搜不到广播说明接收端扫描阶段就没有发现PA周期性广播加不进广播说明接收端已经看到了广播源但同步BIS失败或认证失败。这两种问题的排查路径完全不一样。先看搜不到的情况。排查第一步确认发射端确实在广播状态这可以通过芯片日志或者LED状态判断。第二步检查广播信道是否被干扰2.4G频段里Wi-Fi、微波炉、隔壁的蓝牙设备都可能干扰PA广播可以把广播信道改成其他channel试试。第三步检查发射功率如果功率设置太低距离稍远就扫不到室内测试建议先用0dBm以上。第四步把接收端距离拉到1米以内排除距离因素。有一种隐蔽情况是发射端和接收端的蓝牙版本兼容问题。有些接收端设备虽然支持LE Audio但系统固件只实现了CIS连接音频没实现BIS广播音频这种设备搜到广播后会显示在列表里但永远加不进去。判断方法是换一个确定支持Auracast的设备测试如果换设备正常那问题就在接收端。4.2 音质差、卡顿、断断续续音频广播出现卡顿原因多半不在音频编码而在射频链路。BIS广播是单向链路发射端只管发接收端如果错过一个事件就永远错过那一段音频了没有重传机制。这和CIS不同CIS可以重传错过的数据包所以接收缓存不够只会延迟不会丢音BIS没有重传缓存不够就会直接卡顿。卡顿问题的排查顺序第一看信号强度。用芯片日志打印接收端的RSSI如果低于-80dBm先改善天线和距离。第二看干扰。在办公环境下2.4G Wi-Fi工作信道和蓝牙广播信道可能重叠试着手动切换广播信道。第三看发射端缓冲配置。SDK里广播缓冲区的深度影响抗干扰能力缓冲调大一些抗突发干扰能力会增强但端到端延迟也会变大。第四看LC3码率。码率过高在弱信号下更容易出现解不出来适当降一档会有改善。另外如果音频输入源本身不稳定比如ADC输入信号太弱或者过冲也会表现为“广播出来的声音忽大忽小、杂音很重”。先直接在本地播放输入源排除音源问题再怀疑蓝牙链路。4.3 私密广播加不进去开启加密广播后接收端加入时需要输入Broadcast Code广播码。实际测试中最常见的失败原因是Broadcast Code的字节序问题。蓝牙空中传输的Broadcast Code有统一的字节序要求而SDK里配置的数组是本地字节序如果转换错误接收端解密时得到的码完全不一样自然进不去。排查方法先用不加密的公开广播测通整条链路再打开加密。加密模式偶发进不去时可以确认接收端是否支持私密广播。部分入门级TWS耳机虽然支持Auracast接收但只支持公开广播不支持加密广播这个在选型时就要提前确认。另外给接收端添加Broadcast Code时很多手机是通过扫描二维码自动填入的。这个二维码本质上是把广播名称、加密标志、Broadcast Code等信息编码在里面格式要符合Auracast Assistant规范。SDK如果不提供二维码生成工具可以自己按照规范生成注意编码字段不能有错。4.4 多个广播源互相干扰一个人在同一空间测试多台Auracast设备时会出现广播源互相抢信道的情况。现象是A设备广播正常B设备一开广播A的接收端开始卡顿。这背后是多个周期广播事件在同一个信道上发生碰撞。解决思路有几种。一是让不同广播源使用不同的广播信道SDK里可以设置信道映射把A设在37信道B设在38、39信道。二是错开广播周期如果A的广播事件间隔是20msB的间隔可以设成30ms减少碰撞概率。三是降低单台设备的发射功率只要覆盖目标区域就行不必功率拉满。这个方法在展会、商超这类多设备场景下特别实用。如果你量产的产品要支持同一空间多台并发建议在固件里做信道和事件间隔的动态选择逻辑而不是让每台设备都用默认值。4.5 实测距离不达预期开发板和模块的射频性能在实际组装成产品后往往会打折扣。我这次测试裸板加PCB天线空旷环境实测距离大概在25米左右但装进外壳、加上电池和排线之后距离直接缩到12米。原因主要是天线周围被金属件和电池地平面遮挡天线净空不够。优化距离的方向第一PCB天线周围要保持净空不要在正上方覆盖金属或大面积地铜第二优先选ipex外接天线方案调试阶段可以换不同增益天线快速测试产品定型后再决定内置还是外置第三检查天线匹配电路用网络分析仪看S11参数谐振点偏了距离会差很多第四在功耗允许的前提下提高发射功率从0dBm提到8dBm大概能增加30%到50%的距离但也要注意认证限值。调试距离时别在电脑旁边测电脑的USB3.0接口和显示器都会辐射干扰信号实测效果会偏悲观。找个相对空旷的走廊或者室外环境测得到的数据才有参考意义。4.6 常见问题速查表现象可能原因快速排查与解决手机搜不到广播发射端未启动广播信道干扰功率过低确认芯片日志和LED换信道距离拉到1米内能搜到但加不进接收端不支持BISLC3参数不匹配固件兼容性换已知支持的耳机验证降低采样率到32k或16k加入后没声音BIS索引配置错误接收端选择了错误的音频流确认BIS排序单BIS场景时把bih_count设为1音频卡顿断续信号弱射频碰撞缓冲不足看RSSI切换广播信道增大广播缓冲加密广播进不去Broadcast Code错误接收端不支持私密广播用公开广播验证检查字节序换高版本接收端距离明显偏短天线净空不足匹配不良功率设置低检查天线布局用ipex天线对比提高发射功率广播名显示乱码编码格式GB2312/UTF-8混用统一使用UTF-8编码暂时用纯英文字符命名5. 再分享两个调试时的小技巧第一个技巧是验证LC3编码质量时不要直接听声音而是先在芯片内部做数据回环测试。把编码器输出的LC3数据直接送给同一个芯片的解码器解出来再播放这样能确认编码环节没有异常。如果回环正常但广播接收后音质不对问题就在射频链路上再用抓包器看空口错误率一层层隔离问题。第二个技巧是调试音频输入路径时在ADC配置里开一下数字增益和限幅防止输入信号过大削波。削波后广播出来的声音会有明显的爆音和沙哑感容易被误判成蓝牙传输问题。我一开始就栽在这里把Line-in音量开到最大广播出来音质很差还以为是LC3码率不够折腾半天才发现是前端削波了。后续如果想把BT2106C做成产品级Auracast发射器还可以扩展的方向不少。比如加一个OLED屏幕显示广播名称、BIS数量和发射功率音频输入从模拟口升级到I2S数字口配一颗支持USB Audio的桥接芯片就能让电视或电脑直接通过USB输出广播音频再比如把加密广播的Broadcast Code做成动态生成通过App扫码配网整体安全性会更好一些。我在实际开发中体会最深的一点是Auracast把音频从“连接”中解放了出来一对多、多频道、按需加入这套体验对公共广播和信息推送类产品的价值才刚刚开始显现。
返回列表