我爱蓝牙网 - 52Bluetooth - 最具人气蓝牙技术交流网站

 找回密码
 立即注册

只需一步,快速开始

使用微信账号登录

qcc304x笔记之音频链路(chain)机制

2020-11-23 21:48| 发布者: csdn| 查看: 776| 评论: 0|来自: csdn

摘要: 相关概念介绍首先介绍一些相关概念,为了方便理解,引用面向对象思想中class与object描述。类(class):类是具有相同属性和服务的一组对象的集合。它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和服务 ...

相关概念介绍

首先介绍一些相关概念,为了方便理解,引用面向对象思想中class与object描述。
类(class):类是具有相同属性和服务的一组对象的集合。它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和服务两个主要部分。在面向对象的编程语言中,一个类是一个独立的程序单位,它应该有一个类名并包括属性说明和服务说明两个主要部分。

对象():对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的一组服务组成。从更抽象的角度来说,对象是问题域与实现域中某些事物的一个抽象,它反映该事物在系统中需要保存的信息和发挥的作用;它是一组属性和有权对这些属性进行操作的一组服务的封装体。客观世界是由对象和对象之间的联系组成的。

类与对象的关系就如模具与铸件的关系,类的实例化结果就是对象,而对一类对象的抽象就是类。类描述了一组有相同特性(属性)和相同行为(方法)的对象。

Capability:将对音频的处理能力--Capability的抽象,class,参考上述class
Operator:对音频处理的实际操作,可以看做是Capability的具体实现,参考object
Chain:音频会经过一系列的处理(operator),然后才会输出,以固定的流程将这一系列的处理串在一起,就形成了一个处理链路,也就是chain


实例分析

下面我们针对一个具体的实例--提示音的播放进行分析

提示音

提示音chain分析

下面这段代码是在chain_prompt_decoder_no_iir.c中,是由chain_prompt_decoder_no_iir.chain文件转化来的

/*指明有这段chain中用了两种Capability,对应的也有两个Operator*/
static const operator_config_t operators[] =
{
    MAKE_OPERATOR_CONFIG(CAP_ID_SBC_DECODER, OPR_PROMPT_DECODER),
    MAKE_OPERATOR_CONFIG(CAP_ID_BASIC_PASS, OPR_TONE_PROMPT_BUFFER),
} ;
 
/*指明当前chain的音频输入的端点(EPR_PROMPT_IN),并说明音频由该端点输入之后,下一步进行的操作(OPR_PROMPT_DECODER)*/
static const operator_endpoint_t inputs[] =
{
    {OPR_PROMPT_DECODER, EPR_PROMPT_IN, 0},
} ;
/*指明当前chain的音频输出的端点,当前的chain最后一个操作(OPR_TONE_PROMPT_BUFFER),音频通过端点(EPR_TONE_PROMPT_CHAIN_OUT),流到下一个chain或者硬件设备*/
static const operator_endpoint_t outputs[] =
{
    {OPR_TONE_PROMPT_BUFFER, EPR_TONE_PROMPT_CHAIN_OUT, 0},
} ;
 
/*chain各个Operator之间是怎么连接的,此处将两个Operator(OPR_PROMPT_DECODER与OPR_TONE_PROMPT_BUFFER)连接起来*/
static const operator_connection_t connections[] =
{
    {OPR_PROMPT_DECODER, 0, OPR_TONE_PROMPT_BUFFER, 0, 1},
} ;

所以在这条chain上的音频流如下:

EPR_PROMPT_IN->OPR_PROMPT_DECODER->OPR_TONE_PROMPT_BUFFER->EPR_TONE_PROMPT_CHAIN_OUT

下面这段代码是在chain_output_volume_mirror.c中,是由chain_output_volume_mirror.chain文件转化来的。output有两条chain,当包含mirror时用mirror的output,否则用普通的output。

/*指明有这段chain中用了两种Capability,对应的也有两个Operator*/
static const operator_config_t operators[] =
{
    MAKE_OPERATOR_CONFIG_PRIORITY_MEDIUM(CAP_ID_SOURCE_SYNC, OPR_SOURCE_SYNC),
    MAKE_OPERATOR_CONFIG_PRIORITY_MEDIUM(EB_CAP_ID_VOL_CTRL_VOL, OPR_VOLUME_CONTROL),
} ;
/*指明当前chain的音频输入的端点(EPR_SINK_MIXER_MAIN_IN、EPR_VOLUME_AUX)*/
static const operator_endpoint_t inputs[] =
{
    {OPR_SOURCE_SYNC, EPR_SINK_MIXER_MAIN_IN, 0},
    {OPR_VOLUME_CONTROL, EPR_VOLUME_AUX, 1},
} ;
/*指明当前chain的音频输出的端点(EPR_SOURCE_MIXER_OUT)*/
static const operator_endpoint_t outputs[] =
{
    {OPR_VOLUME_CONTROL, EPR_SOURCE_MIXER_OUT, 0},
} ;
/*说明chain两个Operator如何串联的*/
static const operator_connection_t connections[] =
{
    {OPR_SOURCE_SYNC, 0, OPR_VOLUME_CONTROL, 0, 1},
} ;

所以在这条chain上的音频流如下:

EPR_SINK_MIXER_MAIN_IN/EPR_VOLUME_AUX->OPR_SOURCE_SYNC->OPR_VOLUME_CONTROL->EPR_SOURCE_MIXER_OUT

当我们连接TRB打开QACT工具,播放提示音就可以看到链路如下图所示,两幅图是一样的,后图我进行了标注,其中1区为prompt的chain,2区(不包含Basic)为output的chain,正好可以与上述的音频流描述对应:

 

提示音代码解析

(注:由于SDK在持续更新,文中所述的有些接口可能会有些变化,这里仅供参考)

kymera_msg_handler
	KYMERA_INTERNAL_TONE_PROMPT_PLAY
		appKymeraHandleInternalTonePromptPlay
			kymera_CreateTonePromptOutputChain
				KymeraOutput_CreateChain
					/*创建一个volume control的chain,并配置*/
					kymeraOutput_CreateOutputChainOnly
						KymeraOutput_CreateChain
					/*将音频与实际的物理输出连接起来*/
					KymeraOutput_CreateOutput
						kymeraOutput_ConnectChainToAudioSink
							Kymera_ConnectOutputSource
								AudioOutputConnect
									connect
			/*开功放*/
			appKymeraExternalAmpControl
			/*创建提示音的chain*/
			kymera_CreatePromptChain
			/*配置提示音的chain*/
			kymera_ConfigurePromptChain
			/*使能dsp的电源*/
			appKymeraConfigureDspPowerMode

通过代码也可以看到,一共创建了两条chain:prompt和output。将两条chain链接起来,然后打开了dsp和功放,提示音就可以正常播放了。

sbc格式音频播放

然后我们在以sbc的格式音乐播放来简单说明,qact所示的链路如下图:

代码流程如下:

kymera_msg_handler
	KYMERA_INTERNAL_A2DP_STARTING
	appKymeraHandleInternalA2dpStart
		appKymeraA2dpStartMaster
            /*共创建了三条链路*/
			appKymeraCreateAndConfigureOutputChain
			appKymeraCreateInputChain
			Kymera_CreateMusicProcessingChain

涉及的三条chain为chain_output_volume_mirror.chainchain_music_processing.chainchain_input_sbc_stereo_mix.chain,有兴趣可以自己核对一下,三条chain中的Operator与上图中的所示的块是否能对应起来,这里我也就不细说了。

然后其他的链路,包括通话,anc等等也可根据上述的方法进行类推,反正就会一通百通嘛!

来源:https://blog.csdn.net/ylangeia/article/details/109805137
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

免责声明

1.本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
2.如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。

3

鲜花
1

握手

雷人

路过

鸡蛋

刚表态过的朋友 (4 人)

相关阅读

最新评论

发布主题 客服中心 搜索 官方QQ群

QQ|小黑屋|简约版|手机版|我爱蓝牙网 - 52Bluetooth ( 粤ICP备16101765号 )

GMT+8, 2021-2-27 17:24 , Processed in 0.108366 second(s), 58 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

返回顶部