现在的位置: 首页 > 综合 > 正文

ALSA driver(Control)

2013年10月09日 ⁄ 综合 ⁄ 共 3525字 ⁄ 字号 评论关闭

如何增加一个ALSA 控制接口:

static struct snd_kcontrol_new wm8976_output_volume_control = {

.iface = SNDRV_CTL_ELEM_IFACE_MIXER,

.name = "Output Volume",

.info = wm8976_ctl_integer_output_volume_info,

.get = wm8976_output_volume_get,

.put = wm8976_output_volume_put,

};

 

/* global output volume param */

int wm8976_ctl_integer_output_volume_info(struct snd_kcontrol *kcontrol,

     struct snd_ctl_elem_info *uinfo)

{

    uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;

    uinfo->count = 1;

    uinfo->value.integer.min = 0;

    uinfo->value.integer.max = 100;

    return 0;

}

 

/*  增加一个控制接口 */

err = snd_ctl_add(codec->card,

snd_soc_cnew(&wm8976_output_volume_control, codec, NULL));

 

android/libaudio

--------------------------------------------------------------------------------------------

int setVolumeItem(const char *elem_name, int volume)

{

int err = 0;

int orig_volume = 0;

snd_ctl_t *handle = NULL;

snd_ctl_elem_info_t *info;

snd_ctl_elem_id_t *id;

snd_ctl_elem_value_t *control;

snd_ctl_elem_type_t type;

int count;

snd_ctl_elem_info_alloca(&info);

snd_ctl_elem_id_alloca(&id);

snd_ctl_elem_value_alloca(&control);

snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);/* default */

snd_ctl_elem_id_set_name(id, elem_name);

// snd_ctl_elem_id_set_index(id, 1);  // does not have index.

if ((err = snd_ctl_open(&handle, sControlDevice, 0)) < 0) {

LOGE("Error: snd_ctl_open error: %s", snd_strerror(err));

return err;

snd_ctl_elem_info_set_id(info, id);

if ((err = snd_ctl_elem_info(handle, info)) < 0) {

LOGE("Error: snd_ctl_elem_info volume error: %s", snd_strerror(err));

snd_ctl_close(handle);

handle = NULL;

return err;

}

type = snd_ctl_elem_info_get_type(info);

count = snd_ctl_elem_info_get_count(info);

/* SNDRV_CTL_ELEM_TYPE_INTEGER驱动层的定义 */

if ((type != SND_CTL_ELEM_TYPE_INTEGER) || (1 != count)) {

LOGE("Error: snd_ctl_elem_info volume type should be INTEGER and count should be 1: type:%d, count:%d", type, count);

snd_ctl_close(handle);

handle = NULL;

return err;

}

snd_ctl_elem_value_set_id(control, id);

if (!snd_ctl_elem_read(handle, control)) {

orig_volume = snd_ctl_elem_value_get_integer(control, 0);

}

//if (volume != orig_volume) {

snd_ctl_elem_value_set_integer(control, 0, volume);

if ((err = snd_ctl_elem_write(handle, control)) < 0) {

LOGE("Error: snd_ctl_elem_write set volume error: %s", snd_strerror(err));

snd_ctl_close(handle);

handle = NULL;

return err;

}

//} 

snd_ctl_close(handle);

handle = NULL;

return err;

}

 

int getVolumeItem(const char *elem_name)

{

int err = 0;

int volume = 0;

snd_ctl_t *handle = NULL;

snd_ctl_elem_info_t *info;

snd_ctl_elem_id_t *id;

snd_ctl_elem_value_t *control;

snd_ctl_elem_type_t type;

int count;

snd_ctl_elem_info_alloca(&info);

snd_ctl_elem_id_alloca(&id);

snd_ctl_elem_value_alloca(&control);

snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);/* default */

snd_ctl_elem_id_set_name(id, elem_name);

// snd_ctl_elem_id_set_index(id, 1);  // does not have index.

if ((err = snd_ctl_open(&handle, sControlDevice, 0)) < 0) {

LOGE("Error: snd_ctl_open error: %s", snd_strerror(err));

return err;

snd_ctl_elem_info_set_id(info, id);

if ((err = snd_ctl_elem_info(handle, info)) < 0) {

LOGE("Error: snd_ctl_elem_info volume error: %s", snd_strerror(err));

snd_ctl_close(handle);

handle = NULL;

return err;

}

type = snd_ctl_elem_info_get_type(info);

count = snd_ctl_elem_info_get_count(info);

if ((type != SND_CTL_ELEM_TYPE_INTEGER) || (1 != count)) {

LOGE("Error: snd_ctl_elem_info volume type should be INTEGER and count should be 1: type:%d, count:%d", type, count);

snd_ctl_close(handle);

handle = NULL;

return err;

}

snd_ctl_elem_value_set_id(control, id);

if ((err = snd_ctl_elem_read(handle, control)) < 0) {

LOGE("Error: snd_ctl_elem_read get volume error: %s", snd_strerror(err));

snd_ctl_close(handle);

handle = NULL;

return err;

}    

    volume = snd_ctl_elem_value_get_integer(control, 0);

 

snd_ctl_close(handle);

handle = NULL;

return volume;

}

【上篇】
【下篇】

抱歉!评论已关闭.