diff --git a/modules/module-pw-audio-softdsp-endpoint.c b/modules/module-pw-audio-softdsp-endpoint.c
index 0bbb1220a03a6397b54856bd374d68b01a751802..4fb0c148439b323cf612b1143af3b83de132464f 100644
--- a/modules/module-pw-audio-softdsp-endpoint.c
+++ b/modules/module-pw-audio-softdsp-endpoint.c
@@ -23,6 +23,7 @@
 
 #define MIN_QUANTUM_SIZE  64
 #define MAX_QUANTUM_SIZE  1024
+#define CONTROL_SELECTED 0
 
 static const char * streams[] = {
   "multimedia",
@@ -40,6 +41,8 @@ struct _WpPwAudioSoftdspEndpoint
   guint global_id;
   guint stream_count;
 
+  gboolean selected;
+
   /* The task to signal the endpoint is initialized */
   GTask *init_task;
 
@@ -298,12 +301,16 @@ endpoint_get_control_value (WpEndpoint * ep, guint32 id)
   guint stream_id, control_id;
   WpPwAudioDsp *stream = NULL;
 
+  if (id == CONTROL_SELECTED)
+    return g_variant_new_boolean (self->selected);
+
+  wp_pw_audio_dsp_id_decode (id, &stream_id, &control_id);
+
   /* 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);
+  if (stream_id == WP_STREAM_ID_NONE)
+    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);
@@ -317,12 +324,19 @@ endpoint_set_control_value (WpEndpoint * ep, guint32 id, GVariant * value)
   guint stream_id, control_id;
   WpPwAudioDsp *stream = NULL;
 
+  if (id == CONTROL_SELECTED) {
+    self->selected = g_variant_get_boolean (value);
+    wp_endpoint_notify_control_value (ep, CONTROL_SELECTED);
+    return TRUE;
+  }
+
+  wp_pw_audio_dsp_id_decode (id, &stream_id, &control_id);
+
   /* 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);
+  if (stream_id == WP_STREAM_ID_NONE)
+    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);
@@ -336,6 +350,7 @@ wp_endpoint_init_async (GAsyncInitable *initable, int io_priority,
   WpPwAudioSoftdspEndpoint *self = WP_PW_AUDIO_SOFTDSP_ENDPOINT (initable);
   g_autoptr (WpCore) core = wp_endpoint_get_core(WP_ENDPOINT(self));
   const gchar *media_class = wp_endpoint_get_media_class (WP_ENDPOINT (self));
+  GVariantDict d;
 
   /* Create the async task */
   self->init_task = g_task_new (initable, cancellable, callback, data);
@@ -354,6 +369,15 @@ wp_endpoint_init_async (GAsyncInitable *initable, int io_priority,
   g_signal_connect_object(self->remote_pipewire, "global-added::port",
       (GCallback)on_port_added, self, 0);
 
+  /* Register the selected control */
+  self->selected = FALSE;
+  g_variant_dict_init (&d, NULL);
+  g_variant_dict_insert (&d, "id", "u", 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);
+  wp_endpoint_register_control (WP_ENDPOINT (self), g_variant_dict_end (&d));
+
   /* Call the parent interface */
   wp_endpoint_parent_interface->init_async (initable, io_priority, cancellable,
       callback, data);
diff --git a/modules/module-pw-audio-softdsp-endpoint/dsp.c b/modules/module-pw-audio-softdsp-endpoint/dsp.c
index 62bdb931dbb82919492b42c05d62403def65b4e6..d1a3a28777fd5a78a6e97f79fc32cfbfe095c97f 100644
--- a/modules/module-pw-audio-softdsp-endpoint/dsp.c
+++ b/modules/module-pw-audio-softdsp-endpoint/dsp.c
@@ -29,9 +29,6 @@ enum {
 enum {
   CONTROL_VOLUME = 0,
   CONTROL_MUTE,
-  N_DEFAULT_CONTROLS,
-  /* Master controls only */
-  CONTROL_SELECTED,
   N_CONTROLS,
 };
 
@@ -67,7 +64,6 @@ struct _WpPwAudioDsp
   /* Volume */
   gfloat volume;
   gboolean mute;
-  gboolean selected;
 };
 
 static void wp_pw_audio_dsp_async_initable_init (gpointer iface,
@@ -77,24 +73,18 @@ 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;
-  }
+  g_return_val_if_fail (control_id < N_CONTROLS, 0);
+
+  /* encode NONE as 0 and everything else with +1 */
+  /* NONE is MAX_UINT, so +1 will do the trick */
+  stream_id += 1;
 
-  /* 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;
+  /* Encode the stream and control Ids. The first ID is reserved
+   * for the "selected" control, registered in the endpoint */
+  return 1 + (stream_id * N_CONTROLS) + control_id;
 }
 
 void
@@ -102,10 +92,12 @@ wp_pw_audio_dsp_id_decode (guint id, guint *stream_id, guint *control_id)
 {
   guint s_id, c_id;
 
+  g_return_if_fail (id >= 1);
+  id -= 1;
+
   /* 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;
+  s_id = (id / N_CONTROLS) - 1;
+  c_id = id % N_CONTROLS;
 
   /* Set the output params */
   if (stream_id)
@@ -143,17 +135,6 @@ register_controls (WpPwAudioDsp * self)
   g_variant_dict_insert (&d, "type", "s", "b");
   g_variant_dict_insert (&d, "default-value", "b", self->mute);
   wp_endpoint_register_control (ep, g_variant_dict_end (&d));
-
-  /* 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",
-        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);
-    wp_endpoint_register_control (ep, g_variant_dict_end (&d));
-  }
 }
 
 static void
@@ -320,11 +301,13 @@ audio_dsp_event_param (void *object, int seq, uint32_t id,
 
       if (self->volume != volume) {
         self->volume = volume;
-        wp_endpoint_notify_control_value (WP_ENDPOINT (self), CONTROL_VOLUME);
+        wp_endpoint_notify_control_value (WP_ENDPOINT (self),
+            wp_pw_audio_dsp_id_encode (self->id, CONTROL_VOLUME));
       }
       if (self->mute != mute) {
         self->mute = mute;
-        wp_endpoint_notify_control_value (WP_ENDPOINT (self), CONTROL_MUTE);
+        wp_endpoint_notify_control_value (WP_ENDPOINT (self),
+            wp_pw_audio_dsp_id_encode (self->id, CONTROL_MUTE));
       }
 
       break;
@@ -487,10 +470,9 @@ wp_pw_audio_dsp_init_async (GAsyncInitable *initable, int io_priority,
   /* Init the list of port proxies */
   self->port_proxies = g_ptr_array_new_full(4, (GDestroyNotify)g_object_unref);
 
-  /* Set the volume */
+  /* Set the default volume */
   self->volume = 1.0;
   self->mute = FALSE;
-  self->selected = FALSE;
 
   /* Create the properties */
   props = pw_properties_new_dict(self->target->props);
@@ -648,10 +630,6 @@ wp_pw_audio_dsp_get_control_value (WpPwAudioDsp * self, guint32 control_id)
       return g_variant_new_double (self->volume);
     case CONTROL_MUTE:
       return g_variant_new_boolean (self->mute);
-    case CONTROL_SELECTED:
-      if (self->id == WP_STREAM_ID_NONE)
-        return g_variant_new_boolean (self->selected);
-      return NULL;
     default:
       g_warning ("Unknown control id %u", control_id);
       return NULL;
@@ -667,8 +645,6 @@ wp_pw_audio_dsp_set_control_value (WpPwAudioDsp * self, guint32 control_id,
   struct pw_node_proxy *pw_proxy = NULL;
   float volume;
   bool mute;
-  g_autoptr (WpEndpoint) ep = g_weak_ref_get (&self->endpoint);
-  g_return_val_if_fail (ep, FALSE);
 
   /* Get the pipewire dsp proxy */
   g_return_val_if_fail (self->proxy, FALSE);
@@ -708,13 +684,6 @@ wp_pw_audio_dsp_set_control_value (WpPwAudioDsp * self, guint32 control_id,
           NULL);
       break;
 
-    case CONTROL_SELECTED:
-      if (self->id == WP_STREAM_ID_NONE) {
-        self->selected = g_variant_get_boolean (value);
-        wp_endpoint_notify_control_value (ep, CONTROL_SELECTED);
-      }
-      break;
-
     default:
       g_warning ("Unknown control id %u", control_id);
       return FALSE;
diff --git a/modules/module-pw-audio-softdsp-endpoint/dsp.h b/modules/module-pw-audio-softdsp-endpoint/dsp.h
index c1b4c8bf08f01a980098136b046d910c701767bc..484158448b67f98bc3b8e05defcb1a375a060478 100644
--- a/modules/module-pw-audio-softdsp-endpoint/dsp.h
+++ b/modules/module-pw-audio-softdsp-endpoint/dsp.h
@@ -15,7 +15,6 @@
 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);