audio control控制接口

audio control控制接口,第1张

control的主要用于mixer。它能被用户空间存取,从而读写CODEC相关寄存器,可以控制amix指令,它用snd_kcontrol_new结构体描述

相关结构体

struct snd_kcontrol_new {

    snd_ctl_elem_iface_t iface;    /* interface identifier */

    unsigned int device;        /* device/client number */

    unsigned int subdevice;        /* subdevice (substream) number */

    const unsigned char *name;    /* ASCII name of item */

    unsigned int index;        /* index of item */

    unsigned int access;        /* access rights */

    unsigned int count;        /* count of same elements */

    snd_kcontrol_info_t *info;

    snd_kcontrol_get_t *get;

    snd_kcontrol_put_t *put;

    union {

        snd_kcontrol_tlv_rw_t *c;

        const unsigned int *p;

    } tlv;

    unsigned long private_value;

};

iface字段指出了control的类型,alsa定义了几种类型(SNDDRV_CTL_ELEM_IFACE_XXX),常用的类型是MIXER,当然也可以定义属于全局的CARD类型,也可以定义属于某类设备的类型,

#define    SNDRV_CTL_ELEM_IFACE_CARD    ((__force snd_ctl_elem_iface_t) 0) /* global control */

#define    SNDRV_CTL_ELEM_IFACE_HWDEP    ((__force snd_ctl_elem_iface_t) 1) /* hardware dependent device */

#define    SNDRV_CTL_ELEM_IFACE_MIXER    ((__force snd_ctl_elem_iface_t) 2) /* virtual mixer device */

#define    SNDRV_CTL_ELEM_IFACE_PCM    ((__force snd_ctl_elem_iface_t) 3) /* PCM device */

#define    SNDRV_CTL_ELEM_IFACE_RAWMIDI    ((__force snd_ctl_elem_iface_t) 4) /* RawMidi device */

#define    SNDRV_CTL_ELEM_IFACE_TIMER    ((__force snd_ctl_elem_iface_t) 5) /* timer device */

#define    SNDRV_CTL_ELEM_IFACE_SEQUENCER    ((__force snd_ctl_elem_iface_t) 6) /* sequencer client */

#define    SNDRV_CTL_ELEM_IFACE_LAST    SNDRV_CTL_ELEM_IFACE_SEQUENCER

name字段是该control的名字,从ALSA 0.9.x开始,control的名字是变得比较重要,因为control的作用是按名字来归类的。ALSA已经预定义了一些control的名字,我们再Control Name一节详细讨论。

control的名字需要遵循一些标准,通常可以分成3部分来定义control的名字:源--方向--功能。

源,可以理解为该control的输入端,alsa已经预定义了一些常用的源,例如:Master,PCM,CD,Line等等。

方向,代表该control的数据流向,例如:Playback,Capture,Bypass,Bypass Capture等等,也可以不定义方向,这时表示该Control是双向的(playback和capture)。

功能,根据control的功能,可以是以下字符串:Switch,Volume,Route等等

index字段用于保存该control的在该卡中的编号。如果声卡中有不止一个codec,每个codec中有相同名字的control,这时我们可以通过index来区分这些controls。当index为0时,则可以忽略这种区分策略。

access字段包含了该control的访问类型。每一个bit代表一种访问类型,这些访问类型可以多个“或”运算组合在一起。

Access字段是一个bitmask,它保存了改control的访问类型。默认的访问类型是:SNDDRV_CTL_ELEM_ACCESS_READWRITE,表明该control支持读和写 *** 作。如果access字段没有定义(.access==0),此时也认为是READWRITE类型。

如果是一个只读control,access应该设置为:SNDDRV_CTL_ELEM_ACCESS_READ,这时,我们不必定义put回调函数。类似地,如果是只写control,access应该设置为:SNDDRV_CTL_ELEM_ACCESS_WRITE,这时,我们不必定义get回调函数。

如果control的值会频繁地改变(例如:电平表),我们可以使用VOLATILE类型,这意味着该control会在没有通知的情况下改变,应用程序应该定时地查询该control的值。

#define SNDRV_CTL_ELEM_ACCESS_READ        (1<<0)

#define SNDRV_CTL_ELEM_ACCESS_WRITE        (1<<1)

#define SNDRV_CTL_ELEM_ACCESS_READWRITE        (SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE)

#define SNDRV_CTL_ELEM_ACCESS_VOLATILE        (1<<2)    /* control value may be changed without a notification */

#define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP        (1<<3)    /* when was control changed */

#define SNDRV_CTL_ELEM_ACCESS_TLV_READ        (1<<4)    /* TLV read is possible */

#define SNDRV_CTL_ELEM_ACCESS_TLV_WRITE        (1<<5)    /* TLV write is possible */

#define SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE    (SNDRV_CTL_ELEM_ACCESS_TLV_READ|SNDRV_CTL_ELEM_ACCESS_TLV_WRITE)

#define SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND    (1<<6)    /* TLV command is possible */

#define SNDRV_CTL_ELEM_ACCESS_INACTIVE        (1<<8)    /* control does actually nothing, but may be updated */

#define SNDRV_CTL_ELEM_ACCESS_LOCK        (1<<9)    /* write lock */

#define SNDRV_CTL_ELEM_ACCESS_OWNER        (1<<10)    /* write lock owner */

#define SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK    (1<<28)    /* kernel use a TLV callback */

#define SNDRV_CTL_ELEM_ACCESS_USER        (1<<29) /* user space element */

private_value字段包含了一个任意的长整数类型值。该值可以通过info,get,put这几个回调函数访问。你可以自己决定如何使用该字段,例如可以把它拆分成多个位域,又或者是一个指针,指向某一个数据结构。

tlv字段为该control提供元数据

    .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\

    .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\

         SNDRV_CTL_ELEM_ACCESS_READWRITE,\

    .tlv.p = (tlv_array), \

    .info = snd_soc_info_volsw, \

    .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \

    .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \

                        xmax, xinvert) }

/*

* DAC digital volumes. From -63.5 to 0 dB in 0.5 dB steps

*/

static DECLARE_TLV_DB_SCALE(dac_tlv, -6350, 50, 0);

相关的回调函数

info回调函数用于获取control的详细信息。

get回调函数用于读取control的当前值,并返回给用户空间的应用程序。

put回调函数用于把应用程序的控制值设置到control中。

元数据

这里指的是.tlv.p = (tlv_array), 也就是如下函数

DECLARE_TLV_DB_SCALE宏定义的mixer control,它所代表的值按一个固定的dB值的步长变化。该宏的第一个参数是要定义变量的名字,第二个参数是最小值,以0.01dB为单位。第三个参数是变化的步长

DECLARE_TLV_DB_LINEAR宏定义的mixer control,它的输出随值的变化而线性变化。 该宏的第一个参数是要定义变量的名字,第二个参数是最小值,以0.01dB为单位。第二个参数是最大值

#define TLV_DB_SCALE_MASK    0xffff

#define TLV_DB_SCALE_MUTE    0x10000

#define TLV_DB_SCALE_ITEM(min, step, mute)            \

    TLV_ITEM(SNDRV_CTL_TLVT_DB_SCALE,            \

         (min),                    \

         ((step) & TLV_DB_SCALE_MASK) |        \

            ((mute) ? TLV_DB_SCALE_MUTE : 0))

#define DECLARE_TLV_DB_SCALE(name, min, step, mute) \

    unsigned int name[] = { TLV_DB_SCALE_ITEM(min, step, mute) }

/* linear volume between min_dB and max_dB (.01dB unit) */

#define TLV_DB_LINEAR_ITEM(min_dB, max_dB)            \

    TLV_ITEM(SNDRV_CTL_TLVT_DB_LINEAR, (min_dB), (max_dB))

#define DECLARE_TLV_DB_LINEAR(name, min_dB, max_dB)    \

    unsigned int name[] = { TLV_DB_LINEAR_ITEM(min_dB, max_dB) }

代码调用

snd_soc_init

 --》platform_driver_register

        --》soc_probe

               --》snd_soc_register_card

                     --》snd_soc_instantiate_card  

                         --》snd_card_new                         create and initialize a soundcard structure

                               --》 snd_ctl_create                  create control core:

                                      --》snd_soc_add_card_controls   add an array of controls to a SoC card.

                                            --》snd_soc_add_controls     

                                                   --》 snd_soc_cnew

                                                        --》snd_ctl_new1            create a control instance from the template

                                                   --》 snd_ctl_add                  add the control instance to the card

snd_soc_add_platform_controls          Add an array of controls to a component.

 --》snd_soc_add_controls     

        --》 snd_soc_cnew

                --》snd_ctl_new1            create a control instance from the template

                      --》 snd_ctl_add                  add the control instance to the card

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1330938.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-12
下一篇 2022-06-12

发表评论

登录后才能评论

评论列表(0条)

保存