CSR8670的TWS模式的应用笔记

1. 应用场景

1.1 非TWS会话

单个音箱最多可以连两个A2DP源。

  • 当音箱A同时与两个A2DP源建立了连接,另一个音箱B不能与其建立TWS会话
  • 同一时间一个音箱只能选择2个A2DP源中的一个来播放

1.2 TWS会话

1.2.1 准备工作

单个音箱最多可以连接1个A2DP源,1组TWS会话最多连接2个A2DP源。

在进入TWS会话之前,两个A2DP源必须分别与两个音箱完成配对,否则一旦开始建立TWS会话,A2DP源无法搜索到两个音箱,也就无法配对。

1.2.2 建立会话

两个音箱与两个A2DP源完成配对后,开始建立TWS会话:

  • 音箱A调用EventUsrPeerSessionInquire,进入inquiry模式
  • 音箱B调用EventUsrPeerSessionConnDisc,进入conndisc模式
  • 音箱A搜索到音箱B,根据如下设定建立TWS连接:
    • 链接丢失后自动回连。建议slave使能此选项,防止master出现音频抖动
    • 使用受限呼叫访问码
    • 连接设备过滤方式。如果音箱B的UUID能通过音箱A设定的滤波器规则,那么音箱A与音箱B开始建立TWS连接。此处的滤波器规则有设备ID和CSR对等设备服务UUID,后者是由客户定义的非零值。
    • 配对模式

    • 是否支持作为音频中继者和音频被中继者
    • 音频中继模式:双立体声、主左从右、主右从左、缩混
    • 音量削减。TWS的音量由系统音量和削减音量控制。系统音量由AVRCP指令设定,削减音量的默认值存储在PSR配置中。master会将配置发送给slave,模式切换时master会再发送给slave

    • 单设备模式。此模式使能后,A2DP源的AVRCP指令可以在master,slave和A2DP源之间保持同步,否则slave接收的AVRCP指令不能中继到master

1.2.3 播放音频

  • TWS会话建立成功后,连接两个A2DP源中的一个并播放音频文件。假设A2DP源1正在播放,那么与A2DP源1配对的音箱作为TWS会话的master,另一个音箱作为slave。A2DP1的音频数据会从master中继到slave。

  • 假设此时播放A2DP源2,则与源2配对的音箱作为TWS会话的master,另一个音箱自动切换成slave

  • A2DP源可以是其它蓝牙设备,也可以是本地的音频接口。
    • 蓝牙设备必须支持A2DP,AVRCP协议。可支持的蓝牙设备的音频编码方式有SBC,MP3,AAC,aptX。
    • 本地音频接口包括USB接口和analog接口(ADC/SPDIF/I2S)。本地音频接口将音频数据缓存在内部RAM中,使用SBC编码后,通过master与slave之间建立的连接传送给slave。

    • slave接收后用SBC解码,将解码后的音频数据通过DAC转换成音频信号,或是用I2S接口输出给外部音频芯片。

1.2.4 设置命令

TWS模式支持AVRCP 1.4中定义的命令,包括快进快退,播放暂停等。

TWS模式也支持特有的AVRCP命令如下:

TWS模式支持的GAIA命令如下,且这些指令在TWS会话的两个设备之间同步(音量控制和设备音量削减控制不能同步):

TWS模式的音量控制分两部分:

  • 系统音量:可以通过AVRCP命令设定,如果需要同步到A2DP源,需支持AVRCP的绝对音量控制(absolute volume control)
  • 音量削减:可以由master通过如下用户事件调用

1.2.5 切换音频源

TWS模式建立时的默认音频源由PSR决定。可选项有auto,A2DP,USB,analog。

选择auto选项后,TWS连接建立时选择当前可用的音频源,优先级为A2DP>USB>analog。

运行时可调用下列事件以手动切换音频源:

可调用EventUsrSelectAudioSourceNone再切换回自动切换模式。

1.2.6 结束TWS会话

调用EventUsrPeerSessionEnd以结束TWS会话。

调用EventUsrEstablishPeerConnection以请求重新连接已配对完成的TWS会话。

2. 建立VM应用

2.1 修改VM应用工程properties

2.2 使能对等设备支持

  • 设定对等设备支持“true wireless”

  • 使能MP3,AAC和aptX A2DP编解码
    • 安装对应的ADK编解码包
    • 将对应的解码器工程包含在工作站内
    • 申请解码算法的授权
    • 修改speaker.mak,将kap文件加入到工程的映像文件夹
  • 使能扩展编解码extra codec

  • 使能USB / 有线音频

  • sbc_decoder的配置文件选择TWS_WIRED_MODE

2.3 使能调试信息

  • 修改sink_debug.h

    • 使能DEBUG_PRINT_ENABLE
    • 使能DEBUG_PEER
    • 使能DEBUG_PEER_SM
  • 添加库文件
    • 打开库文件目录C:\ADK4.0.0\tools\lib\BlueLab-7.0.1-Release\assisted
    • 找到libcsr_a2dp_decoder_common_plugin_stereo_tws_debug.a
    • xIDE->project->properties->libraries,添加csr_a2dp_decoder_common_plugin_stereo_tws_debug

3 扩展应用——analog模式的I2S接口

在CSR的官方demo中,当TWS模式的音频源是analog时,程序中设定的硬件接口是ADC。而本项目中需要用到I2S接口作为音频输入。修改步骤如下:

  • 第一步:将CSR8670的I2S设为master,采样率设为48KHz。

  • 第二步:按下暂停键后,I2S时钟会消失。修改sink_audio_routing.c的代码如下:

  • 第三步:修改csr_a2dp_decoder_common_plugin.c的函数MusicConnectAudio如下:

  • 第四步:重新编译库文件。开始菜单->adk4.0.0->rebuild->vm libraries
  • 第五步:修改sink_wired.c
    • 1: 修改宏定义,用程序来控制ADC设备的接入检测的结果

    • 2: 新建函数wiredAudioSetAnalogConnect(uint8 status)

  • 第六步: 只有inquriy的设备才会enable analog connect,当收到发送inquiry事件的请求时,使能模拟连接;当收到发送conndisc事件的请求时,关闭模拟连接。

  • 第七步:如果A2DP源发生切换,master和slave的规则也会发生转换,因此需修改sink_a2dp.c的sinkA2dpSetLinkRole

4 总结

TWS模式的特点是帧与帧之间有同步时间戳,两个音箱之间的音频数据延迟只有±5Sample。

在使用过程中遇到过长时间不能进入TWS会话的情况,还需继续深入探寻原因。

时间: 2024-11-05 20:46:51

CSR8670的TWS模式的应用笔记的相关文章

程序的加载和执行(六)——《x86汇编语言:从实模式到保护模式》读书笔记26

程序的加载和执行(六)--<x86汇编语言:从实模式到保护模式>读书笔记26 通过本文能学到什么? NASM的条件汇编 用NASM编译的时候,通过命令行选项定义宏 Makefile的条件语句 在make命令行中覆盖Makefile中的变量值 第13章习题解答 复习如何构造栈段描述符 我们接着上篇博文说. 在我修改后的文件中,用到了条件汇编. 比如: %ifdef DEBUG put_core_salt: ;打印内核的符号 ... ... put_usr_salt: ;打印用户的符号 ... .

【游戏设计模式】之四 《游戏编程模式》读书笔记:全书内容梗概总结

本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/53240330 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 本文的Github版本:QianMo/Reading-Notes/<游戏编程模式>读书笔记 这是一篇超过万字读书笔记,总结了<游戏编程模式>一书中所有章节与内容的知识梗概. 我们知道,游戏行业其实一直很缺一本系

设计模式---装饰者模式(学习笔记)

首先看装饰者模式的定义:动态的将责任附加到对象上.若要扩展功 能,装饰者提供了比继承更有弹性的替代方案! 先看看<大话设计模式>给出的类图: 实际上,装饰者模式就是:把装饰者对象当成"包装者",换言之,把要装饰的对象作为参数传递到装饰对象里去,然后进行操作.(如果理解不对,希望给指正),下面看代码来理解这个类图: 这是装饰者和需要装饰的具体对象共同的接口: public abstract class Component { abstract void Operation()

程序的载入和运行(五)——《x86汇编语言:从实模式到保护模式》读书笔记25

程序的载入和运行(五)--<x86汇编语言:从实模式到保护模式>读书笔记25 前面几篇博文最终把代码分析完了.这篇就来说说代码的编译.运行和调试. 1.代码的编译及写入镜像文件 之前我们都是在命令行输入命令进行编译和写入.源文件少的时候还不认为麻烦,当源文件多了,就会认为特别麻烦.有没有简单的方法呢? 当然有,就是用make工具. 1.1.什么是make工具 make是一个命令工具,它解释Makefile中的指令.在Makefile文件里描写叙述了整个project全部文件的编译顺序.编译规则

存储器的保护(一)——《x86汇编语言:从实模式到保护模式》读书笔记18

本文是原书第12章的学习笔记. 说句题外话,这篇博文是补写的,因为让我误删了,可恶的是CSDN的回收站里找不到! 好吧,那就再写一遍,我有坚强的意志.司马迁曰:“文王拘而演<周易>:仲尼厄而作<春秋>:屈原放逐,乃赋<离骚>:左丘失明,厥有<国语>:孙子膑脚,<兵法>修列:不韦迁蜀,世传<吕览>……”好了,不煽情了,进入正题. 第12章的代码如下. 1 ;代码清单12-1 2 ;文件名:c12_mbr.asm 3 ;文件说明:硬盘主引

存储器的保护(三)——《x86汇编语言:从实模式到保护模式》读书笔记20

存储器的保护(三) 改动本章代码清单,使之能够检測1MB以上的内存空间(从地址0x0010_0000開始,不考虑快速缓存的影响).要求:对内存的读写按双字的长度进行.并在检測的同一时候显示已检測的内存数量.建议对每一个双字单元用两个花码0x55AA55AA和0xAA55AA55进行检測. 上面的文字选自原书第12章的习题1. 这篇博文就讨论一下这道题.由于是初学,我不正确自己做太高的要求.仅仅要实现功能就可以. 代码清单 ;文件说明:第12章习题-1 ;创建日期:2016-3-7 ;------

程序的加载和执行(三)——《x86汇编语言:从实模式到保护模式》读书笔记23

程序的加载和执行(三)--读书笔记23 接着上次的内容说. 关于过程load_relocate_program的讲解还没有完,还差创建栈段描述符和重定位符号表. 分配栈空间与创建栈段描述符 462 ;建立程序堆栈段描述符 463 mov ecx,[edi+0x0c] ;4KB的倍率 464 mov ebx,0x000fffff 465 sub ebx,ecx ;得到段界限 466 mov eax,4096 467 mul dword [edi+0x0c] 468 mov ecx,eax ;准备为

《软件需求模式》阅读笔记03

在对需求模式的概念和内容方面有了深刻的了解之后,我将学习各类不同的需求模式. 基础需求模式是所有种类的系统都可能需要的一些东西,它包括了:技术.遵从标准.参考需求.文档.系统间接口.系统间交互.系统间需求模式是用来定义被定义的系统和任何与之交互的外部系统或组件之间的接口的基本细节,它包含了以下内容:接口名称.接口标识符.两端的系统.接口的目的.接口的所有者.定义接口的标准.用于接口的技术.在开发测试的时候,我们应该明确交互需求,找到隐含的交互以帮助满足间接陈述的目标.系统间交互需求模式是用来定义

《软件需求模式》读书笔记之三

接下来本书主要介绍了四个领域需求模式,性能领域需求模式,适应性领域需求模式,访问控制领域需求模式,商业领域需求模式. 性能领域需求模式有:响应时间需求模式.吞吐量需求模式.动态容量需求模式.静态容量需求模式.可用性需求模式.性能领域的需求模式解决的是系统的性能问题.响应时间是系统需要多少时间完成一个请求:吞吐量是系统处理事情的速率:动态容量是系统能够同时处理多少件事:静态容量是系统可以保存多少某种类型的实体:可用性是什么时候系统对用户是可用的,以及多么可靠. 适应性领域需求模式有:可伸缩性需求模