android soundrecorder之四 dapm介绍

来源:互联网 发布:宝冢96期事件 知乎 编辑:程序博客网 时间:2024/06/05 06:27

转载请标注原文地址:http://blog.csdn.net/uranus_wm/article/details/12855325

 

前三篇文章对录音的大体流程介绍了下

这篇文章讲一下codec内部的dapm配置

dapm的全称:dynamic audio power managment

还是先看张图:

这幅图是codec内部ctrl连接关系的一张示意图,当然实际的codec内部连接更加灵活,这里只是大致列出了其中一些走向关系

所谓dapm其实就是管理配置这些内部控制器,如mixer,muxer,gpa,micbias等,以实现音频通路和音量的切换以及电源管理

在codec probe的时候会向snd_soc注册一些dapm control

其中某些control以:{目标,控制,源}的形式出现

这类control形成了一条简单路径关系,“源”通过“控制”到达“目标”

这个“控制”通常类型是“MIXER”或者“MUXER”

他们通常是多条路径route的控制点

“MIXER”指多输入一输出,多输入可以同时有效

“MUXER”指多输入一输出,只能选择一路输入有效

由此简单路径我们构成一条从mic输入到speaker输出的完整路径

也可以是从mic输入到aif1输出的完整路径,这就是我们录音的dapm route

同时每一个“控制”都会对应其相应的寄存器配置,如下面的SOC_DAPM_SINGLE申明

static int wm8994_codec_probe(struct snd_soc_codec *codec){struct wm8994 *control;struct wm8994_priv *wm8994;struct snd_soc_dapm_context *dapm = &codec->dapm;wm_hubs_add_analogue_controls(codec);snd_soc_add_controls(codec, wm8994_snd_controls,    ARRAY_SIZE(wm8994_snd_controls));snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets, ARRAY_SIZE(wm8994_dapm_widgets));}struct snd_soc_dapm_route {const char *sink;const char *control;const char *source;/* Note: currently only supported for links where source is a supply */int (*connected)(struct snd_soc_dapm_widget *source,struct snd_soc_dapm_widget *sink);};static const struct snd_soc_dapm_route wm8994_lateclk_revd_intercon[] = {{ "DAC1L", NULL, "Late DAC1L Enable PGA" },{ "Late DAC1L Enable PGA", NULL, "DAC1L Mixer" },{ "DAC1R", NULL, "Late DAC1R Enable PGA" },{ "Late DAC1R Enable PGA", NULL, "DAC1R Mixer" },{ "DAC2L", NULL, "Late DAC2L Enable PGA" },{ "Late DAC2L Enable PGA", NULL, "AIF2DAC2L Mixer" },{ "DAC2R", NULL, "Late DAC2R Enable PGA" },{ "Late DAC2R Enable PGA", NULL, "AIF2DAC2R Mixer" },{ "AIF2ADCL", NULL, "Late DAC2L Enable PGA" }, //wangmeng,20130625{ "AIF2ADCR", NULL, "Late DAC2R Enable PGA"} //wangmeng,20130625static const struct snd_soc_dapm_route intercon[] = {{ "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },{ "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },/* DAC2/AIF2 outputs  */{ "AIF2ADCL", NULL, "AIF2DAC2L Mixer" },{ "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" },{ "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },{ "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },{ "AIF2DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },{ "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },{ "AIF2ADCR", NULL, "AIF2DAC2R Mixer" },{ "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" },{ "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },{ "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },{ "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },{ "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },}SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0,  aif2dac2r_mix, ARRAY_SIZE(aif2dac2r_mix)),static const struct snd_kcontrol_new aif2dac2r_mix[] = {SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,5, 1, 0),SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,4, 1, 0),SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,2, 1, 0),SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,1, 1, 0),SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,0, 1, 0),};

上面的代码片段我们可以发现找到这样一条route:

{ "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },{ "Late DAC2R Enable PGA", NULL, "AIF2DAC2R Mixer" },

“AIF1DAC1R”通过“AIF1.1 Switch”到达“AIF2DAC2R Mixer”再通过“NULL”到达“Late DAC2R Enable PGA”

这里“NULL”表示无条件到达,说明其内部是直接相连的

 

下面这段是录音时从main mic输入(IN1LN-IN1LP差分输入)到aif1输出的配置表

实际操作时,通常将“源”省略

const AudioMixer device_input_Main_Mic[] = {#if defined (USES_I2S_AUDIO) || defined (USES_PCM_AUDIO)//Main_MIC(IN1L N_VMID) to MIXIN to ADC to DAC2 Mixer to AIF2(ADCDAT2)//Main_MIC(IN1L N_VMID) to MIXINL    {"IN1L PGA IN1LN Switch", 1}, //OFF,IN1LN    {"IN1L PGA IN1LP Switch", 1}, //VMID,IN1LP    {"IN1L Switch", 1}, //[0..1]:[MUTE..UNMUTE] ,0018h:b7    {"IN1L Volume", 12}, //[1..31]:[-16.5db..+30db],0018h    {"MIXINL IN1L Switch", 1},    {"MIXINL IN1L Volume",1}, //[0..1]:[0db..+30db]],0029h/*ADCL to AIF1ADC*/    {"ADCL Mux", 0}, //ADC,DMIC    {"AIF1ADCL Source", 0}, //Left,Right    {"AIF1ADCR Source", 0}, //Left,Right    {"AIF1ADC1 Volume", 119}, //[0,1..119]:[MUTE,-71.625db..+17.625db],0400h_0401h default:C0 eq 0db    {"AIF1ADC1L DRC Switch",1},    {"AIF1ADC1R DRC Switch",1},    {"AIF1ADC1L Mixer ADC/DMIC Switch",1},    {"AIF1ADC1R Mixer ADC/DMIC Switch",1},#elif defined(USES_SPDIF_AUDIO)#endif    {NULL, NULL}};