概述
基于adk_r00201.1版本。
相关源文件为 audio_curation.c 和 audio_curation.h,所在目录是adksrcservicesaudio_curation。audio_curation关注的为两个目标,一个是AEC(即leakthrough,高通的声音透传功能),另一个是ANC(高能的主动降噪方案)。相关的动作有打开/关闭,和打开与关闭间的轮流切换,模式包含:anc打开和关闭,aec打开和关闭,anc tuning模式。该部分源码就是围绕着这几个功能的状态来工作。
- audio_curation.h
该文件内容不多,只定义了两个枚举类型:
/*! brief Messages sent by the audio curation component to clients. */
enum audio_curation_messages
{
AUDIO_CURATION_ANC_ON = AUDIO_CURATION_SERVICE_MESSAGE_BASE,
AUDIO_CURATION_ANC_OFF,
AUDIO_CURATION_ANC_MODE_CHANGED,
AUDIO_CURATION_AANC_ED_INACTIVE,
AUDIO_CURATION_AANC_ED_ACTIVE,
AUDIO_CURATION_AANC_QUIET_MODE_ON,
AUDIO_CURATION_AANC_QUIET_MODE_OFF,
AUDIO_CURATION_AANC_CLEAR_EVENT
};
该结构定义了和audio curation中ANC相关的事件(Events),比如打开ANC时触发一个AUDIO_CURATION_ANC_ON事件,关闭时触发一个AUDIO_CURATION_ANC_OFF事件。这些事件该版本中仅用来产生一些Tone或Prompts或者LED的指示,用来给用户一些反馈或提示。
/*@{*/
/*! brief Audio Curation UI Provider contexts */
typedef enum
{
context_anc_disabled,
context_anc_enabled,
context_anc_tuning_mode_active,
context_leakthrough_disabled,
context_leakthrough_enabled,
} audio_curation_provider_context_t;
该结构定义了audio curatoin中用来表征anc和aec各自的状态,在UI的定义中会用到这个定义,表示在该状态下要触发什么运作等。
- audio_curation.c
文件中只有一个全局函数(非Static修饰):bool AudioCuration_Init(Task init_task),作用是注册该消息组UI相关操作到各其它管理模块中,如电源管理,ANC管理,Kymera管理,UI管理,以便在相关即用来解释并执行该部分相关的UI定义;所有与audio curation相关的UI消息均定义在ui_provider_audio_curation下面。
- 那么系统是如何调用到该模块的UI消息处理函数的呢?
看该源文件上面部分的定义:
static const TaskData ui_task = {audioCuration_HandleMessage};
该行代码创建了一个系统任务,所有和audio curation相关联的消息都会进入到该任务处理函数,函数原型为:
static void audioCuration_HandleMessage(Task task, MessageId id, Message message);
- 那什么是任务?
任务其实就是一个指定格式的函数,它的定义是:
typedef struct TaskData { void (*handler)(Task, MessageId, Message);} TaskData;
同时ADK还为该TaskData定义了一个指针类型的别名:Task,其定义为:
typedef struct TaskData *Task;
可以看出Task和TaskData是同一个东西。
之所以再定义一个Task,笔者猜想有两个原因:一个是Task看起来更像是对任务的描述,二是使用起来更方便,因为它本身就修饰指针类型的。
所以audio curation 的UI Task就是这个audioCuration_HandleMessage函数。
文件中还定义了一个链表:client_list,它其实是多个Task类型的一个链表,用来关联所有和该curation相关的Task到上面。它的具体动作机制笔者目前还没研究清楚,有待后续更新。
所以,该.c文件的功能就是用来处理不同消息组传递过来与自己相关消息的事件,其消息总接口为:
audioCuration_HandleMessage (Task task, MessageId id, Message message);
函数依据消息的模块来源再分发到内部对应模块消息的处理函数中,比如分配到ANC相关的消息处理单元,或AEC相关的消息处理单元; 其中参数id中隐藏着消息的模块来源,该id值为一个uint16数值,bit15~7用来表征消息组或叫模块的出处,bit6~0用来表征对应消息组的组内消息定义,所以可以得知组个消息组最多可以定义2^6=64个消息,一共可以有2^10=1024个消息组。
- 消息组又是在哪里定义的呢?
文件中定义一自己负责的消息组:UI_INPUTS_AUDIO_CURATION_MESSAGE_GROUP,用代码索引的话你是找不到它在哪里定义的,这和ADK函数的实现方式有关,ADK中采用的大量的宏定义及字符拼接,所以很多消息的定义都是索引不到的。
其实该消息的原始名称为 UI_INPUTS_AUDIO_CURATION,后面的<_MESSAGE_GROUP>是用宏定义拼接上去的,所有的消息组的后缀都是MESSAGE_GROUP,它定义在文件domain_message.h中,所有消息组全都定义在枚举类型enum message_groups中。
源码可以看出,该 枚举包含了五大类,每个类为一相系列相似功能的消息组,然后依次顺序排列。分析可以知道,值为0的消息组为 INTERNAL_MESSAGE_GROUP,它定义在FOREACH_DOMAINS_MESSAGE_GROUP这一类中。而最后一个消息组为FOREACH_UI_INPUTS_MESSAGE_GROUP类中的UI_INPUTS_BOUNDS_CHECK_MESSAGE_GROUP,具体值 是多少就不去数了。
- ANC与AEC
研究发现ANC与AEC是功能互斥的,实际使用时只能二选一;ANC其实是包含AEC的,所以全能ANC更合适一些。
最后
以上就是老迟到中心为你收集整理的audio_curation分析及系统消息的定义方式的全部内容,希望文章能够帮你解决audio_curation分析及系统消息的定义方式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复