From 066c9f6753dff5e2b8556eeaec986651bf835e08 Mon Sep 17 00:00:00 2001 From: Simon Wilson Date: Sun, 5 Jun 2011 18:23:05 -0700 Subject: Add enum support to mixer - simplify interface for setting/getting enum values - implement enum string get function - update tinymix to deal with enums - rename set/get_int functions because of supported types --- include/tinyalsa/asoundlib.h | 11 +++---- mixer.c | 62 ++++++++++++++++-------------------- tinymix.c | 76 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 105 insertions(+), 44 deletions(-) diff --git a/include/tinyalsa/asoundlib.h b/include/tinyalsa/asoundlib.h index 34e5f8c..2965c17 100644 --- a/include/tinyalsa/asoundlib.h +++ b/include/tinyalsa/asoundlib.h @@ -119,16 +119,15 @@ int mixer_ctl_get_name(struct mixer_ctl *ctl, char *name, unsigned int size); enum mixer_ctl_type mixer_ctl_get_type(struct mixer_ctl *ctl); const char *mixer_ctl_get_type_string(struct mixer_ctl *ctl); unsigned int mixer_ctl_get_num_values(struct mixer_ctl *ctl); +unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl); +int mixer_ctl_get_enum_string(struct mixer_ctl *ctl, unsigned int enum_id, + char *string, unsigned int size); /* Set and get mixer controls */ int mixer_ctl_get_percent(struct mixer_ctl *ctl, unsigned int id); int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent); -int mixer_ctl_get_int(struct mixer_ctl *ctl, unsigned int id); -int mixer_ctl_set_int(struct mixer_ctl *ctl, unsigned int id, int value); - -int mixer_ctl_get_enum(struct mixer_ctl *ctl, const char *string, unsigned int size); -int mixer_ctl_set_enum(struct mixer_ctl *ctl, unsigned int value); -int mixer_ctl_set_enum_by_name(struct mixer_ctl *ctl, const char *string); +int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id); +int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value); #endif diff --git a/mixer.c b/mixer.c index c2fd78c..65be1f3 100644 --- a/mixer.c +++ b/mixer.c @@ -292,7 +292,7 @@ int mixer_ctl_get_percent(struct mixer_ctl *ctl, unsigned int id) return -1; } - return int_to_percent(ctl->info, mixer_ctl_get_int(ctl, id)); + return int_to_percent(ctl->info, mixer_ctl_get_value(ctl, id)); } int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent) @@ -302,10 +302,10 @@ int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent) return -1; } - return mixer_ctl_set_int(ctl, id, percent_to_int(ctl->info, percent)); + return mixer_ctl_set_value(ctl, id, percent_to_int(ctl->info, percent)); } -int mixer_ctl_get_int(struct mixer_ctl *ctl, unsigned int id) +int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id) { struct snd_ctl_elem_value ev; @@ -322,11 +322,12 @@ int mixer_ctl_get_int(struct mixer_ctl *ctl, unsigned int id) switch (ctl->info->type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: return !!ev.value.integer.value[id]; - break; case SNDRV_CTL_ELEM_TYPE_INTEGER: return ev.value.integer.value[id]; - break; + + case SNDRV_CTL_ELEM_TYPE_ENUMERATED: + return ev.value.enumerated.item[id]; default: errno = EINVAL; @@ -336,7 +337,7 @@ int mixer_ctl_get_int(struct mixer_ctl *ctl, unsigned int id) return 0; } -int mixer_ctl_set_int(struct mixer_ctl *ctl, unsigned int id, int value) +int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value) { struct snd_ctl_elem_value ev; @@ -357,6 +358,10 @@ int mixer_ctl_set_int(struct mixer_ctl *ctl, unsigned int id, int value) ev.value.integer.value[id] = value; break; + case SNDRV_CTL_ELEM_TYPE_ENUMERATED: + ev.value.enumerated.item[id] = value; + break; + default: errno = EINVAL; return -1; @@ -365,46 +370,33 @@ int mixer_ctl_set_int(struct mixer_ctl *ctl, unsigned int id, int value) return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev); } -int mixer_ctl_set_enum(struct mixer_ctl *ctl, unsigned int id) +unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl) +{ + if (!ctl) { + errno = EINVAL; + return 0; + } + + return ctl->info->value.enumerated.items; +} + +int mixer_ctl_get_enum_string(struct mixer_ctl *ctl, unsigned int enum_id, + char *string, unsigned int size) { struct snd_ctl_elem_value ev; if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED) || - (id >= ctl->info->value.enumerated.items)) { + (enum_id >= ctl->info->value.enumerated.items)) { errno = EINVAL; return -1; } memset(&ev, 0, sizeof(ev)); - ev.value.enumerated.item[0] = id; ev.id.numid = ctl->info->id.numid; - if (ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev) < 0) + if (ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev)) return -1; + strncpy(string, (char *)ctl->ename[enum_id], size); + return 0; } -int mixer_ctl_set_enum_by_name(struct mixer_ctl *ctl, const char *string) -{ - unsigned int n, max; - struct snd_ctl_elem_value ev; - - if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED)) { - errno = EINVAL; - return -1; - } - - max = ctl->info->value.enumerated.items; - for (n = 0; n < max; n++) { - if (!strcmp(string, ctl->ename[n])) { - memset(&ev, 0, sizeof(ev)); - ev.value.enumerated.item[0] = n; - ev.id.numid = ctl->info->id.numid; - if (ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev) < 0) - return -1; - return 0; - } - } - - errno = EINVAL; - return -1; -} diff --git a/tinymix.c b/tinymix.c index 73694fd..68c23d1 100644 --- a/tinymix.c +++ b/tinymix.c @@ -28,17 +28,37 @@ #include #include +#include + +static void tinymix_list_controls(struct mixer *mixer); +static void tinymix_detail_control(struct mixer *mixer, unsigned int id); int main(int argc, char **argv) { struct mixer *mixer; + + mixer = mixer_open(0); + + if (argc == 1) + tinymix_list_controls(mixer); + else if (argc == 2) + tinymix_detail_control(mixer, atoi(argv[1])); + else + printf("Usage: tinymix [control id]\n"); + + mixer_close(mixer); + + return 0; +} + +static void tinymix_list_controls(struct mixer *mixer) +{ struct mixer_ctl *ctl; const char *type; unsigned int num_ctls, num_values; char buffer[256]; unsigned int i; - mixer = mixer_open(0); num_ctls = mixer_get_num_ctls(mixer); printf("Number of controls: %d\n", num_ctls); @@ -53,9 +73,59 @@ int main(int argc, char **argv) printf("%d\t%s\t%d\t%s\n", i, type, num_values, buffer); } +} - mixer_close(mixer); +static void tinymix_print_enum(struct mixer_ctl *ctl) +{ + unsigned int num_enums; + char buffer[256]; + unsigned int i; - return 0; + num_enums = mixer_ctl_get_num_enums(ctl); + + for (i = 0; i < num_enums; i++) { + mixer_ctl_get_enum_string(ctl, i, buffer, sizeof(buffer)); + printf("\t%s%s", mixer_ctl_get_value(ctl, 0) == i ? ">" : "", buffer); + } +} + +static void tinymix_detail_control(struct mixer *mixer, unsigned int id) +{ + struct mixer_ctl *ctl; + enum mixer_ctl_type type; + unsigned int num_values; + char buffer[256]; + unsigned int i; + + if (id >= mixer_get_num_ctls(mixer)) { + fprintf(stderr, "Invalid mixer control\n"); + return; + } + + ctl = mixer_get_ctl(mixer, id); + + mixer_ctl_get_name(ctl, buffer, sizeof(buffer)); + type = mixer_ctl_get_type(ctl); + num_values = mixer_ctl_get_num_values(ctl); + + printf("%s:", buffer); + for (i = 0; i < num_values; i++) { + switch (type) + { + case MIXER_CTL_TYPE_INT: + printf("\t%d", mixer_ctl_get_value(ctl, i)); + break; + case MIXER_CTL_TYPE_BOOL: + printf("\t%s", mixer_ctl_get_value(ctl, i) ? "On" : "Off"); + break; + case MIXER_CTL_TYPE_ENUM: + tinymix_print_enum(ctl); + break; + default: + printf("\tunknown"); + break; + }; + } + printf("\n"); } -- cgit v1.2.3