android soundrecorder之四 dapm介紹

轉載請標註原文地址: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,20130625
static 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}
};



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章