aboutsummaryrefslogtreecommitdiff
path: root/tinymix.c
diff options
context:
space:
mode:
Diffstat (limited to 'tinymix.c')
-rw-r--r--tinymix.c105
1 files changed, 98 insertions, 7 deletions
diff --git a/tinymix.c b/tinymix.c
index afc2fee..5966df9 100644
--- a/tinymix.c
+++ b/tinymix.c
@@ -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;
}
}