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