controls

int ctl_val(snd_ctl_t * handle, const char *elem_name, const int *elem_value)
{
    snd_ctl_elem_info_t *info;
    snd_ctl_elem_id_t *id;
    snd_ctl_elem_value_t *value;
    snd_ctl_elem_list_t *list;
    snd_ctl_elem_type_t type;
    unsigned int count, used, idx, info_count;
    int err;
    long tmp;
    long long tmp64;
	unsigned char need_set_val=0;

    snd_ctl_elem_info_alloca(&info);
    snd_ctl_elem_id_alloca(&id);
    snd_ctl_elem_value_alloca(&value);
    snd_ctl_elem_list_alloca(&list);
#if 1
    err = snd_ctl_elem_list(handle, list);
    if (err < 0) {
        printf("%s(), L%d  err: %s\n", __FUNCTION__, __LINE__, snd_strerror(err));
        return err;
    }

    count = snd_ctl_elem_list_get_count(list);
    used = snd_ctl_elem_list_get_used(list);
	//printf("%s(), L%d  count: %d, used:%d\n", __FUNCTION__, __LINE__, count, used);
    while(count != used) {
        err = snd_ctl_elem_list_alloc_space(list, count);
        if (err < 0) {
            printf("%s(), L%d  err: %s\n", __FUNCTION__, __LINE__, snd_strerror(err));
            return err;
        }
        err = snd_ctl_elem_list(handle, list);
        if (err < 0) {
            printf("%s(), L%d  err: %s\n", __FUNCTION__, __LINE__, snd_strerror(err));
            return err;
        }
        used = snd_ctl_elem_list_get_used(list);
    }
	///printf("%s(), L%d  count: %d, used:%d\n", __FUNCTION__, __LINE__, count, used);
    for (idx = 0; idx < used; idx++) {
        if (!strcmp(snd_ctl_elem_list_get_name(list, idx), elem_name))
            break;
    }
    
    if (idx >= used) {
        printf("%s(), L%d  idx: %d, used:%d\n", __FUNCTION__, __LINE__, idx, used);
        return -1;
    }

    snd_ctl_elem_list_get_id(list, idx, id);
#endif
	/*设置并检查id*/
	/*err = snd_ctl_ascii_elem_id_parse(id, elem_name);
	if (err < 0) {
		printf("%s(), L%d  err: %s\n", __FUNCTION__, __LINE__, snd_strerror(err));
	}*/

    snd_ctl_elem_info_set_id(info, id);
    err = snd_ctl_elem_info(handle, info);
    if (err < 0) {
        printf("%s(), L%d  err: %s\n", __FUNCTION__, __LINE__, snd_strerror(err));
        return err;
    }
    
    snd_ctl_elem_info_get_id(info, id);
    snd_ctl_elem_value_set_id(value, id);

    err = snd_ctl_elem_read(handle, value);
    if (err < 0) {
        printf("%s(), L%d  err: %s\n", __FUNCTION__, __LINE__, snd_strerror(err));
        return err;
    }

    type = snd_ctl_elem_info_get_type(info);
    info_count = snd_ctl_elem_info_get_count(info);
    for (idx = 0; idx < info_count && idx < 128; idx++) {
        switch(type) {
            case SND_CTL_ELEM_TYPE_BOOLEAN:
                tmp = snd_ctl_elem_value_get_boolean(value, idx);
                //printf("%s(), L%d  %s idx:%d, tmp:%ld, elem_value:%ld\n", __FUNCTION__, __LINE__, elem_name, idx, tmp, elem_value[idx]);
                if (tmp != elem_value[idx])
				{
					need_set_val = 1;
					snd_ctl_elem_value_set_boolean(value, idx, elem_value[idx]);
				}        
                break;
            case SND_CTL_ELEM_TYPE_INTEGER:
                tmp = snd_ctl_elem_value_get_integer(value, idx);
                printf("%s(), L%d  %s idx:%d, tmp:%ld, elem_value:%ld\n", __FUNCTION__, __LINE__, elem_name, idx, tmp, elem_value[idx]);
                if (tmp != elem_value[idx])
				{
					need_set_val = 1;
                    snd_ctl_elem_value_set_integer(value, idx, elem_value[idx]);
				}
                break;
            case SND_CTL_ELEM_TYPE_INTEGER64:
                tmp64 = snd_ctl_elem_value_get_integer64(value, idx);
                printf("%s(), L%d  %s idx:%d, tmp64:%lld\n", __FUNCTION__, __LINE__, elem_name, idx, tmp64);
                if (tmp != elem_value[idx])
				{
					need_set_val = 1;
                    snd_ctl_elem_value_set_integer64(value, idx, elem_value[idx]);
				}
                break;
            case SND_CTL_ELEM_TYPE_ENUMERATED:
                tmp = snd_ctl_elem_value_get_enumerated(value, idx);
                printf("%s(), L%d  %s idx:%d, tmp:%ld\n", __FUNCTION__, __LINE__, elem_name, idx, tmp);
                if (tmp != elem_value[idx])
				{
					need_set_val = 1;
                    snd_ctl_elem_value_set_enumerated(value, idx, elem_value[idx]);
				}
                break;
            case SND_CTL_ELEM_TYPE_BYTES:
                tmp = snd_ctl_elem_value_get_byte(value, idx);
                //tmp = snd_ctl_elem_value_get_bytes(value);
                printf("%s(), L%d  %s idx:%d, tmp:%ld\n", __FUNCTION__, __LINE__, elem_name, idx, tmp);
                if (tmp != elem_value[idx])
				{
					need_set_val = 1;
                    snd_ctl_elem_set_bytes(value, &elem_value, sizeof(elem_value));
				}
                break;
            default:
                break;
        }
    }
    
    if (need_set_val) {
        err = snd_ctl_elem_write(handle, value);
        if (err < 0) {
            printf("%s(), L%d  err: %s\n", __FUNCTION__, __LINE__, snd_strerror(err));
            return err;
        }
    }
    snd_ctl_elem_list_free_space(list);
    
    return 0;
}

int set_controls_by_lib(const struct config_control *ctls, unsigned controls_count)
{
	unsigned char i;
	int err;
	snd_ctl_t * handle;

	err = snd_ctl_open(&handle, "hw:0", 0);
    if (err < 0) {
        printf("%s(), L%d  err: %s\n", __FUNCTION__, __LINE__, snd_strerror(err));
        return err;
    }
    
	//hw:0 "Master Playback Volume" 50
	for (i = 0; i < controls_count; i++) {
		ctl_val(handle, ctls[i].ctl_name, ctls[i].int_val);
	}

	snd_ctl_close(handle);
    return 0;
}

参考

https://www.cnblogs.com/fellow1988/p/12404645.html
https://blog.csdn.net/oyoung_2012/article/details/79664491