aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRohit kumar <quic_rohkumar@quicinc.com>2023-05-30 20:27:35 +0530
committerRohit kumar <quic_rohkumar@quicinc.com>2023-09-04 15:26:14 +0530
commita8a581fb422c9c2af2d8858a678c008db80e1e3c (patch)
tree863ad03decd80b18453d20c217a78a586ea4cb8f
parent4fbaeef03cd1cb216e0f356c0433ca70f8b9c464 (diff)
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.
-rw-r--r--include/tinyalsa/mixer.h6
-rw-r--r--src/mixer.c57
2 files changed, 63 insertions, 0 deletions
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.