ALSA学习笔记 (4)Control

1. 如何创建一个control

1.1 定义一个snd_kcontrol_new结构体

static struct snd_kcontrol_new my_control __devinitdata = {
	.face = SNDRV_CTL_ELEM_IFACE_MIXER,
	.name = “PCM Playback Switch”,
	.index = 0,
	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
	.private_value = 0xffff,
	.info = my_control_info,
	.get = my_control_get,
	.put = my_control_put
};

iface 表示control的类型,用SNDRV_CTL_ELEM_IFACE_XXX来定义。例如: CARD, MIXER, PCM等
name 表示control的名字,用户层可以通过这个名字访问这个control
index 存放这个 control 的索引号
access 访问权限的控制,READ,WRITE,READWRITE等
private_value 特定control的私有数据,例如可以存放寄存器地址信息

1.2 回调函数

1.2.1 info 函数

用于得到对应control的详细信息,需要把信息存入snd_ctl_elem_info 对象中。

struct snd_ctl_elem_info {
	struct snd_ctl_elem_id id;	/* W: element ID */
	snd_ctl_elem_type_t type;	/* R: value type - SNDRV_CTL_ELEM_TYPE_* */
	unsigned int access;		/* R: value access (bitmask) - SNDRV_CTL_ELEM_ACCESS_* */
	unsigned int count;		/* count of values */
	__kernel_pid_t owner;		/* owner's PID of this control */
	union {
		struct {
			long min;		/* R: minimum value */
			long max;		/* R: maximum value */
			long step;		/* R: step (0 variable) */
		} integer;
		struct {
			long long min;		/* R: minimum value */
			long long max;		/* R: maximum value */
			long long step;		/* R: step (0 variable) */
		} integer64;
		struct {
			unsigned int items;	/* R: number of items */
			unsigned int item;	/* W: item number */
			char name[64];		/* R: value name */
			__u64 names_ptr;	/* W: names list (ELEM_ADD only) */
			unsigned int names_length;
		} enumerated;
		unsigned char reserved[128];
	} value;
	union {
		unsigned short d[4];		/* dimensions */
		unsigned short *d_ptr;		/* indirect - obsoleted */
	} dimen;
	unsigned char reserved[64-4*sizeof(unsigned short)];
};

其中value的值是一个共用体,根据control的类型,确定值的类型:
包括BOOLEAN,INTEGER,ENUMERATED,BYTES等类型,下面以BOOLEAN和ENUMRATED为例定义info回调函数。

static int snd_myctl_info(struct snd_kcontrol *kcontrol,
							struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
	uinfo->count = 1;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 1;
	return 0;
}

Static int snd_myctl_info(struct snd_kcontrol *kcontrol,
							struct snd_ctl_elem_info *uinfo)
{
	static char *texts[4] ={
		“First”,“Second”,“Third”,“Fourth”
	};

	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMRATED;
	uinfo->count = 1;
	uinfo->value.enumerated.item = 3;
	strcpy(uinfo->value.enumerated.name,texts[uinfo->value.enumerated.item]);

	return 0;
}

1.2.2 get 函数

这个函数用来读取当前 control 的值并返回到用户空间
需要把值放在snd_ctl_elem_value结构体中,与info结构体类似,value字段是一个共用体,与类型相关。
如果value的cont大于1, 需要把值全部放入到 value[]数组中。

static int snd_myctl_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct mychip *chip = snd_kcontrol_chip(kcontrol);
ucontrol->value.integer.value[0] = get_some_value(chip);
return 0;
}

1.2.3 put 函数

主要是从用户空间写一个值

static int snd_myctrl_put(struct snd_kcontrol *kcontrol,
							struct snd_ctl_elem_value *ucontrol)
{
	struct mychip *chip = snd_kcontrol_chip(kcontrol);
	int changed = 0;

	if (chip->current_value != ucontrol->value.integer.value[0]){
		change_current_value(chip,ucontrol->value.integer.value[0]);
		changed = 1;
	}

	return changed;
}

1.3 创建并添加一个 snd_kcontrol

snd_ctl_new1用于分配一个snd_kcontrol实例,把snd_kcontrol_new中的成员赋值给snd_kcontrol实例,另外需要传入private_data 的指针
snd_ctl_add 把给定的 control 组件添加到 card 里面

if ((err = snd_ctl_add(card, snd_ctl_new1(&my_control, chip))) < 0)
	return err;
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值