aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/tinyalsa/asoundlib.h11
-rw-r--r--mixer.c62
-rw-r--r--tinymix.c76
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 <tinyalsa/asoundlib.h>
#include <stdio.h>
+#include <stdlib.h>
+
+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");
}