[Linux Audio Driver] ACDB文件加载流程(一)

声卡信息是acdb加载中最重要的信息,本文追踪代码,解释声卡名如何被取出来使用的;

环境: Qualcomm平台,android7 , 内核版本:msm-3.18

1. platform_init函数

代码路径:
hardware/qcom/audio/hal/msm8916/platform.c

void *platform_init(struct audio_device *adev)

   ->snd_card_name = mixer_get_name(adev->mixer);

今天就只聊这句代码:

snd_card_name = mixer_get_name(adev->mixer);

2. 说正事前,扯点别的(凑点字数。。。。)

[Linux Audio Driver] ACDB文件加载流程(一)_第1张图片

首先这个函数的定义就很有意思: void *platform_init(struct audio_device *adev) ,void *的意思是返回任意类型的指针;

其次,platform_init函数里面有很有意思几句代码:

property_get(“persist.audio.fluence.voicerec”,value,"");
if (!strncmp(“true”, value, sizeof(“true”))) {
my_data->fluence_in_voice_rec = true;
}

指针my_data是指向 platform_data 结构体;

struct platform_data *my_data = NULL;

struct platform_data {
    struct audio_device *adev;
    bool fluence_in_spkr_mode;
    bool fluence_in_voice_call;
    bool fluence_in_voice_rec;
    bool fluence_in_audio_rec;
    bool external_spk_1;
    bool external_spk_2;
    bool external_mic;
    int  fluence_type;
    int  fluence_mode;
   ...
}

结构里面的这些布尔变量,与平台对应的.mk对应,编译后会生成build.prop文件;

persist.audio.fluence.voicerec等各种系统属性的true 、false值,对应相应XML文件里面不同的单、双麦配置;

同时也对应相应的acdb(音频数据库),不同voice、audio应用场景下的 acdb id (不同的单、双麦算法),这个会影响负责tuning的同事;

3. mixer_get_name函数

snd_card_name = mixer_get_name(adev->mixer); //  此函数获取声卡名

我发现这个mixer_get_name这个函数很嚣张,我特么找了半天没找到函数原型定义在哪里,

[Linux Audio Driver] ACDB文件加载流程(一)_第2张图片

后来发现是定义在external目录下面 ,编译成静态库被使用的。(static library)

[Linux Audio Driver] ACDB文件加载流程(一)_第3张图片

const char *mixer_get_name(struct mixer *mixer)
{
    return (const char *)mixer->card_info.name;
}

返回 const char *的指针,

4. 下面就是获取声卡,各个结构体的调用框架:

4.1 结构体调用总结:

struct audio_device *adev
          ->struct mixer *mixer;
               ->struct snd_ctl_card_info card_info
                     -> unsigned char name[32];    

4.2 各个结构体以及代码路径

代码路径: hardware/qcom/audio/hal/audio_hw.h

struct audio_device {
    struct audio_hw_device device;
    pthread_mutex_t lock; /* see note below on mutex acquisition order */
    struct mixer *mixer;
    ......
};

./external/tinyalsa/mixer.c

struct mixer {
    int fd;
    struct snd_ctl_card_info card_info;
    struct snd_ctl_elem_info *elem_info;
    struct mixer_ctl *ctl;
    unsigned int count;
};

./external/kernel-headers/original/uapi/sound/asound.h

  struct snd_ctl_card_info {
     int card;           /* card number */
      int pad;            /* reserved for future (was type) */
      unsigned char id[16];       /* ID of card (user selectable) */
      unsigned char driver[16];   /* Driver name */
      unsigned char name[32];     /* Short name of soundcard */
      unsigned char longname[80]; /* name + info text about soundcard */
      unsigned char reserved_[16];    /* reserved for future (was ID of mixer) */
      unsigned char mixername[80];    /* visual mixer identification */
      unsigned char components[128];  
  };

OK,我们可以看到声卡名是从这个结构体里面拿出来的;至于声卡信息怎么存进去的,那又是一个愉(bei)快( shang)的故事了。

OVER

有时间继续分析,下篇再见…

你可能感兴趣的:(Qualcomm,Audio)