From e2eab09c1d7963580d9ff3ec2fbf814a842d2881 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 9 Apr 2013 18:38:58 +0200 Subject: amixer: Use the alsa-lib functions for id print and parse and value parse Signed-off-by: Jaroslav Kysela --- amixer/amixer.c | 289 +++++--------------------------------------------------- 1 file changed, 26 insertions(+), 263 deletions(-) (limited to 'amixer') diff --git a/amixer/amixer.c b/amixer/amixer.c index c7c879d..2f1521b 100644 --- a/amixer/amixer.c +++ b/amixer/amixer.c @@ -138,11 +138,6 @@ static int info(void) return 0; } -static const char *control_iface(snd_ctl_elem_id_t *id) -{ - return snd_ctl_elem_iface_name(snd_ctl_elem_id_get_interface(id)); -} - static const char *control_type(snd_ctl_elem_info_t *info) { return snd_ctl_elem_type_name(snd_ctl_elem_info_get_type(info)); @@ -208,62 +203,6 @@ static int convert_prange(long val, long min, long max) #define convert_prange1(val, min, max) \ ceil((val) * ((max) - (min)) * 0.01 + (min)) -static long get_integer(char **ptr, long min, long max) -{ - long val = min; - char *p = *ptr, *s; - - if (*p == ':') - p++; - if (*p == '\0' || (!isdigit(*p) && *p != '-')) - goto out; - - s = p; - val = strtol(s, &p, 10); - if (*p == '.') { - p++; - strtol(p, &p, 10); - } - if (*p == '%') { - val = (long)convert_prange1(strtod(s, NULL), min, max); - p++; - } - val = check_range(val, min, max); - if (*p == ',') - p++; - out: - *ptr = p; - return val; -} - -static long get_integer64(char **ptr, long long min, long long max) -{ - long long val = min; - char *p = *ptr, *s; - - if (*p == ':') - p++; - if (*p == '\0' || (!isdigit(*p) && *p != '-')) - goto out; - - s = p; - val = strtol(s, &p, 10); - if (*p == '.') { - p++; - strtol(p, &p, 10); - } - if (*p == '%') { - val = (long long)convert_prange1(strtod(s, NULL), min, max); - p++; - } - val = check_range(val, min, max); - if (*p == ',') - p++; - out: - *ptr = p; - return val; -} - struct volume_ops { int (*get_range)(snd_mixer_elem_t *elem, long *min, long *max); int (*get)(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t c, @@ -476,20 +415,12 @@ static int simple_skip_word(char **ptr, char *str) static void show_control_id(snd_ctl_elem_id_t *id) { - unsigned int index, device, subdevice; - printf("numid=%u,iface=%s,name='%s'", - snd_ctl_elem_id_get_numid(id), - control_iface(id), - snd_ctl_elem_id_get_name(id)); - index = snd_ctl_elem_id_get_index(id); - device = snd_ctl_elem_id_get_device(id); - subdevice = snd_ctl_elem_id_get_subdevice(id); - if (index) - printf(",index=%i", index); - if (device) - printf(",device=%i", device); - if (subdevice) - printf(",subdevice=%i", subdevice); + char *str; + + str = snd_ctl_ascii_elem_id_get(id); + if (str) + printf("%s", str); + free(str); } static void print_spaces(unsigned int spaces) @@ -1086,103 +1017,6 @@ static int selems(int level) return 0; } -static int parse_control_id(const char *str, snd_ctl_elem_id_t *id) -{ - int c, size, numid; - char *ptr; - - while (*str == ' ' || *str == '\t') - str++; - if (!(*str)) - return -EINVAL; - snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); /* default */ - while (*str) { - if (!strncasecmp(str, "numid=", 6)) { - str += 6; - numid = atoi(str); - if (numid <= 0) { - fprintf(stderr, "amixer: Invalid numid %d\n", numid); - return -EINVAL; - } - snd_ctl_elem_id_set_numid(id, atoi(str)); - while (isdigit(*str)) - str++; - } else if (!strncasecmp(str, "iface=", 6)) { - str += 6; - if (!strncasecmp(str, "card", 4)) { - snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_CARD); - str += 4; - } else if (!strncasecmp(str, "mixer", 5)) { - snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); - str += 5; - } else if (!strncasecmp(str, "pcm", 3)) { - snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_PCM); - str += 3; - } else if (!strncasecmp(str, "rawmidi", 7)) { - snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_RAWMIDI); - str += 7; - } else if (!strncasecmp(str, "timer", 5)) { - snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_TIMER); - str += 5; - } else if (!strncasecmp(str, "sequencer", 9)) { - snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_SEQUENCER); - str += 9; - } else { - return -EINVAL; - } - } else if (!strncasecmp(str, "name=", 5)) { - char buf[64]; - str += 5; - ptr = buf; - size = 0; - if (*str == '\'' || *str == '\"') { - c = *str++; - while (*str && *str != c) { - if (size < (int)sizeof(buf)) { - *ptr++ = *str; - size++; - } - str++; - } - if (*str == c) - str++; - } else { - while (*str && *str != ',') { - if (size < (int)sizeof(buf)) { - *ptr++ = *str; - size++; - } - str++; - } - } - *ptr = '\0'; - snd_ctl_elem_id_set_name(id, buf); - } else if (!strncasecmp(str, "index=", 6)) { - str += 6; - snd_ctl_elem_id_set_index(id, atoi(str)); - while (isdigit(*str)) - str++; - } else if (!strncasecmp(str, "device=", 7)) { - str += 7; - snd_ctl_elem_id_set_device(id, atoi(str)); - while (isdigit(*str)) - str++; - } else if (!strncasecmp(str, "subdevice=", 10)) { - str += 10; - snd_ctl_elem_id_set_subdevice(id, atoi(str)); - while (isdigit(*str)) - str++; - } - if (*str == ',') { - str++; - } else { - if (*str) - return -EINVAL; - } - } - return 0; -} - static int parse_simple_id(const char *str, snd_mixer_selem_id_t *sid) { int c, size; @@ -1231,34 +1065,6 @@ static int parse_simple_id(const char *str, snd_mixer_selem_id_t *sid) return 0; } -static int get_ctl_enum_item_index(snd_ctl_t *handle, snd_ctl_elem_info_t *info, - char **ptrp) -{ - char *ptr = *ptrp; - int items, i, len; - const char *name; - - items = snd_ctl_elem_info_get_items(info); - if (items <= 0) - return -1; - - for (i = 0; i < items; i++) { - snd_ctl_elem_info_set_item(info, i); - if (snd_ctl_elem_info(handle, info) < 0) - return -1; - name = snd_ctl_elem_info_get_item_name(info); - len = strlen(name); - if (! strncmp(name, ptr, len)) { - if (! ptr[len] || ptr[len] == ',' || ptr[len] == '\n') { - ptr += len; - *ptrp = ptr; - return i; - } - } - } - return -1; -} - static int cset(int argc, char *argv[], int roflag, int keep_handle) { int err; @@ -1266,10 +1072,6 @@ static int cset(int argc, char *argv[], int roflag, int keep_handle) snd_ctl_elem_info_t *info; snd_ctl_elem_id_t *id; snd_ctl_elem_value_t *control; - char *ptr; - unsigned int idx, count; - long tmp; - snd_ctl_elem_type_t type; snd_ctl_elem_info_alloca(&info); snd_ctl_elem_id_alloca(&id); snd_ctl_elem_value_alloca(&control); @@ -1278,7 +1080,7 @@ static int cset(int argc, char *argv[], int roflag, int keep_handle) fprintf(stderr, "Specify a full control identifier: [[iface=,][name='name',][index=,][device=,][subdevice=]]|[numid=]\n"); return -EINVAL; } - if (parse_control_id(argv[0], id)) { + if (snd_ctl_ascii_elem_id_parse(id, argv[0])) { fprintf(stderr, "Wrong control identifier: %s\n", argv[0]); return -EINVAL; } @@ -1303,66 +1105,27 @@ static int cset(int argc, char *argv[], int roflag, int keep_handle) } return err; } - snd_ctl_elem_info_get_id(info, id); /* FIXME: Remove it when hctl find works ok !!! */ - type = snd_ctl_elem_info_get_type(info); - count = snd_ctl_elem_info_get_count(info); - snd_ctl_elem_value_set_id(control, id); - if (!roflag) { - ptr = argv[1]; - for (idx = 0; idx < count && idx < 128 && ptr && *ptr; idx++) { - switch (type) { - case SND_CTL_ELEM_TYPE_BOOLEAN: - tmp = 0; - if (!strncasecmp(ptr, "on", 2) || !strncasecmp(ptr, "up", 2)) { - tmp = 1; - ptr += 2; - } else if (!strncasecmp(ptr, "yes", 3)) { - tmp = 1; - ptr += 3; - } else if (!strncasecmp(ptr, "toggle", 6)) { - tmp = snd_ctl_elem_value_get_boolean(control, idx); - tmp = tmp > 0 ? 0 : 1; - ptr += 6; - } else if (isdigit(*ptr)) { - tmp = atoi(ptr) > 0 ? 1 : 0; - while (isdigit(*ptr)) - ptr++; - } else { - while (*ptr && *ptr != ',') - ptr++; - } - snd_ctl_elem_value_set_boolean(control, idx, tmp); - break; - case SND_CTL_ELEM_TYPE_INTEGER: - tmp = get_integer(&ptr, - snd_ctl_elem_info_get_min(info), - snd_ctl_elem_info_get_max(info)); - snd_ctl_elem_value_set_integer(control, idx, tmp); - break; - case SND_CTL_ELEM_TYPE_INTEGER64: - tmp = get_integer64(&ptr, - snd_ctl_elem_info_get_min64(info), - snd_ctl_elem_info_get_max64(info)); - snd_ctl_elem_value_set_integer64(control, idx, tmp); - break; - case SND_CTL_ELEM_TYPE_ENUMERATED: - tmp = get_ctl_enum_item_index(handle, info, &ptr); - if (tmp < 0) - tmp = get_integer(&ptr, 0, snd_ctl_elem_info_get_items(info) - 1); - snd_ctl_elem_value_set_enumerated(control, idx, tmp); - break; - case SND_CTL_ELEM_TYPE_BYTES: - tmp = get_integer(&ptr, 0, 255); - snd_ctl_elem_value_set_byte(control, idx, tmp); - break; - default: - break; + snd_ctl_elem_value_set_id(control, id); + if ((err = snd_ctl_elem_read(handle, control)) < 0) { + if (ignore_error) + return 0; + error("Cannot read the given element from control %s\n", card); + if (! keep_handle) { + snd_ctl_close(handle); + handle = NULL; } - if (!strchr(argv[1], ',')) - ptr = argv[1]; - else if (*ptr == ',') - ptr++; + return err; + } + err = snd_ctl_ascii_value_parse(handle, control, info, argv[1]); + if (err < 0) { + if (!ignore_error) + error("Control %s parse error: %s\n", card, snd_strerror(err)); + if (!keep_handle) { + snd_ctl_close(handle); + handle = NULL; + } + return ignore_error ? 0 : err; } if ((err = snd_ctl_elem_write(handle, control)) < 0) { if (!ignore_error) -- cgit v1.2.1