From f0a20ee4ccbba5504bd87397fcf9d9a89467208d Mon Sep 17 00:00:00 2001 From: Simon Wilson Date: Sun, 5 Jun 2011 21:18:52 -0700 Subject: Implement mixer setting in tinymix - re-add function to set enum type by string - implement setting of mixer values in tinymix - fix bug: read current mixer values before writing --- include/tinyalsa/asoundlib.h | 1 + mixer.c | 28 ++++++++++++++++++++++++++++ tinymix.c | 37 ++++++++++++++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/include/tinyalsa/asoundlib.h b/include/tinyalsa/asoundlib.h index 2965c17..4ee04a3 100644 --- a/include/tinyalsa/asoundlib.h +++ b/include/tinyalsa/asoundlib.h @@ -129,5 +129,6 @@ int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent); 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); +int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string); #endif diff --git a/mixer.c b/mixer.c index 65be1f3..eedcbb7 100644 --- a/mixer.c +++ b/mixer.c @@ -348,6 +348,8 @@ int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value) memset(&ev, 0, sizeof(ev)); ev.id.numid = ctl->info->id.numid; + if (ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev)) + return -1; switch (ctl->info->type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: @@ -400,3 +402,29 @@ int mixer_ctl_get_enum_string(struct mixer_ctl *ctl, unsigned int enum_id, return 0; } +int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string) +{ + unsigned int i, num_enums; + struct snd_ctl_elem_value ev; + + if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED)) { + errno = EINVAL; + return -1; + } + + num_enums = ctl->info->value.enumerated.items; + for (i = 0; i < num_enums; i++) { + if (!strcmp(string, ctl->ename[i])) { + memset(&ev, 0, sizeof(ev)); + ev.value.enumerated.item[0] = i; + 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 68c23d1..bf24a7c 100644 --- a/tinymix.c +++ b/tinymix.c @@ -32,6 +32,8 @@ static void tinymix_list_controls(struct mixer *mixer); static void tinymix_detail_control(struct mixer *mixer, unsigned int id); +static void tinymix_set_value(struct mixer *mixer, unsigned int id, + char *value); int main(int argc, char **argv) { @@ -43,8 +45,10 @@ int main(int argc, char **argv) tinymix_list_controls(mixer); else if (argc == 2) tinymix_detail_control(mixer, atoi(argv[1])); + else if (argc == 3) + tinymix_set_value(mixer, atoi(argv[1]), argv[2]); else - printf("Usage: tinymix [control id]\n"); + printf("Usage: tinymix [control id] [value to set]\n"); mixer_close(mixer); @@ -129,3 +133,34 @@ static void tinymix_detail_control(struct mixer *mixer, unsigned int id) printf("\n"); } +static void tinymix_set_value(struct mixer *mixer, unsigned int id, + char *string) +{ + struct mixer_ctl *ctl; + enum mixer_ctl_type type; + unsigned int num_values; + unsigned int i; + + ctl = mixer_get_ctl(mixer, id); + type = mixer_ctl_get_type(ctl); + num_values = mixer_ctl_get_num_values(ctl); + + if (isdigit(string[0])) { + int value = atoi(string); + + for (i = 0; i < num_values; i++) { + if (mixer_ctl_set_value(ctl, i, value)) { + fprintf(stderr, "Error: invalid value\n"); + return; + } + } + } else { + if (type == MIXER_CTL_TYPE_ENUM) { + if (mixer_ctl_set_enum_by_string(ctl, string)) + fprintf(stderr, "Error: invalid enum value\n"); + } else { + fprintf(stderr, "Error: only enum types can be set with strings\n"); + } + } +} + -- cgit v1.2.3