⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 state.c

📁 alsa-utils-1.0.14编译声卡驱动所需要的一些文件源码
💻 C
📖 第 1 页 / 共 3 页
字号:
			return -EINVAL;		}	}	err = snd_config_compound_add(control, "value", 1, &value);	if (err < 0) {		error("snd_config_compound_add: %s", snd_strerror(err));		return err;	}	switch (type) {	case SND_CTL_ELEM_TYPE_BOOLEAN:		for (idx = 0; idx < count; idx++) {			err = snd_config_string_add(value, num_str(idx), snd_ctl_elem_value_get_boolean(ctl, idx) ? "true" : "false");			if (err < 0) {				error("snd_config_string_add: %s", snd_strerror(err));				return err;			}		}		break;	case SND_CTL_ELEM_TYPE_INTEGER:		for (idx = 0; idx < count; idx++) {			err = snd_config_integer_add(value, num_str(idx), snd_ctl_elem_value_get_integer(ctl, idx));			if (err < 0) {				error("snd_config_integer_add: %s", snd_strerror(err));				return err;			}		}		break;	case SND_CTL_ELEM_TYPE_INTEGER64:		for (idx = 0; idx < count; idx++) {			err = snd_config_integer64_add(value, num_str(idx), snd_ctl_elem_value_get_integer64(ctl, idx));			if (err < 0) {				error("snd_config_integer64_add: %s", snd_strerror(err));				return err;			}		}		break;	case SND_CTL_ELEM_TYPE_ENUMERATED:		for (idx = 0; idx < count; idx++) {			unsigned int v = snd_ctl_elem_value_get_enumerated(ctl, idx);			snd_config_t *c;			err = snd_config_search(item, num_str(v), &c);			if (err == 0) {				err = snd_config_get_string(c, &s);				assert(err == 0);				err = snd_config_string_add(value, num_str(idx), s);			} else {				err = snd_config_integer_add(value, num_str(idx), v);			}			if (err < 0) {				error("snd_config add: %s", snd_strerror(err));				return err;			}		}		break;	default:		error("Unknown control type: %d\n", type);		return -EINVAL;	}		return 0;}	static int get_controls(int cardno, snd_config_t *top){	snd_ctl_t *handle;	snd_ctl_card_info_t *info;	snd_config_t *state, *card, *control;	snd_ctl_elem_list_t *list;	unsigned int idx;	int err;	char name[32];	unsigned int count;	const char *id;	snd_ctl_card_info_alloca(&info);	snd_ctl_elem_list_alloca(&list);	sprintf(name, "hw:%d", cardno);	err = snd_ctl_open(&handle, name, SND_CTL_READONLY);	if (err < 0) {		error("snd_ctl_open error: %s", snd_strerror(err));		return err;	}	err = snd_ctl_card_info(handle, info);	if (err < 0) {		error("snd_ctl_card_info error: %s", snd_strerror(err));		goto _close;	}	id = snd_ctl_card_info_get_id(info);	err = snd_config_search(top, "state", &state);	if (err == 0 &&	    snd_config_get_type(state) != SND_CONFIG_TYPE_COMPOUND) {		error("config state node is not a compound");		err = -EINVAL;		goto _close;	}	if (err < 0) {		err = snd_config_compound_add(top, "state", 1, &state);		if (err < 0) {			error("snd_config_compound_add: %s", snd_strerror(err));			goto _close;		}	}	err = snd_config_search(state, id, &card);	if (err == 0 &&	    snd_config_get_type(card) != SND_CONFIG_TYPE_COMPOUND) {		error("config state.%s node is not a compound", id);		err = -EINVAL;		goto _close;	}	if (err < 0) {		err = snd_config_compound_add(state, id, 0, &card);		if (err < 0) {			error("snd_config_compound_add: %s", snd_strerror(err));			goto _close;		}	}	err = snd_config_search(card, "control", &control);	if (err == 0) {		err = snd_config_delete(control);		if (err < 0) {			error("snd_config_delete: %s", snd_strerror(err));			goto _close;		}	}	err = snd_ctl_elem_list(handle, list);	if (err < 0) {		error("Cannot determine controls: %s", snd_strerror(err));		goto _close;	}	count = snd_ctl_elem_list_get_count(list);	if (count < 0) {		err = 0;		goto _close;	}	err = snd_config_compound_add(card, "control", count > 0, &control);	if (err < 0) {		error("snd_config_compound_add: %s", snd_strerror(err));		goto _close;	}	if (count == 0) {		err = 0;		goto _close;	}	snd_ctl_elem_list_set_offset(list, 0);	if (snd_ctl_elem_list_alloc_space(list, count) < 0) {		error("No enough memory...");		goto _close;	}	if ((err = snd_ctl_elem_list(handle, list)) < 0) {		error("Cannot determine controls (2): %s", snd_strerror(err));		goto _free;	}	for (idx = 0; idx < count; ++idx) {		snd_ctl_elem_id_t *id;		snd_ctl_elem_id_alloca(&id);		snd_ctl_elem_list_get_id(list, idx, id);		err = get_control(handle, id, control);		if (err < 0)			goto _free;	}					err = 0; _free:	snd_ctl_elem_list_free_space(list); _close:	snd_ctl_close(handle);	return err;}static long config_iface(snd_config_t *n){	long i;	long long li;	snd_ctl_elem_iface_t idx; 	const char *str;	switch (snd_config_get_type(n)) {	case SND_CONFIG_TYPE_INTEGER:		snd_config_get_integer(n, &i);		return i;	case SND_CONFIG_TYPE_INTEGER64:		snd_config_get_integer64(n, &li);		return li;	case SND_CONFIG_TYPE_STRING:		snd_config_get_string(n, &str);		break;	default:		return -1;	}	for (idx = 0; idx <= SND_CTL_ELEM_IFACE_LAST; idx++) {		if (strcasecmp(snd_ctl_elem_iface_name(idx), str) == 0)			return idx;	}	return -1;}static int config_bool(snd_config_t *n){	const char *str;	long val;	long long lval;	switch (snd_config_get_type(n)) {	case SND_CONFIG_TYPE_INTEGER:		snd_config_get_integer(n, &val);		if (val < 0 || val > 1)			return -1;		return val;	case SND_CONFIG_TYPE_INTEGER64:		snd_config_get_integer64(n, &lval);		if (lval < 0 || lval > 1)			return -1;		return (int) lval;	case SND_CONFIG_TYPE_STRING:		snd_config_get_string(n, &str);		break;	default:		return -1;	}	if (strcmp(str, "on") == 0 || strcmp(str, "true") == 0)		return 1;	if (strcmp(str, "off") == 0 || strcmp(str, "false") == 0)		return 0;	return -1;}static int config_enumerated(snd_config_t *n, snd_ctl_t *handle,			     snd_ctl_elem_info_t *info){	const char *str;	long val;	long long lval;	unsigned int idx, items;	switch (snd_config_get_type(n)) {	case SND_CONFIG_TYPE_INTEGER:		snd_config_get_integer(n, &val);		return val;	case SND_CONFIG_TYPE_INTEGER64:		snd_config_get_integer64(n, &lval);		return (int) lval;	case SND_CONFIG_TYPE_STRING:		snd_config_get_string(n, &str);		break;	default:		return -1;	}	items = snd_ctl_elem_info_get_items(info);	for (idx = 0; idx < items; idx++) {		int err;		snd_ctl_elem_info_set_item(info, idx);		err = snd_ctl_elem_info(handle, info);		if (err < 0) {			error("snd_ctl_elem_info: %s", snd_strerror(err));			return err;		}		if (strcmp(str, snd_ctl_elem_info_get_item_name(info)) == 0)			return idx;	}	return -1;}static int is_user_control(snd_config_t *conf){	snd_config_iterator_t i, next;	snd_config_for_each(i, next, conf) {		snd_config_t *n = snd_config_iterator_entry(i);		const char *id, *s;		if (snd_config_get_id(n, &id) < 0)			continue;		if (strcmp(id, "access") == 0) {			if (snd_config_get_string(n, &s) < 0)				return 0;			if (strstr(s, "user"))				return 1;		}	}	return 0;}static int add_user_control(snd_ctl_t *handle, snd_ctl_elem_info_t *info, snd_config_t *conf){	snd_ctl_elem_id_t *id;	snd_config_iterator_t i, next;	long imin, imax, istep;	snd_ctl_elem_type_t ctype;	unsigned int count;	int err;	unsigned int *tlv;	imin = imax = istep = 0;	count = 0;	ctype = SND_CTL_ELEM_TYPE_NONE;	tlv = NULL;	snd_config_for_each(i, next, conf) {		snd_config_t *n = snd_config_iterator_entry(i);		const char *id, *type;		if (snd_config_get_id(n, &id) < 0)			continue;		if (strcmp(id, "type") == 0) {			if ((err = snd_config_get_string(n, &type)) < 0)				return -EINVAL;			if (strcmp(type, "BOOLEAN") == 0)				ctype = SND_CTL_ELEM_TYPE_BOOLEAN;			else if (strcmp(type, "INTEGER") == 0)				ctype = SND_CTL_ELEM_TYPE_INTEGER;			else if (strcmp(type, "IEC958") == 0)				ctype = SND_CTL_ELEM_TYPE_IEC958;			else				return -EINVAL;			continue;		}		if (strcmp(id, "range") == 0) {			const char *s;			if ((err = snd_config_get_string(n, &s)) < 0)				return -EINVAL;			switch (ctype) {			case SND_CTL_ELEM_TYPE_INTEGER:				err = sscanf(s, "%li - %li (step %li)", &imin, &imax, &istep);				if (err != 3) {					istep = 0;					err = sscanf(s, "%li - %li", &imin, &imax);					if (err != 2)						return -EINVAL;				}				break;			default:				return -EINVAL;			}			continue;		}		if (strcmp(id, "count") == 0) {			long v;			if ((err = snd_config_get_integer(n, &v)) < 0)				return err;			count = v;			continue;		}		if (strcmp(id, "tlv") == 0) {			const char *s;			if ((err = snd_config_get_string(n, &s)) < 0)				return -EINVAL;			if (tlv)				free(tlv);			if ((tlv = str_to_tlv(s)) == NULL)				return -EINVAL;			continue;		}	}	snd_ctl_elem_id_alloca(&id);	snd_ctl_elem_info_get_id(info, id);	if (count <= 0)		count = 1;	switch (ctype) {	case SND_CTL_ELEM_TYPE_INTEGER:		if (imin > imax || istep > imax - imin)			return -EINVAL;		err = snd_ctl_elem_add_integer(handle, id, count, imin, imax, istep);		if (err < 0)			goto error;		if (tlv) {			fprintf(stderr, "XXX write TLV...\n");			snd_ctl_elem_tlv_write(handle, id, tlv);		}		break;	case SND_CTL_ELEM_TYPE_BOOLEAN:		err = snd_ctl_elem_add_boolean(handle, id, count);		break;	case SND_CTL_ELEM_TYPE_IEC958:		err = snd_ctl_elem_add_iec958(handle, id);		break;	default:		err = -EINVAL;		break;	} error:	free(tlv);	if (err < 0)		return err;	return snd_ctl_elem_info(handle, info);}static int set_control(snd_ctl_t *handle, snd_config_t *control){	snd_ctl_elem_value_t *ctl;	snd_ctl_elem_info_t *info;	snd_config_iterator_t i, next;	unsigned int numid1;	snd_ctl_elem_iface_t iface = -1;	int iface1;	const char *name1;	unsigned int numid;	snd_ctl_elem_type_t type;	unsigned int count;	long device = -1;	long device1;	long subdevice = -1;	long subdevice1;	const char *name = NULL;	long index1;	long index = -1;	snd_config_t *value = NULL;	snd_config_t *comment = NULL;	long val;	long long lval;	unsigned int idx;	int err;	char *set;	const char *id;	snd_ctl_elem_value_alloca(&ctl);	snd_ctl_elem_info_alloca(&info);	if (snd_config_get_type(control) != SND_CONFIG_TYPE_COMPOUND) {		error("control is not a compound");		return -EINVAL;	}	err = snd_config_get_id(control, &id);	if (err < 0) {		error("unable to get id");		return -EINVAL;	}	numid = atoi(id);	snd_config_for_each(i, next, control) {		snd_config_t *n = snd_config_iterator_entry(i);		const char *fld;		if (snd_config_get_id(n, &fld) < 0)			continue;		if (strcmp(fld, "comment") == 0) {			if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {				error("control.%d.%s is invalid", numid, fld);				return -EINVAL;			}			comment = n;			continue;		}		if (strcmp(fld, "iface") == 0) {			iface = (snd_ctl_elem_iface_t)config_iface(n);			if (iface < 0) {				error("control.%d.%s is invalid", numid, fld);				return -EINVAL;			}			continue;		}		if (strcmp(fld, "device") == 0) {			if (snd_config_get_type(n) != SND_CONFIG_TYPE_INTEGER) {				error("control.%d.%s is invalid", numid, fld);				return -EINVAL;			}			snd_config_get_integer(n, &device);			continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -