diff options
Diffstat (limited to 'tinymix.c')
-rw-r--r-- | tinymix.c | 105 |
1 files changed, 98 insertions, 7 deletions
@@ -27,10 +27,13 @@ */ #include <tinyalsa/asoundlib.h> +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> +#include <limits.h> +#include <errno.h> static void tinymix_list_controls(struct mixer *mixer); static void tinymix_detail_control(struct mixer *mixer, const char *control, @@ -87,7 +90,7 @@ static void tinymix_list_controls(struct mixer *mixer) num_ctls = mixer_get_num_ctls(mixer); - printf("Number of controls: %d\n", num_ctls); + printf("Number of controls: %u\n", num_ctls); printf("ctl\ttype\tnum\t%-40s value\n", "name"); for (i = 0; i < num_ctls; i++) { @@ -96,7 +99,7 @@ static void tinymix_list_controls(struct mixer *mixer) name = mixer_ctl_get_name(ctl); type = mixer_ctl_get_type_string(ctl); num_values = mixer_ctl_get_num_values(ctl); - printf("%d\t%s\t%d\t%-40s", i, type, num_values, name); + printf("%u\t%s\t%u\t%-40s", i, type, num_values, name); tinymix_detail_control(mixer, name, 0); } } @@ -127,6 +130,8 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control, unsigned int num_values; unsigned int i; int min, max; + int ret; + char *buf = NULL; if (isdigit(control[0])) ctl = mixer_get_ctl(mixer, atoi(control)); @@ -141,6 +146,21 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control, type = mixer_ctl_get_type(ctl); num_values = mixer_ctl_get_num_values(ctl); + if ((type == MIXER_CTL_TYPE_BYTE) && (num_values > 0)) { + buf = calloc(1, num_values); + if (buf == NULL) { + fprintf(stderr, "Failed to alloc mem for bytes %u\n", num_values); + return; + } + + ret = mixer_ctl_get_array(ctl, buf, num_values); + if (ret < 0) { + fprintf(stderr, "Failed to mixer_ctl_get_array\n"); + free(buf); + return; + } + } + if (print_all) printf("%s:", mixer_ctl_get_name(ctl)); @@ -156,8 +176,8 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control, case MIXER_CTL_TYPE_ENUM: tinymix_print_enum(ctl, print_all); break; - case MIXER_CTL_TYPE_BYTE: - printf(" 0x%02x", mixer_ctl_get_value(ctl, i)); + case MIXER_CTL_TYPE_BYTE: + printf("%02x", buf[i]); break; default: printf(" unknown"); @@ -172,9 +192,75 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control, printf(" (range %d->%d)", min, max); } } + + free(buf); + printf("\n"); } +static void tinymix_set_byte_ctl(struct mixer_ctl *ctl, + char **values, unsigned int num_values) +{ + int ret; + char *buf; + char *end; + unsigned int i; + long n; + + buf = calloc(1, num_values); + if (buf == NULL) { + fprintf(stderr, "set_byte_ctl: Failed to alloc mem for bytes %u\n", num_values); + exit(EXIT_FAILURE); + } + + for (i = 0; i < num_values; i++) { + errno = 0; + n = strtol(values[i], &end, 0); + if (*end) { + fprintf(stderr, "%s not an integer\n", values[i]); + goto fail; + } + if (errno) { + fprintf(stderr, "strtol: %s: %s\n", values[i], + strerror(errno)); + goto fail; + } + if (n < 0 || n > 0xff) { + fprintf(stderr, "%s should be between [0, 0xff]\n", + values[i]); + goto fail; + } + buf[i] = n; + } + + ret = mixer_ctl_set_array(ctl, buf, num_values); + if (ret < 0) { + fprintf(stderr, "Failed to set binary control\n"); + goto fail; + } + + free(buf); + return; + +fail: + free(buf); + exit(EXIT_FAILURE); +} + +static int is_int(char *value) +{ + char* end; + long int result; + + errno = 0; + result = strtol(value, &end, 10); + + if (result == LONG_MIN || result == LONG_MAX) + return 0; + + return errno == 0 && *end == '\0'; +} + static void tinymix_set_value(struct mixer *mixer, const char *control, char **values, unsigned int num_values) { @@ -196,7 +282,12 @@ static void tinymix_set_value(struct mixer *mixer, const char *control, type = mixer_ctl_get_type(ctl); num_ctl_values = mixer_ctl_get_num_values(ctl); - if (isdigit(values[0][0])) { + if (type == MIXER_CTL_TYPE_BYTE) { + tinymix_set_byte_ctl(ctl, values, num_values); + return; + } + + if (is_int(values[0])) { if (num_values == 1) { /* Set all values the same */ int value = atoi(values[0]); @@ -211,13 +302,13 @@ static void tinymix_set_value(struct mixer *mixer, const char *control, /* Set multiple values */ if (num_values > num_ctl_values) { fprintf(stderr, - "Error: %d values given, but control only takes %d\n", + "Error: %u values given, but control only takes %u\n", num_values, num_ctl_values); return; } for (i = 0; i < num_values; i++) { if (mixer_ctl_set_value(ctl, i, atoi(values[i]))) { - fprintf(stderr, "Error: invalid value for index %d\n", i); + fprintf(stderr, "Error: invalid value for index %u\n", i); return; } } |