Implement volume and mute controls
authorMikko Rasa <mikko.rasa@movial.fi>
Wed, 29 Oct 2008 09:54:56 +0000 (11:54 +0200)
committerMikko Rasa <mikko.rasa@movial.fi>
Wed, 29 Oct 2008 09:54:56 +0000 (11:54 +0200)
data/gstreamer.ocd
src/octopus-backend-gst.c
src/octopus-backend.c
src/octopus-backend.h
src/octopus-dbus.xml
src/octopus-route.c
src/octopus-route.h
src/octopus-server.c
src/octopus-server.h

index f81514d..640acae 100644 (file)
@@ -26,6 +26,7 @@ component dec_mp3mad
 
 component sink_alsasink
        element audioconvert
+       element volume
        element alsasink
                sink local-audio-alsa
 
index b86d5f8..ce28279 100644 (file)
@@ -62,6 +62,14 @@ pause_route(OctopusBackend *backend,
 static gboolean
 stop_route(OctopusBackend *backend,
            OctopusRoute   *route);
+static gboolean
+set_route_muted(OctopusBackend *backend,
+                OctopusRoute   *route,
+                gboolean       muted);
+static gboolean
+set_route_volume(OctopusBackend *backend,
+                 OctopusRoute   *route,
+                 gdouble        volume);
 
 static void
 route_mapping_changed(OctopusRoute *route,
@@ -111,6 +119,8 @@ octopus_backend_gst_class_init(OctopusBackendGstClass *klass)
   backend->play_route = play_route;
   backend->pause_route = pause_route;
   backend->stop_route = stop_route;
+  backend->set_route_muted = set_route_muted;
+  backend->set_route_volume = set_route_volume;
 
   hooks[HOOK_INIT] = 
     g_signal_new ("hook-init",
@@ -192,6 +202,29 @@ can_maybe_sink_caps(GstElementFactory *factory,
   return result;
 }
 
+static gboolean
+set_property_all(OctopusRoute *route,
+                 const gchar  *prop_name,
+                 const GValue *value)
+{
+  RouteDataGst *data;
+  GstIterator  *iter;
+  gpointer     elem;
+  gboolean     ret = FALSE;
+
+  data = (RouteDataGst *)g_object_get_data(G_OBJECT(route), "data");
+  iter = gst_bin_iterate_recurse(GST_BIN(data->pipeline));
+  while(gst_iterator_next(iter, &elem) == GST_ITERATOR_OK) {
+    if(g_object_class_find_property(G_OBJECT_GET_CLASS(elem), prop_name)) {
+      g_object_set_property(G_OBJECT(elem), prop_name, value);
+      ret = TRUE;
+    }
+  }
+  gst_iterator_free(iter);
+
+  return ret;
+}
+
 /*
  * OctopusBackend implementation
  */
@@ -370,6 +403,38 @@ stop_route(OctopusBackend *backend,
   return TRUE;
 }
 
+static gboolean
+set_route_muted(OctopusBackend *backend,
+                OctopusRoute   *route,
+                gboolean       muted)
+{
+  GValue   value = {0};
+  gboolean ret;
+
+  g_value_init(&value, G_TYPE_BOOLEAN);
+  g_value_set_boolean(&value, muted);
+  ret = set_property_all(route, "mute", &value);
+  g_value_unset(&value);
+
+  return ret;
+}
+
+static gboolean
+set_route_volume(OctopusBackend *backend,
+                 OctopusRoute   *route,
+                 gdouble        volume)
+{
+  GValue   value = {0};
+  gboolean ret;
+
+  g_value_init(&value, G_TYPE_DOUBLE);
+  g_value_set_double(&value, volume);
+  ret = set_property_all(route, "volume", &value);
+  g_value_unset(&value);
+
+  return ret;
+}
+
 /*
  * Private functions
  */
index b3bcfeb..e91e7f6 100644 (file)
@@ -403,10 +403,28 @@ octopus_backend_pause_route(OctopusBackend *backend,
 
 gboolean
 octopus_backend_stop_route(OctopusBackend *backend,
-                          OctopusRoute   *route)
+                           OctopusRoute   *route)
 {
   g_assert(OCTOPUS_IS_BACKEND(backend));
   return OCTOPUS_BACKEND_GET_CLASS(backend)->stop_route(backend, route);
 }
 
+gboolean
+octopus_backend_set_route_muted(OctopusBackend *backend,
+                                OctopusRoute   *route,
+                                gboolean       muted)
+{
+  g_assert(OCTOPUS_IS_BACKEND(backend));
+  return OCTOPUS_BACKEND_GET_CLASS(backend)->set_route_muted(backend, route, muted);
+}
+
+gboolean
+octopus_backend_set_route_volume(OctopusBackend *backend,
+                                 OctopusRoute   *route,
+                                 gdouble        volume)
+{
+  g_assert(OCTOPUS_IS_BACKEND(backend));
+  return OCTOPUS_BACKEND_GET_CLASS(backend)->set_route_volume(backend, route, volume);
+}
+
 // vim: filetype=c:expandtab:shiftwidth=2:tabstop=2:softtabstop=2
index 46d0516..d1cc317 100644 (file)
@@ -80,6 +80,12 @@ struct _OctopusBackendClass {
                                       OctopusRoute *);
   gboolean     (*stop_route)         (OctopusBackend *,
                                       OctopusRoute *);
+  gboolean     (*set_route_muted)    (OctopusBackend *,
+                                      OctopusRoute *,
+                                      gboolean);
+  gboolean     (*set_route_volume)   (OctopusBackend *,
+                                      OctopusRoute *,
+                                      gdouble);
 };
 
 struct _OctopusParameter {
@@ -139,6 +145,14 @@ octopus_backend_pause_route              (OctopusBackend *backend,
 gboolean
 octopus_backend_stop_route               (OctopusBackend *backend,
                                           OctopusRoute   *route);
+gboolean
+octopus_backend_set_route_muted          (OctopusBackend *backend,
+                                          OctopusRoute   *route,
+                                          gboolean       muted);
+gboolean
+octopus_backend_set_route_volume         (OctopusBackend *backend,
+                                          OctopusRoute   *route,
+                                          gdouble        volume);
 
 #endif
 
index 4df4b92..097099c 100644 (file)
 
     <!-- Module Manager API -->
 
-<!--
-    <method name="GetSrcModules">
-      <arg type="as" direction="out" />
-    </method>
-
-    <method name="GetDestModules">
-      <arg type="as" direction="out" />
-    </method>
-
-    <method name="GetActiveRoutes">
-      <arg type="as" direction="out" />
-    </method>
--->
-
     <method name="New">
       <arg type="u" direction="out" />
     </method>
@@ -86,7 +72,7 @@
       <arg type="s" direction="out" name="uri" />
     </method>
 
- <!-- Set the display name and window xid -->
   <!-- Set the display name and window xid -->
     <method name="SetX11Display">
       <arg type="u" direction="in" name="id" />
       <arg type="s" direction="in" name="endpoint" />
       <arg type="u" name="id" direction="in" />
     </method>
 
+    <!-- Mute audio output of the pipeline -->
+    <method name="SetMuted">
+      <!-- 0 for a global mute -->
+      <arg type="u" name="id" direction="in" />
+      <arg type="b" name="muted" direction="in" />
+    </method>
+
+    <!-- Set volume of the pipeline -->
+    <method name="SetVolume">
+      <!-- 0 for a global volume -->
+      <arg type="u" name="id" direction="in" />
+      <!-- 0.0 - 1.0 -->
+      <arg type="d" name="volume" direction="in" />
+    </method>
+
     <!-- Playback signals -->
 
     <!-- Emitted when the playback fails  -->
index f05f5b3..0b0ecc9 100644 (file)
@@ -380,6 +380,20 @@ octopus_route_stop(OctopusRoute *route)
   return octopus_backend_stop_route(route->priv->backend, route);
 }
 
+gboolean
+octopus_route_set_muted(OctopusRoute *route,
+                        gboolean     muted)
+{
+  return octopus_backend_set_route_muted(route->priv->backend, route, muted);
+}
+
+gboolean
+octopus_route_set_volume(OctopusRoute *route,
+                         gdouble      volume)
+{
+  return octopus_backend_set_route_volume(route->priv->backend, route, volume);
+}
+
 void
 octopus_route_playback_error(OctopusRoute *route,
                              const gchar  *error)
index 31c728b..694f219 100644 (file)
@@ -95,6 +95,12 @@ gboolean
 octopus_route_pause                    (OctopusRoute *route);
 gboolean
 octopus_route_stop                     (OctopusRoute *route);
+gboolean
+octopus_route_set_muted                (OctopusRoute *route,
+                                        gboolean     muted);
+gboolean
+octopus_route_set_volume               (OctopusRoute *route,
+                                        gdouble      volume);
 
 void
 octopus_route_playback_error           (OctopusRoute *route,
index 902441c..e096c17 100644 (file)
@@ -318,7 +318,7 @@ octopus_server_set_mapping(OctopusServer   *server,
 {
   OctopusRoute *route;
 
-  g_assert(OCTOPUS_IS_SERVER (server));
+  g_assert(OCTOPUS_IS_SERVER(server));
 
   if(!(route = get_route_by_id(server, id, error)))
     return FALSE;
@@ -340,7 +340,7 @@ octopus_server_get_mapping(OctopusServer   *server,
 {
   OctopusRoute *route;
 
-  g_assert(OCTOPUS_IS_SERVER (server));
+  g_assert(OCTOPUS_IS_SERVER(server));
 
   if(!(route = get_route_by_id(server, id, error)))
     return FALSE;
@@ -358,7 +358,7 @@ octopus_server_force_pipeline  (OctopusServer   *server,
 {
   OctopusRoute *route;
 
-  g_assert(OCTOPUS_IS_SERVER (server));
+  g_assert(OCTOPUS_IS_SERVER(server));
 
   if(!(route = get_route_by_id(server, id, error)))
     return FALSE;
@@ -381,7 +381,7 @@ octopus_server_set_endpoint_uri(OctopusServer   *server,
 {
   OctopusRoute *route;
 
-  g_assert(OCTOPUS_IS_SERVER (server));
+  g_assert(OCTOPUS_IS_SERVER(server));
 
   if(!(route = get_route_by_id(server, id, error)))
     return FALSE;
@@ -405,7 +405,7 @@ octopus_server_get_endpoint_uri(OctopusServer   *server,
   OctopusRoute          *route;
   const OctopusEndpoint *endpoint;
 
-  g_assert(OCTOPUS_IS_SERVER (server));
+  g_assert(OCTOPUS_IS_SERVER(server));
 
   if(!(route = get_route_by_id(server, id, error)))
     return FALSE;
@@ -430,7 +430,7 @@ octopus_server_set_x11_display(OctopusServer   *server,
 {
   OctopusRoute *route;
 
-  g_assert(OCTOPUS_IS_SERVER (server));
+  g_assert(OCTOPUS_IS_SERVER(server));
 
   if(!(route = get_route_by_id(server, id, error)))
     return FALSE;
@@ -450,7 +450,7 @@ octopus_server_play(OctopusServer  *server,
 {
   OctopusRoute *route;
 
-  g_assert(OCTOPUS_IS_SERVER (server));
+  g_assert(OCTOPUS_IS_SERVER(server));
 
   if(!(route = get_route_by_id(server, id, error)))
     return FALSE;
@@ -470,7 +470,7 @@ octopus_server_pause(OctopusServer *server,
 {
   OctopusRoute *route;
 
-  g_assert(OCTOPUS_IS_SERVER (server));
+  g_assert(OCTOPUS_IS_SERVER(server));
 
   if(!(route = get_route_by_id(server, id, error)))
     return FALSE;
@@ -490,7 +490,7 @@ octopus_server_stop(OctopusServer  *server,
 {
   OctopusRoute *route;
 
-  g_assert(OCTOPUS_IS_SERVER (server));
+  g_assert(OCTOPUS_IS_SERVER(server));
 
   if(!(route = get_route_by_id(server, id, error)))
     return FALSE;
@@ -503,6 +503,49 @@ octopus_server_stop(OctopusServer  *server,
   return TRUE;
 }
 
+/* XXX Implement global mute/volume */
+gboolean
+octopus_server_set_muted(OctopusServer  *server,
+                         guint32        id,
+                         gboolean       muted,
+                         GError         **error)
+{
+  OctopusRoute *route;
+
+  g_assert(OCTOPUS_IS_SERVER(server));
+
+  if(!(route = get_route_by_id(server, id, error)))
+    return FALSE;
+
+  if(!octopus_route_set_muted(route, muted)) {
+    g_set_error(error, OCTOPUS_SERVER_ERROR, OCTOPUS_SERVER_ERROR_FAILED, "Could not mute/unmute route");
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+gboolean
+octopus_server_set_volume(OctopusServer  *server,
+                          guint32        id,
+                          gdouble        volume,
+                          GError         **error)
+{
+  OctopusRoute *route;
+
+  g_assert(OCTOPUS_IS_SERVER(server));
+
+  if(!(route = get_route_by_id(server, id, error)))
+    return FALSE;
+
+  if(!octopus_route_set_volume(route, volume)) {
+    g_set_error(error, OCTOPUS_SERVER_ERROR, OCTOPUS_SERVER_ERROR_FAILED, "Could not set route volume");
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
 /*
  * D-Bus API signals
  */
index d29ac97..d4adbaf 100644 (file)
@@ -143,6 +143,16 @@ gboolean
 octopus_server_stop            (OctopusServer  *server,
                                 guint32        id,
                                 GError         **error);
+gboolean
+octopus_server_set_muted       (OctopusServer  *server,
+                                guint32        id,
+                                gboolean       muted,
+                                GError         **error);
+gboolean
+octopus_server_set_volume      (OctopusServer  *server,
+                                guint32        id,
+                                gdouble        volume,
+                                GError         **error);
 
 G_END_DECLS