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

📄 state.c

📁 alsa-utils-1.0.14编译声卡驱动所需要的一些文件源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  Advanced Linux Sound Architecture Control Program *  Copyright (c) by Abramo Bagnara <abramo@alsa-project.org> *                   Jaroslav Kysela <perex@suse.cz> * * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA * */#include "aconfig.h"#include "version.h"#include <getopt.h>#include <stdarg.h>#include <stdio.h>#include <assert.h>#include <errno.h>#include <alsa/asoundlib.h>#include "alsactl.h"char *id_str(snd_ctl_elem_id_t *id){	static char str[128];	assert(id);	sprintf(str, "%i,%i,%i,%s,%i", 		snd_ctl_elem_id_get_interface(id),		snd_ctl_elem_id_get_device(id),		snd_ctl_elem_id_get_subdevice(id),		snd_ctl_elem_id_get_name(id),		snd_ctl_elem_id_get_index(id));	return str;}char *num_str(long n){	static char str[32];	sprintf(str, "%ld", n);	return str;}static int snd_config_integer_add(snd_config_t *father, char *id, long integer){	int err;	snd_config_t *leaf;	err = snd_config_make_integer(&leaf, id);	if (err < 0)		return err;	err = snd_config_add(father, leaf);	if (err < 0) {		snd_config_delete(leaf);		return err;	}	err = snd_config_set_integer(leaf, integer);	if (err < 0) {		snd_config_delete(leaf);		return err;	}	return 0;}static int snd_config_integer64_add(snd_config_t *father, char *id, long long integer){	int err;	snd_config_t *leaf;	err = snd_config_make_integer64(&leaf, id);	if (err < 0)		return err;	err = snd_config_add(father, leaf);	if (err < 0) {		snd_config_delete(leaf);		return err;	}	err = snd_config_set_integer64(leaf, integer);	if (err < 0) {		snd_config_delete(leaf);		return err;	}	return 0;}static int snd_config_string_add(snd_config_t *father, const char *id, const char *string){	int err;	snd_config_t *leaf;	err = snd_config_make_string(&leaf, id);	if (err < 0)		return err;	err = snd_config_add(father, leaf);	if (err < 0) {		snd_config_delete(leaf);		return err;	}	err = snd_config_set_string(leaf, string);	if (err < 0) {		snd_config_delete(leaf);		return err;	}	return 0;}static int snd_config_compound_add(snd_config_t *father, const char *id, int join,				   snd_config_t **node){	int err;	snd_config_t *leaf;	err = snd_config_make_compound(&leaf, id, join);	if (err < 0)		return err;	err = snd_config_add(father, leaf);	if (err < 0) {		snd_config_delete(leaf);		return err;	}	*node = leaf;	return 0;}#define MAX_USER_TLV_SIZE	64static char *tlv_to_str(unsigned int *tlv){	int i, len = tlv[1] / 4 + 2;	char *s, *p;	if (len >= MAX_USER_TLV_SIZE)		return NULL;	s = malloc(len * 8 + 1);	if (! s)		return NULL;	p = s;	for (i = 0; i < len; i++) {		sprintf(p, "%08x", tlv[i]);		p += 8;	}	return s;}static int hextodigit(int c){	if (c >= '0' && c <= '9')		c -= '0';	else if (c >= 'a' && c <= 'f')		c = c - 'a' + 10;	else if (c >= 'A' && c <= 'F')		c = c - 'A' + 10;	else		return -1;	return c;}static unsigned int *str_to_tlv(const char *s){	int i, j, c, len;	unsigned int *tlv;				len = strlen(s);	if (len % 8) /* aligned to 4 bytes (= 8 letters) */		return NULL;	len /= 8;	if (len > MAX_USER_TLV_SIZE)		return NULL;	tlv = malloc(sizeof(int) * len);	if (! tlv)		return NULL;	for (i = 0; i < len; i++) {		tlv[i] = 0;		for (j = 0; j < 8; j++) {			if ((c = hextodigit(*s++)) < 0) {				free(tlv);				return NULL;			}			tlv[i] = (tlv[i] << 4) | c;		}	}	return tlv;}static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *top){	snd_ctl_elem_value_t *ctl;	snd_ctl_elem_info_t *info;	snd_config_t *control, *comment, *item, *value;	const char *s;	char buf[256];	unsigned int idx;	int err;	unsigned int device, subdevice, index;	const char *name;	snd_ctl_elem_type_t type;	unsigned int count;	snd_ctl_elem_value_alloca(&ctl);	snd_ctl_elem_info_alloca(&info);	snd_ctl_elem_info_set_id(info, id);	err = snd_ctl_elem_info(handle, info);	if (err < 0) {		error("Cannot read control info '%s': %s", id_str(id), snd_strerror(err));		return err;	}	if (!snd_ctl_elem_info_is_readable(info))		return 0;	snd_ctl_elem_value_set_id(ctl, id);	err = snd_ctl_elem_read(handle, ctl);	if (err < 0) {		error("Cannot read control '%s': %s", id_str(id), snd_strerror(err));		return err;	}	err = snd_config_compound_add(top, num_str(snd_ctl_elem_info_get_numid(info)), 0, &control);	if (err < 0) {		error("snd_config_compound_add: %s", snd_strerror(err));		return err;	}	err = snd_config_compound_add(control, "comment", 1, &comment);	if (err < 0) {		error("snd_config_compound_add: %s", snd_strerror(err));		return err;	}	buf[0] = '\0';	buf[1] = '\0';	if (snd_ctl_elem_info_is_readable(info))		strcat(buf, " read");	if (snd_ctl_elem_info_is_writable(info))		strcat(buf, " write");	if (snd_ctl_elem_info_is_inactive(info))		strcat(buf, " inactive");	if (snd_ctl_elem_info_is_volatile(info))		strcat(buf, " volatile");	if (snd_ctl_elem_info_is_locked(info))		strcat(buf, " locked");	if (snd_ctl_elem_info_is_user(info))		strcat(buf, " user");	err = snd_config_string_add(comment, "access", buf + 1);	if (err < 0) {		error("snd_config_string_add: %s", snd_strerror(err));		return err;	}	type = snd_ctl_elem_info_get_type(info);	device = snd_ctl_elem_info_get_device(info);	subdevice = snd_ctl_elem_info_get_subdevice(info);	index = snd_ctl_elem_info_get_index(info);	name = snd_ctl_elem_info_get_name(info);	count = snd_ctl_elem_info_get_count(info);	s = snd_ctl_elem_type_name(type);	err = snd_config_string_add(comment, "type", s);	if (err < 0) {		error("snd_config_string_add: %s", snd_strerror(err));		return err;	}	err = snd_config_integer_add(comment, "count", count);	if (err < 0) {		error("snd_config_integer_add: %s", snd_strerror(err));		return err;	}	switch (type) {	case SND_CTL_ELEM_TYPE_BOOLEAN:		break;	case SND_CTL_ELEM_TYPE_INTEGER:	{		long min = snd_ctl_elem_info_get_min(info);		long max = snd_ctl_elem_info_get_max(info);		long step = snd_ctl_elem_info_get_step(info);		if (step)			sprintf(buf, "%li - %li (step %li)", min, max, step);		else			sprintf(buf, "%li - %li", min, max);		err = snd_config_string_add(comment, "range", buf);		if (err < 0) {			error("snd_config_string_add: %s", snd_strerror(err));			return err;		}		if (snd_ctl_elem_info_is_tlv_readable(info) &&		    snd_ctl_elem_info_is_tlv_writable(info)) {			unsigned int tlv[MAX_USER_TLV_SIZE];			err = snd_ctl_elem_tlv_read(handle, id, tlv, sizeof(tlv));			if (err >= 0) {				char *s = tlv_to_str(tlv);				if (s) {					err = snd_config_string_add(comment, "tlv", s);					if (err < 0) {						error("snd_config_string_add: %s", snd_strerror(err));						return err;					}					free(s);				}			}		}		    		break;	}	case SND_CTL_ELEM_TYPE_INTEGER64:	{		long long min = snd_ctl_elem_info_get_min64(info);		long long max = snd_ctl_elem_info_get_max64(info);		long long step = snd_ctl_elem_info_get_step64(info);		if (step)			sprintf(buf, "%Li - %Li (step %Li)", min, max, step);		else			sprintf(buf, "%Li - %Li", min, max);		err = snd_config_string_add(comment, "range", buf);		if (err < 0) {			error("snd_config_string_add: %s", snd_strerror(err));			return err;		}		break;	}	case SND_CTL_ELEM_TYPE_ENUMERATED:	{		unsigned int items;		err = snd_config_compound_add(comment, "item", 1, &item);		if (err < 0) {			error("snd_config_compound_add: %s", snd_strerror(err));			return err;		}		items = snd_ctl_elem_info_get_items(info);		for (idx = 0; idx < items; idx++) {			snd_ctl_elem_info_set_item(info, idx);			err = snd_ctl_elem_info(handle, info);			if (err < 0) {				error("snd_ctl_card_info: %s", snd_strerror(err));				return err;			}			err = snd_config_string_add(item, num_str(idx), snd_ctl_elem_info_get_item_name(info));			if (err < 0) {				error("snd_config_string_add: %s", snd_strerror(err));				return err;			}		}		break;	}	default:		break;	}	s = snd_ctl_elem_iface_name(snd_ctl_elem_info_get_interface(info));	err = snd_config_string_add(control, "iface", s);	if (err < 0) {		error("snd_config_string_add: %s", snd_strerror(err));		return err;	}	if (device != 0) {		err = snd_config_integer_add(control, "device", device);		if (err < 0) {			error("snd_config_integer_add: %s", snd_strerror(err));			return err;		}	}	if (subdevice != 0) {		err = snd_config_integer_add(control, "subdevice", subdevice);		if (err < 0) {			error("snd_config_integer_add: %s", snd_strerror(err));			return err;		}	}	err = snd_config_string_add(control, "name", name);	if (err < 0) {		error("snd_config_string_add: %s", snd_strerror(err));		return err;	}	if (index != 0) {		err = snd_config_integer_add(control, "index", index);		if (err < 0) {			error("snd_config_integer_add: %s", snd_strerror(err));			return err;		}	}	switch (type) {	case SND_CTL_ELEM_TYPE_BYTES:	case SND_CTL_ELEM_TYPE_IEC958:	{		size_t size = type == SND_CTL_ELEM_TYPE_BYTES ?			count : sizeof(snd_aes_iec958_t);		char buf[size * 2 + 1];		char *p = buf;		char *hex = "0123456789abcdef";		const unsigned char *bytes = 		  (const unsigned char *)snd_ctl_elem_value_get_bytes(ctl);		for (idx = 0; idx < size; idx++) {			int v = bytes[idx];			*p++ = hex[v >> 4];			*p++ = hex[v & 0x0f];		}		*p = '\0';		err = snd_config_string_add(control, "value", buf);		if (err < 0) {			error("snd_config_string_add: %s", snd_strerror(err));			return err;		}		return 0;	}	default:		break;	}	if (count == 1) {		switch (type) {		case SND_CTL_ELEM_TYPE_BOOLEAN:			err = snd_config_string_add(control, "value", snd_ctl_elem_value_get_boolean(ctl, 0) ? "true" : "false");			if (err < 0) {				error("snd_config_string_add: %s", snd_strerror(err));				return err;			}			return 0;		case SND_CTL_ELEM_TYPE_INTEGER:			err = snd_config_integer_add(control, "value", snd_ctl_elem_value_get_integer(ctl, 0));			if (err < 0) {				error("snd_config_integer_add: %s", snd_strerror(err));				return err;			}			return 0;		case SND_CTL_ELEM_TYPE_INTEGER64:			err = snd_config_integer64_add(control, "value", snd_ctl_elem_value_get_integer64(ctl, 0));			if (err < 0) {				error("snd_config_integer64_add: %s", snd_strerror(err));				return err;			}			return 0;		case SND_CTL_ELEM_TYPE_ENUMERATED:		{			unsigned int v = snd_ctl_elem_value_get_enumerated(ctl, 0);			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(control, "value", s);			} else {				err = snd_config_integer_add(control, "value", v);			}			if (err < 0)				error("snd_config add: %s", snd_strerror(err));			return 0;		}		default:			error("Unknown control type: %d\n", type);

⌨️ 快捷键说明

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