From a8a581fb422c9c2af2d8858a678c008db80e1e3c Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Tue, 30 May 2023 20:27:35 +0530 Subject: mixer: add support for pcm device specific mixer controls Mixer control such as "Playback channel map" can be registered by multiple pcm device nodes and is distinguished by device in snd_ctl_elem_id. Add support to get the control handle associated with mixer ctl name and device number. Also, introduce API to get the device number associated with specific mixer_ctl handle. --- include/tinyalsa/mixer.h | 6 +++++ src/mixer.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/include/tinyalsa/mixer.h b/include/tinyalsa/mixer.h index 7d0580f..149b395 100644 --- a/include/tinyalsa/mixer.h +++ b/include/tinyalsa/mixer.h @@ -103,6 +103,10 @@ struct mixer_ctl *mixer_get_ctl(struct mixer *mixer, unsigned int id); struct mixer_ctl *mixer_get_ctl_by_name(struct mixer *mixer, const char *name); +struct mixer_ctl *mixer_get_ctl_by_name_and_device(struct mixer *mixer, + const char *name, + unsigned int device); + struct mixer_ctl *mixer_get_ctl_by_name_and_index(struct mixer *mixer, const char *name, unsigned int index); @@ -153,6 +157,8 @@ int mixer_ctl_get_range_min(const struct mixer_ctl *ctl); int mixer_ctl_get_range_max(const struct mixer_ctl *ctl); +unsigned int mixer_ctl_get_device(const struct mixer_ctl *ctl); + int mixer_read_event(struct mixer *mixer, struct mixer_ctl_event *event); int mixer_consume_event(struct mixer *mixer); diff --git a/src/mixer.c b/src/mixer.c index 029fc84..f2c21c3 100644 --- a/src/mixer.c +++ b/src/mixer.c @@ -760,6 +760,55 @@ struct mixer_ctl *mixer_get_ctl_by_name_and_index(struct mixer *mixer, return NULL; } +/** Gets an instance of mixer control handle, by the mixer control's name and device. + * For instance, if two controls have same name, + * e.g. 'Playback Channel map', then PCM device returns the specific control. + * @param mixer An initialized mixer handle. + * @param name The control's name in the given mixer. + * @param device The PCM device + * @returns A handle to the mixer control. + * @ingroup libtinyalsa-mixer + */ +struct mixer_ctl *mixer_get_ctl_by_name_and_device(struct mixer *mixer, + const char *name, + unsigned int device) +{ + struct mixer_ctl_group *grp; + unsigned int n; + struct mixer_ctl *ctl; + + if (!mixer || !name) { + return NULL; + } + + if (mixer->h_grp) { + grp = mixer->h_grp; + ctl = grp->ctl; + + for (n = 0; n < grp->count; n++) { + if (!strcmp(name, (char*) ctl[n].info.id.name) && + device == ctl[n].info.id.device) { + return ctl + n; + } + } + } + +#ifdef TINYALSA_USES_PLUGINS + if (mixer->v_grp) { + grp = mixer->v_grp; + ctl = grp->ctl; + + for (n = 0; n < grp->count; n++) { + if (!strcmp(name, (char*) ctl[n].info.id.name) && + device == ctl[n].info.id.device) { + return ctl + n; + } + } + } +#endif + return NULL; +} + /** Updates the control's info. * This is useful for a program that may be idle for a period of time. * @param ctl An initialized control handle. @@ -822,6 +871,14 @@ const char *mixer_ctl_get_name(const struct mixer_ctl *ctl) return (const char *)ctl->info.id.name; } +unsigned int mixer_ctl_get_device(const struct mixer_ctl *ctl) +{ + if (!ctl) + return UINT_MAX; + + return ctl->info.id.device; +} + /** Gets the value type of the control. * @param ctl An initialized control handle * @returns On success, the type of mixer control. -- cgit v1.2.3 From 4516c73951d861e974f338540b026285148dc426 Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Tue, 30 May 2023 20:34:51 +0530 Subject: utils: tinymix: Print device number associated with mixer controls For mixer controls with same name and different device number, there is no clarity in tinymix output. Print device number along with mixer control name to distinguish between mixer controls with same name. --- utils/tinymix.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/utils/tinymix.c b/utils/tinymix.c index e272ade..f0e1d95 100644 --- a/utils/tinymix.c +++ b/utils/tinymix.c @@ -201,7 +201,7 @@ static void list_controls(struct mixer *mixer, int print_all) { struct mixer_ctl *ctl; const char *name, *type; - unsigned int num_ctls, num_values; + unsigned int num_ctls, num_values, device; unsigned int i; num_ctls = mixer_get_num_ctls(mixer); @@ -209,9 +209,9 @@ static void list_controls(struct mixer *mixer, int print_all) printf("Number of controls: %u\n", num_ctls); if (print_all) - printf("ctl\ttype\tnum\t%-40svalue\n", "name"); + printf("ctl\ttype\tnum\t%-40s\tdevice\tvalue\n", "name"); else - printf("ctl\ttype\tnum\t%-40s\n", "name"); + printf("ctl\ttype\tnum\t%-40s\tdevice\n", "name"); for (i = 0; i < num_ctls; i++) { ctl = mixer_get_ctl(mixer, i); @@ -219,7 +219,8 @@ static void list_controls(struct mixer *mixer, int print_all) name = mixer_ctl_get_name(ctl); type = mixer_ctl_get_type_string(ctl); num_values = mixer_ctl_get_num_values(ctl); - printf("%u\t%s\t%u\t%-40s", i, type, num_values, name); + device = mixer_ctl_get_dev_num(ctl); + printf("%u\t%s\t%u\t%-40s\t%u", i, type, num_values, name, device); if (print_all) print_control_values(ctl); printf("\n"); -- cgit v1.2.3