Android/Linux/音频/驱动
全部博文(41)
分类: Android平台
2016-10-13 07:27:16
【Parameter-Framework是什么】
Parameter-Framework 是一种基于插件(plugin-based)和既定规则(rule-based)的,用于处理各种parameter的框架。它在运行Android系统的Intel架构设备上(例如智能手机、平板电脑)被广泛使用。它采用pfw语言进行记录并保存在后缀为“.pfw”的文件中,再通过特定的转换规则被转换成XML格式的文件,描述系统的结构和各个参数(parameters)。
【Parameter-Framework的用处】
可以用Parameter-Framework基于既定的规则来为智能手机或平板电脑等设备的各个硬件控制部件(这些控制部件可被视为 parameters)设定合适的值。举个例子,为设备的不同的音频应用场景(播放音乐、打电话、QQ语音等)分别采取合适的音频参数设置,这个过程通常被称为 “audio tuning”,就可以采用 Parameter-Framework 来实现。
【Parameter-Framework的文件组织结构】
Parameter-Framework文件的目录结构类似于下图:
最顶层的配置文件的文件名应该以 .in 后缀结尾(比如,ParameterFrameworkConfiguration.xml.in)。如下图:
有2个makefile文件很重要,它们的概念有相似之处可能引起混淆,简单介绍以示区别:
1、device.mk
这个文件中列出了所有必须被引用的meta-package
2、AndroidBoard.mk
这个文件中定义了上述的这些meta-package
【Parameter-Framework的XML格式文件生成规则】
下面的代码是一个示例:
include $(CLEAR_VARS)
LOCAL_MODULE := AudioConfigurableDomains-bytcr-rt5640-default.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Audio
include $(CLEAR_PFW_VARS)
# Refresh tunning + routing domain file for rt5640-default
LOCAL_REQUIRED_MODULES := \
parameter-framework.audio.common \
parameter-framework.audio.baytrail \
ParameterFrameworkConfiguration-bytcr-rt5640-default.xml \
AudioClass-bytcr-rt5640-default.xml \
CodecSubsystem-bytcr-rt564x-common.xml \
CodecSubsystem-bytcr-rt5640-default.xml \
SstSubsystem-bytcr-rt5640-default.xml \
SstSubsystem-bytcr-rt56xx-common.xml \
PFW_TOPLEVEL_FILE := $(TARGET_OUT_ETC)/parameter-framework/ParameterFrameworkConfiguration-bytcr-rt5640-default.xml
PFW_CRITERIA_FILE := $(COMMON_PFW_CONFIG_PATH)/AudioCriteria.txt
PFW_TUNING_FILE := $(LOCAL_PATH)/Settings/Audio/AudioConfigurableDomains-bytcr-rt5640-default.Tuning.xml
PFW_EDD_FILES := \
$(PLATFORM_PFW_CONFIG_PATH)/Settings/Audio/routing_scalpe_common.pfw \
$(LOCAL_PATH)/Settings/Audio/bytcr-rt5640-default.pfw
PFW_COPYBACK := Settings/Audio/$(LOCAL_MODULE)
include $(BUILD_PFW_SETTINGS)
名称带有PFW_前缀的变量很重要,简单说明一下:
在使用任何以PFW_开头的变量以前, 你必须调用include $(CLEAR_PFW_VARS)来清除之前的参数设定。在这之后,再调用include $(BUILD_PFW_SETTINGS)就可以触发XML文件的生成过程了。这2个变量在文件AndroidBoard.mk中被定义。
【PFW在Android Audio中的运用】
在使用 Intel 平台的 Android系统中,音频链路的设置使用了PFW来完成。既然上文中说到PFW是对parameters进行设置,那么我们在编写 PFW文件之前应该先准备好被控制的对象——parameters,它们实际上是Codec芯片中的各个Mixer。
如果在你的设备上音频模块使用了tinyalsa,那么可以在adb登录到shell后使用命令tinymix -D 1查看声卡上的所有Mixer。
通常这些Mixer信息由Codec的芯片制造商以XML文件的形式给出,在文件中被称作Component。这个XML文件通常会以Codec芯片型号来命名,比如叫Realtek5677Subsystem.xml。文件内容大体格式分为子系统声明(Subsystem)、Component声明(Component Library)和Component引用(Instance Definition)3部分,如下:
在Component声明(Component Library)中,使用
如果parameters中的Mapping属性是Amend类型,那么它的值可以用于替换前文中的 %1、%2 等变量。如下图中的 'Algo%1 Param1' 最终会被替换成 'Algo1 Param1' 或者 'Algo2 Param1':
Component声明中的
我们最后再来看一个综合了以上所有特性的Component声明的例子。如下图中的写法,我们将会声明6个Mixer Control,分别是:
Control:'SpeakerPhone Digital Switch'
Control:'SpeakerPhone Digital Volume'
Control:'LineOut Analog Switch'
Control:'LineOut Analog Volume'
Control:'HeadPhone Analog Switch'
Control:'HeadPhone Analog Volume'
经过上述各部分的定义,它们在 PFW 文件中对应的元素,即被控制的 parameters 就可以生成了。如下:
/Audio/MYCODEC/SOUND_CARD/MIXER/PARAM1[IntegerParameter] name='Mixer param1'
/Audio/MYCODEC/SOUND_CARD/MIXER/PARAM2[BooleanParameter] name='Mixer param2'
/Audio/MYCODEC/SOUND_CARD/EQUALIZER/PARAM1[IntegerParameter] name='Equalizer param1'
/Audio/MYCODEC/SOUND_CARD/EQUALIZER/PARAM2[BooleanParameter] name='Equalizer param2'
/Audio/MYCODEC/SOUND_CARD/ALGO1/PARAM1[IntegerParameter] name='Algo1 param1'
/Audio/MYCODEC/SOUND_CARD/ALGO1/PARAM2[EnumParameter] name='Algo1 param2'
/Audio/MYCODEC/SOUND_CARD/ALGO2/PARAM1[IntegerParameter] name='Algo2 param1'
/Audio/MYCODEC/SOUND_CARD/ALGO2/PARAM2[EnumParameter] name='Algo2 param2'
/Audio/MYCODEC/SOUND_CARD/OUTPUTS/SPEAKERPHONE/VOLUME[IntegerParameter] name='Speakerphone Digital Volume'
/Audio/MYCODEC/SOUND_CARD/OUTPUTS/SPEAKERPHONE/SWITCH[IntegerParameter] name='Speakerphone Digital Switch'
/Audio/MYCODEC/SOUND_CARD/OUTPUTS/LINE_OUT/VOLUME[IntegerParameter] name='LineOut Analog Volume'
/Audio/MYCODEC/SOUND_CARD/OUTPUTS/LINE_OUT/SWITCH[IntegerParameter] name='LineOut Analog Switch'
/Audio/MYCODEC/SOUND_CARD/OUTPUTS/HEADPHONE/VOLUME[IntegerParameter] name='Headphone Analog Volume'
/Audio/MYCODEC/SOUND_CARD/OUTPUTS/HEADPHONE/SWITCH[IntegerParameter] name='Headphone Analog Switch'
有了parameters后就可以编写 PFW文件对其进行控制了。
我们再来看PFW文件中的内容和格式,如下图可分为 域(supDomain / domainGroup / domain)、配置规则(conf)等,而绿色部分的parameter就是通过上文中XML文件所得到的:
最终 PFW 文件也会被转换成 XML 格式的文件,例如上方这段 PFW 信息会被转换成下方的 XML 内容:
具体分析一下 PFW 文件中的音频链路设定(Audio Route)规则。音频链路设定的过程可以分为3个阶段,分别是 Flow、Path 和 Configure。其中Flow阶段控制是否允许音频数据的输出,Path阶段控制是否打通某条音频链路,Configure阶段对链路上传输的音频格式进行配置。具体到代码中,不管是Routing还是Re-Routing的过程对应的函数也分为这3个大阶段,如下:
而这每个阶段则都是按照使用场景的需求从 PFW 文件中读取相应的 parameter 进行设定,如下:
上方截图展示的是 Flow 阶段的实际代码实现,Path 和 Configure 阶段也是类似的。
PFW 文件中 Flow 阶段的内容如下图,当设备上插入了耳机或带麦克风的耳机,并且设备当前处于通话或播放多媒体的状态时,耳机链路的数据输出开关将被打开,即 /AUDIO/REALTEK/SOUND_CARD/OUTPUT/HEADPHONE/SWITCH 参数的值被设置为 1:
PFW 文件中 Path 阶段的内容如下图,当设备处于通话或播放多媒体的状态时,耳机链路将被选通即 /Audio/REALTEK/SOUND_CARD/MIXER/DIGITAL/DAC_MIXER/STEREO/RIGHT/1/SWITCH 和 /Audio/REALTEK/SOUND_CARD/MIXER/DIGITAL/DAC_MIXER/STEREO/LEFT/1/SWITCH 被设置为 1:
PFW文件中Configure阶段的内容如下图,将Codec芯片中输出的音频数据配置为16位深度、双声道输出、48000Hz采样率:
【实例分析】
上面讲了这么多,都是从意义、语法规则等全局层面来讲解的,可能还是有点抽象。下面从工程中的一个PFW文件里截取一行用于route 控制的语句,再结合上文描述的规则进行具体分析,应该能让大家理解得更清晰。
在文件 device/intel/common/audio/parameter-framework/Settings/Audio/routing_realtek5677.pfw中有下面这条控制语句:
/Audio/REALTEK/SOUND_CARD/MIXER/ANALOG/HPOUT_MIXER/DAC1/SWITCH = 1
这条语句所控制的部件被定义在 parameter-framework/Structure/Audio/Realtek5677Subsystem.xml文件中,所以我们应该到 Realtek5677Subsystem.xml 文件中进查找。
1、首先找SOUND_CARD:
/Audio/REALTEK/SOUND_CARD/MIXER/ANALOG/HPOUT_MIXER/DAC1/SWITCH = 1
对应 Realtek5677Subsystem.xml 文件中的
2、然后根据SOUND_CARD的Type找MIXER:
/Audio/REALTEK/SOUND_CARD/MIXER/ANALOG/HPOUT_MIXER/DAC1/SWITCH = 1
对应 Realtek5677Subsystem.xml 文件中的
3、再根据MIXER的Type找ANALOG:
/Audio/REALTEK/SOUND_CARD/MIXER/ANALOG/HPOUT_MIXER/DAC1/SWITCH = 1
对应 Realtek5677Subsystem.xml 文件中的
4、继续根据ANALOG的Type找HPOUT_MIXER:
/Audio/REALTEK/SOUND_CARD/MIXER/ANALOG/HPOUT_MIXER/DAC1/SWITCH = 1
对应 Realtek5677Subsystem.xml 文件中的
此时要注意HPOUT_MIXER部件的末尾多了一个属性Mapping="Amend1:HPO,Amend2:MIX"。这个Mapping属性就是route参数, Amend1:HPO 的意思就是 %1=HPO,同理 Amend2:MIX 的意思就是 %2=MIX。(如果不理解,跳到第 6 点看看 SWITCH 部件的 Mapping 属性就懂了)
5、继续根据HPOUT_MIXER的Type找DAC1:
/Audio/REALTEK/SOUND_CARD/MIXER/ANALOG/HPOUT_MIXER/DAC1/SWITCH = 1
对应 Realtek5677Subsystem.xml 文件中的
此时也要注意在 DAC1 部件末尾面多了一个属性 Mapping="Amend3:DAC1"。同上,这个 Mapping 也是 route 参数。Amend3:DAC1 就是 %3=DAC1 的意思。
6、最后,根据DAC1的Type找SWITCH:
/Audio/REALTEK/SOUND_CARD/MIXER/ANALOG/HPOUT_MIXER/DAC1/SWITCH = 1
对应 Realtek5677Subsystem.xml 文件中的
这样,示例中的一条控制语句就被完整解析出来了。SWITCH部件的Mapping属性为Mapping="Control:'%1 %2 %3 Switch”,将步骤4、5的解析结果分别替换掉 1% %2 %3 后就得到了:
HPO MIX DAC1 Switch = 1
这等效于我们用下面这条 tinymix 命令来对 route 进行配置:
tinymix 'HPO MIX DAC1 Switch' 1
【参考链接】
[1]
[2]
[3]