From 7d1e860b7d340715a197f51008452ee1fe82c7c1 Mon Sep 17 00:00:00 2001
From: Julian Bouzas <julian.bouzas@collabora.com>
Date: Thu, 4 Jul 2019 08:16:31 -0400
Subject: [PATCH] softdsp-endpoint: change the control value properly

---
 modules/module-pw-audio-softdsp-endpoint.c    | 35 ++++++++++----
 .../module-pw-audio-softdsp-endpoint/dsp.c    | 48 +++++++++++++++++--
 .../module-pw-audio-softdsp-endpoint/dsp.h    |  4 ++
 3 files changed, 75 insertions(+), 12 deletions(-)

diff --git a/modules/module-pw-audio-softdsp-endpoint.c b/modules/module-pw-audio-softdsp-endpoint.c
index b87f0c2f..433e78b8 100644
--- a/modules/module-pw-audio-softdsp-endpoint.c
+++ b/modules/module-pw-audio-softdsp-endpoint.c
@@ -292,24 +292,41 @@ endpoint_get_property (GObject * object, guint property_id,
 }
 
 static GVariant *
-endpoint_get_control_value (WpEndpoint * ep, guint32 control_id)
+endpoint_get_control_value (WpEndpoint * ep, guint32 id)
 {
   WpPwAudioSoftdspEndpoint *self = WP_PW_AUDIO_SOFTDSP_ENDPOINT (ep);
+  guint stream_id, control_id;
+  WpPwAudioDsp *stream = NULL;
+
+  /* Check if it is the master stream */
+  if (wp_pw_audio_dsp_id_is_master (id))
+    return wp_pw_audio_dsp_get_control_value (self->converter, id);
 
-  /* TODO: We always set the controls in the converter. This needs to change
-   * and select the proper stream once the stream id is passed as a parameter */
-  return wp_pw_audio_dsp_get_control_value (self->converter, control_id);
+  /* Otherwise get the stream_id and control_id */
+  wp_pw_audio_dsp_id_decode (id, &stream_id, &control_id);
+  g_return_val_if_fail (stream_id < N_STREAMS, NULL);
+  stream = self->streams[stream_id];
+  g_return_val_if_fail (stream, NULL);
+  return wp_pw_audio_dsp_get_control_value (stream, control_id);
 }
 
 static gboolean
-endpoint_set_control_value (WpEndpoint * ep, guint32 control_id,
-    GVariant * value)
+endpoint_set_control_value (WpEndpoint * ep, guint32 id, GVariant * value)
 {
   WpPwAudioSoftdspEndpoint *self = WP_PW_AUDIO_SOFTDSP_ENDPOINT (ep);
+  guint stream_id, control_id;
+  WpPwAudioDsp *stream = NULL;
+
+  /* Check if it is the master stream */
+  if (wp_pw_audio_dsp_id_is_master (id))
+    return wp_pw_audio_dsp_set_control_value (self->converter, id, value);
 
-  /* TODO: We always set the controls in the converter. This needs to change
-   * and select the proper stream once the stream id is passed as a parameter */
-  return wp_pw_audio_dsp_set_control_value (self->converter, control_id, value);
+  /* Otherwise get the stream_id and control_id */
+  wp_pw_audio_dsp_id_decode (id, &stream_id, &control_id);
+  g_return_val_if_fail (stream_id < N_STREAMS, FALSE);
+  stream = self->streams[stream_id];
+  g_return_val_if_fail (stream, FALSE);
+  return wp_pw_audio_dsp_set_control_value (stream, control_id, value);
 }
 
 static void
diff --git a/modules/module-pw-audio-softdsp-endpoint/dsp.c b/modules/module-pw-audio-softdsp-endpoint/dsp.c
index f9e51334..c1d214fc 100644
--- a/modules/module-pw-audio-softdsp-endpoint/dsp.c
+++ b/modules/module-pw-audio-softdsp-endpoint/dsp.c
@@ -29,6 +29,8 @@ enum {
 enum {
   CONTROL_VOLUME = 0,
   CONTROL_MUTE,
+  N_DEFAULT_CONTROLS,
+  /* Master controls only */
   CONTROL_SELECTED,
   N_CONTROLS,
 };
@@ -75,6 +77,43 @@ G_DEFINE_TYPE_WITH_CODE (WpPwAudioDsp, wp_pw_audio_dsp, G_TYPE_OBJECT,
     G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
                            wp_pw_audio_dsp_async_initable_init))
 
+gboolean
+wp_pw_audio_dsp_id_is_master (guint id)
+{
+  return id < N_CONTROLS;
+}
+
+guint
+wp_pw_audio_dsp_id_encode (guint stream_id, guint control_id)
+{
+  /* Just use the cotnrol_id if the stream id is not valid */
+  if (stream_id == WP_STREAM_ID_NONE) {
+    g_return_val_if_fail (control_id < N_CONTROLS, 0);
+    return control_id;
+  }
+
+  /* Encode the stream and control Ids */
+  g_return_val_if_fail (control_id < N_DEFAULT_CONTROLS, 0);
+  return N_CONTROLS + (stream_id * N_DEFAULT_CONTROLS) + control_id;
+}
+
+void
+wp_pw_audio_dsp_id_decode (guint id, guint *stream_id, guint *control_id)
+{
+  guint s_id, c_id;
+
+  /* Decode the stream and control Ids */
+  g_return_if_fail (id >= N_CONTROLS);
+  s_id = (id - N_CONTROLS) / N_DEFAULT_CONTROLS;
+  c_id = (id - N_CONTROLS) % N_DEFAULT_CONTROLS;
+
+  /* Set the output params */
+  if (stream_id)
+    *stream_id = s_id;
+  if (control_id)
+    *control_id = c_id;
+}
+
 static void
 register_controls (WpPwAudioDsp * self)
 {
@@ -84,7 +123,8 @@ register_controls (WpPwAudioDsp * self)
 
   /* Register the volume control */
   g_variant_dict_init (&d, NULL);
-  g_variant_dict_insert (&d, "id", "u", CONTROL_VOLUME);
+  g_variant_dict_insert (&d, "id", "u",
+      wp_pw_audio_dsp_id_encode (self->id, CONTROL_VOLUME));
   g_variant_dict_insert (&d, "stream-id", "u", self->id);
   g_variant_dict_insert (&d, "name", "s", "volume");
   g_variant_dict_insert (&d, "type", "s", "d");
@@ -94,7 +134,8 @@ register_controls (WpPwAudioDsp * self)
 
   /* Register the mute control */
   g_variant_dict_init (&d, NULL);
-  g_variant_dict_insert (&d, "id", "u", CONTROL_MUTE);
+  g_variant_dict_insert (&d, "id", "u",
+      wp_pw_audio_dsp_id_encode (self->id, CONTROL_MUTE));
   g_variant_dict_insert (&d, "stream-id", "u", self->id);
   g_variant_dict_insert (&d, "name", "s", "mute");
   g_variant_dict_insert (&d, "type", "s", "b");
@@ -104,7 +145,8 @@ register_controls (WpPwAudioDsp * self)
   /* Register the selected control only if it is the master converter */
   if (self->id == WP_STREAM_ID_NONE) {
     g_variant_dict_init (&d, NULL);
-    g_variant_dict_insert (&d, "id", "u", CONTROL_SELECTED);
+    g_variant_dict_insert (&d, "id", "u",
+        wp_pw_audio_dsp_id_encode (self->id, CONTROL_SELECTED));
     g_variant_dict_insert (&d, "name", "s", "selected");
     g_variant_dict_insert (&d, "type", "s", "b");
     g_variant_dict_insert (&d, "default-value", "b", self->selected);
diff --git a/modules/module-pw-audio-softdsp-endpoint/dsp.h b/modules/module-pw-audio-softdsp-endpoint/dsp.h
index 5535832c..c1b4c8bf 100644
--- a/modules/module-pw-audio-softdsp-endpoint/dsp.h
+++ b/modules/module-pw-audio-softdsp-endpoint/dsp.h
@@ -15,6 +15,10 @@
 G_DECLARE_FINAL_TYPE (WpPwAudioDsp, wp_pw_audio_dsp,
     WP_PW, AUDIO_DSP, GObject)
 
+gboolean wp_pw_audio_dsp_id_is_master (guint id);
+guint wp_pw_audio_dsp_id_encode (guint stream_id, guint control_id);
+void wp_pw_audio_dsp_id_decode (guint id, guint *stream_id, guint *control_id);
+
 void wp_pw_audio_dsp_new (WpEndpoint *endpoint, guint id, const char *name,
     enum pw_direction direction, const struct pw_node_info *target,
     const struct spa_audio_info_raw *format, GAsyncReadyCallback callback,
-- 
GitLab