One quick question about canberra-gtk-play.  Is this program intended
to be run by end-users, or only by libcanberra internally?  I am
wondering if it makes more sense in /usr/bin or /usr/libexec.  I suspect
it might make more sense in /usr/libexec?

The main topic I wanted to discuss is adding some GStreamer backend
support to libcanberra.

For Solaris, we need to get Canberra working to support system sounds.
I would like to avoid writing a SunAudio backend since I know that Sun
is in the middle of rewriting the low-level Sun Audio interfaces, and
seems to be moving towards an OSS based solution.

So, it sort of seems to make sense to write a GStreamer backend that
could be used as a fallback if the OS does not support any other
backends that talk directly to the audio devices (such as ALSA or
OSS).

I wrote the attached patch which just makes canberra support GStreamer
via the gst-launch system command to play the specified audio file.
This just seemed simpler and more straightforward than using the
GStreamer library interfaces directly.  It also seems to work reasonably
well on Solaris.

However, for this to work I had to add a new interface
(ca_sound_get_filename) to read-sound-file.[ch] since the filename
that the gst-launch command needs is not otherwise exposed.

Is this a reasonable way to solve the libcanberra backend problem
(at least for now) on Solaris?  Or do people think it is really
necessary to write code that links with the GStreamer or Sun Audio
interfaces directly?

Thoughts?

Brian
--- libcanberra-0.6/configure.ac-orig	2008-08-19 18:48:57.904018000 -0500
+++ libcanberra-0.6/configure.ac	2008-08-20 00:55:56.214638000 -0500
@@ -219,6 +219,38 @@ fi
 AC_SUBST(ALSA_CFLAGS)
 AC_SUBST(ALSA_LIBS)
 
+#### GStreamer support (optional) ####
+
+AC_ARG_ENABLE([gstreamer],
+    AC_HELP_STRING([--disable-gstreamer], [Disable optional GStreamer support]),
+        [
+            case "${enableval}" in
+                yes) gstreamer=yes ;;
+                no) gstreamer=no ;;
+                *) AC_MSG_ERROR(bad value ${enableval} for --disable-gstreamer) ;;
+            esac
+        ],
+        [gstreamer=auto])
+
+if test "x${gstreamer}" != xno ; then
+    PKG_CHECK_MODULES(GSTREAMER, [ gstreamer-0.10 ],
+        [
+            HAVE_GSTREAMER=1
+            AC_DEFINE([HAVE_GSTREAMER], 1, [Have GStreamer?])
+        ],
+        [
+            HAVE_GSTREAMER=0
+            if test "x$gstreamer" = xyes ; then
+                AC_MSG_ERROR([*** GStreamer not found ***])
+            fi
+        ])
+else
+    HAVE_GSTREAMER=0
+fi
+
+AC_SUBST(GSTREAMER_CFLAGS)
+AC_SUBST(GSTREAMER_LIBS)
+
 ### PulseAudio (optional) ####
 
 AC_ARG_ENABLE([pulse],
@@ -390,6 +422,7 @@ AC_SUBST(BUILTIN_ALSA)
 AC_SUBST(BUILTIN_NULL)
 AM_CONDITIONAL([HAVE_PULSE], [test "x$HAVE_PULSE" = x1])
 AM_CONDITIONAL([HAVE_ALSA], [test "x$HAVE_ALSA" = x1])
+AM_CONDITIONAL([HAVE_GSTREAMER], [test "x$HAVE_GSTREAMER" = x1])
 AM_CONDITIONAL([HAVE_NULL], [test "x$HAVE_NULL" = x1])
 AM_CONDITIONAL([BUILTIN_DSO], [test "x$BUILTIN_DSO" = x1])
 AM_CONDITIONAL([BUILTIN_PULSE], [test "x$BUILTIN_PULSE" = x1])
@@ -435,6 +468,11 @@ if test "x$BUILTIN_ALSA" = "x1" ; then
    ENABLE_BUILTIN_ALSA=yes
 fi
 
+ENABLE_GSTREAMER=no
+if test "x$HAVE_GSTREAMER" = "x1" ; then
+   ENABLE_GSTREAMER=yes
+fi
+
 ENABLE_NULL=no
 if test "x$HAVE_NULL" = "x1" ; then
    ENABLE_NULL=yes
@@ -464,6 +502,7 @@ echo "
     Builtin PulseAudio:     ${ENABLE_BUILTIN_PULSE}
     Enable ALSA:            ${ENABLE_ALSA}
     Builtin ALSA:           ${ENABLE_BUILTIN_ALSA}
+    Enable GStreamer:       ${ENABLE_GSTREAMER}
     Enable Null Output:     ${ENABLE_NULL}
     Builtin Null Output:    ${ENABLE_BUILTIN_NULL}
     Enable GTK+:            ${ENABLE_GTK}
--- libcanberra-0.6/src/Makefile.am-orig	2008-08-19 18:47:03.375192000 -0500
+++ libcanberra-0.6/src/Makefile.am	2008-08-19 19:18:56.296563000 -0500
@@ -162,6 +162,41 @@ libcanberra_alsa_la_LDFLAGS = \
 endif
 endif
 
+if HAVE_GSTREAMER
+
+# Comment out builtin stuff for now.
+#
+#libcanberra_la_SOURCES += \
+#	gstreamer.c
+#libcanberra_la_CFLAGS += \
+#	$(GSTREAMER_CFLAGS)
+#libcanberra_la_LIBADD += \
+#	 $(GSTREAMER_LIBS)
+#
+#else
+
+plugin_LTLIBRARIES += \
+	libcanberra-gstreamer.la
+
+libcanberra_gstreamer_la_SOURCES = \
+	gstreamer.c
+libcanberra_gstreamer_la_CFLAGS = \
+	$(GSTREAMER_CFLAGS) \
+	 -Ddriver_open=gstreamer_driver_open \
+	 -Ddriver_destroy=gstreamer_driver_destroy \
+	 -Ddriver_change_device=gstreamer_driver_change_device \
+	 -Ddriver_change_props=gstreamer_driver_change_props \
+	 -Ddriver_play=gstreamer_driver_play \
+	 -Ddriver_cancel=gstreamer_driver_cancel \
+	 -Ddriver_cache=gstreamer_driver_cache
+libcanberra_gstreamer_la_LIBADD = \
+	$(GSTREAMER_LIBS) \
+	libcanberra.la
+libcanberra_gstreamer_la_LDFLAGS = \
+	-avoid-version -module -export-dynamic
+
+endif
+
 if HAVE_NULL
 if BUILTIN_NULL
 
--- libcanberra-0.6/src/read-sound-file.h-orig	2008-08-19 23:24:11.755259000 -0500
+++ libcanberra-0.6/src/read-sound-file.h	2008-08-19 23:25:46.333971000 -0500
@@ -48,4 +48,6 @@ int ca_sound_file_read_arbitrary(ca_soun
 
 size_t ca_sound_file_frame_size(ca_sound_file *f);
 
+const char * ca_sound_file_get_filename(ca_sound_file *f);
+
 #endif
--- libcanberra-0.6/src/read-sound-file.c-orig	2008-08-20 00:54:46.115147000 -0500
+++ libcanberra-0.6/src/read-sound-file.c	2008-08-19 23:24:59.586839000 -0500
@@ -111,6 +111,11 @@ unsigned ca_sound_file_get_nchannels(ca_
     return f->nchannels;
 }
 
+const char * ca_sound_file_get_filename(ca_sound_file *f) {
+    ca_assert(f);
+    return f->filename;
+}
+
 unsigned ca_sound_file_get_rate(ca_sound_file *f) {
     ca_assert(f);
     return f->rate;
--- /dev/null	2008-08-20 00:55:11.000000000 -0500
+++ libcanberra-0.6/src/gstreamer.c	2008-08-20 00:18:54.705326000 -0500
@@ -0,0 +1,108 @@
+/***
+  This file is part of libcanberra.
+
+  Copyright 2008 Lennart Poettering
+
+  libcanberra is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation, either version 2.1 of the
+  License, or (at your option) any later version.
+
+  libcanberra is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with libcanberra. If not, If not, see
+  <http://www.gnu.org/licenses/>.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+
+#include "canberra.h"
+#include "common.h"
+#include "driver.h"
+#include "read-sound-file.h"
+#include "sound-theme-spec.h"
+
+int gstreamer_driver_open(ca_context *c) {
+    ca_return_val_if_fail(c, CA_ERROR_INVALID);
+    ca_return_val_if_fail(!c->driver || ca_streq(c->driver, "gstreamer"), CA_ERROR_NODRIVER);
+
+    return CA_SUCCESS;
+}
+
+int gstreamer_driver_destroy(ca_context *c) {
+    ca_return_val_if_fail(c, CA_ERROR_INVALID);
+
+    return CA_SUCCESS;
+}
+
+int gstreamer_driver_change_device(ca_context *c, char *device) {
+    ca_return_val_if_fail(c, CA_ERROR_INVALID);
+
+    return CA_SUCCESS;
+}
+
+int gstreamer_driver_change_props(ca_context *c, ca_proplist *changed, ca_proplist *merged) {
+    ca_return_val_if_fail(c, CA_ERROR_INVALID);
+    ca_return_val_if_fail(changed, CA_ERROR_INVALID);
+    ca_return_val_if_fail(merged, CA_ERROR_INVALID);
+
+    return CA_SUCCESS;
+}
+
+int gstreamer_driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_callback_t cb, void *userdata) {
+    ca_sound_file *file = NULL;
+    ca_theme_data *theme = NULL;
+    char *cmd;
+    int ret = CA_SUCCESS;
+
+    ca_return_val_if_fail(c, CA_ERROR_INVALID);
+    ca_return_val_if_fail(proplist, CA_ERROR_INVALID);
+    ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID);
+
+    if ((ret = ca_lookup_sound(&file, &theme, c->props, proplist)) < 0)
+       goto finish;
+
+    if (file == NULL) {
+       ret = CA_ERROR_OOM;
+       goto finish;
+    }
+
+    cmd = ca_sprintf_malloc(
+       "/bin/sh -c \"gst-launch filesrc location=%s ! decodebin ! audioconvert ! gconfaudiosink\" > /dev/null 2>&1 &",
+       ca_sound_file_get_filename(file));
+
+    if (cmd == NULL) {
+       ret = CA_ERROR_OOM;
+       goto finish;
+    }
+
+    system (cmd);
+
+    if (cb)
+        cb(c, id, CA_SUCCESS, userdata);
+
+finish:
+
+    return ret;
+}
+
+int gstreamer_driver_cancel(ca_context *c, uint32_t id) {
+    ca_return_val_if_fail(c, CA_ERROR_INVALID);
+
+    return CA_SUCCESS;
+}
+
+int gstreamer_driver_cache(ca_context *c, ca_proplist *proplist) {
+    ca_return_val_if_fail(c, CA_ERROR_INVALID);
+    ca_return_val_if_fail(proplist, CA_ERROR_INVALID);
+
+    return CA_ERROR_NOTSUPPORTED;
+}
--- libcanberra-0.6/src/driver-order.c-orig	2008-08-20 01:04:46.646780000 -0500
+++ libcanberra-0.6/src/driver-order.c	2008-08-20 01:04:56.096921000 -0500
@@ -34,6 +34,9 @@ const char* const ca_driver_order[] = {
 #ifdef HAVE_ALSA
     "alsa",
 #endif
+#ifdef HAVE_GSTREAMER
+    "gstreamer",
+#endif
     /* ... */
     NULL
 };
_______________________________________________
libcanberra-discuss mailing list
[email protected]
https://tango.0pointer.de/mailman/listinfo/libcanberra-discuss

Reply via email to