[monkey-bubble: 581/753] Create gnomesoundplugin_csl.la and install it in



commit f5ed936677e1b33d22fd868735628fba94dc486b
Author: Martin Baulig <baulig suse de>
Date:   Fri Aug 3 16:29:03 2001 +0000

    Create gnomesoundplugin_csl.la and install it in
    
    2001-08-03  Martin Baulig  <baulig suse de>
    
    	* Makefile.am: Create gnomesoundplugin_csl.la and install it
    	in $(libdir)/gnome-2.0/sound-plugins/ if we have CSL.
    
    	* gnome-sound.[ch]: The new GNOME Sound API.
    
    	* gnome-sound-csl.c: This is the sound plugin module for CSL.
    
    	* test-sound.c: New file.

 libgnome/.cvsignore        |    1 +
 libgnome/ChangeLog         |   11 +
 libgnome/Makefile.am       |   55 +++-
 libgnome/gnome-sound-csl.c |  218 ++++++++++++++++
 libgnome/gnome-sound.c     |  592 +++++++++++--------------------------------
 libgnome/gnome-sound.h     |  107 +++++++-
 libgnome/libgnome.h        |    2 +-
 libgnome/test-sound.c      |   31 +++
 8 files changed, 552 insertions(+), 465 deletions(-)
---
diff --git a/libgnome/.cvsignore b/libgnome/.cvsignore
index 3e9bf7c..f44ff9e 100644
--- a/libgnome/.cvsignore
+++ b/libgnome/.cvsignore
@@ -24,3 +24,4 @@ gnome-marshal.h
 *-common.c
 Gnome.h
 *-imodule.c
+test-sound
diff --git a/libgnome/ChangeLog b/libgnome/ChangeLog
index 2c9db7a..a25f8b4 100644
--- a/libgnome/ChangeLog
+++ b/libgnome/ChangeLog
@@ -1,3 +1,14 @@
+2001-08-03  Martin Baulig  <baulig suse de>
+
+	* Makefile.am: Create gnomesoundplugin_csl.la and install it
+	in $(libdir)/gnome-2.0/sound-plugins/ if we have CSL.
+
+	* gnome-sound.[ch]: The new GNOME Sound API.
+
+	* gnome-sound-csl.c: This is the sound plugin module for CSL.
+
+	* test-sound.c: New file.
+
 2001-08-01  Martin Baulig  <baulig suse de>
 
 	* gnome-paper.[ch]: Removed.
diff --git a/libgnome/Makefile.am b/libgnome/Makefile.am
index 9a4d351..fbac89d 100644
--- a/libgnome/Makefile.am
+++ b/libgnome/Makefile.am
@@ -13,24 +13,27 @@ lib_LTLIBRARIES = libgnome-2.la
 
 LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@
 
+soundplugindir = $(libdir)/gnome-2.0/sound-plugins
+
 libincludedir = $(includedir)/gnome/2
 
 libgnomeincludedir = $(includedir)/gnome/2/libgnome
 
 INCLUDES = \
-	-I..					\
-	-I$(srcdir)/..				\
-	$(WARN_CFLAGS)				\
-	$(LIBGNOME_CFLAGS)			\
-	-DLIBGNOME_PREFIX=\""$(prefix)"\"		\
-	-DLIBGNOME_LIBDIR=\""$(libdir)"\"		\
-	-DLIBGNOME_DATADIR=\""$(datadir)"\"		\
-	-DLIBGNOME_BINDIR=\""$(bindir)"\"		\
-	-DLIBGNOME_LOCALSTATEDIR=\""$(localstatedir)"\" \
-	-DLIBGNOME_LOCALEDIR=\""$(gnomelocaledir)"\"	\
-	-DLIBGNOME_SYSCONFDIR=\""$(sysconfdir)"\"	\
-	-DVERSION=\""$(VERSION)"\"			\
-	-DGNOMEVFSVERSION=\""$(GNOME_VFS_VERSION)"\" \
+	-I..							\
+	-I$(srcdir)/..						\
+	$(WARN_CFLAGS)						\
+	$(LIBGNOME_CFLAGS)					\
+	-DLIBGNOME_PREFIX=\""$(prefix)"\"			\
+	-DLIBGNOME_LIBDIR=\""$(libdir)"\"			\
+	-DLIBGNOME_DATADIR=\""$(datadir)"\"			\
+	-DLIBGNOME_BINDIR=\""$(bindir)"\"			\
+	-DLIBGNOME_LOCALSTATEDIR=\""$(localstatedir)"\"		\
+	-DLIBGNOME_LOCALEDIR=\""$(gnomelocaledir)"\"		\
+	-DLIBGNOME_SYSCONFDIR=\""$(sysconfdir)"\"		\
+	-DLIBGNOME_SOUNDPLUGINDIR=\""$(soundplugindir)"\"	\
+	-DVERSION=\""$(VERSION)"\"				\
+	-DGNOMEVFSVERSION=\"$(GNOME_VFS_VERSION)\"		\
 	-DG_LOG_DOMAIN=\"Gnome\"
 
 CORBA_SOURCE =			\
@@ -51,6 +54,7 @@ libgnome_src = \
 	libgnometypebuiltins.h	\
 	libgnometypebuiltins.c	\
 	gnome-program.c		\
+	gnome-sound.c		\
 	gnome-exec.c		\
 	gnome-url.c		\
 	gnome-util.c		\
@@ -70,6 +74,7 @@ libinclude_HEADERS = \
 
 libgnome_headers = \
 	gnome-program.h		\
+	gnome-sound.h		\
 	gnome-i18n.h		\
 	gnome-exec.h		\
 	gnome-triggers.h 	\
@@ -88,6 +93,23 @@ noinst_HEADERS = \
 	gnome-triggersP.h	\
 	libgnomeP.h
 
+if HAVE_CSL
+cslmodules = gnomesoundplugin_csl.la
+else
+cslmodules =
+endif
+
+soundplugin_LTLIBRARIES = $(cslmodules)
+
+gnomesoundplugin_csl_la_SOURCES = \
+	gnome-sound-csl.c
+
+gnomesoundplugin_csl_la_LIBADD = \
+	$(LIBGNOME_CSL_LIBS)
+
+gnomesoundplugin_csl_la_LDFLAGS = \
+	-export-dynamic -module
+
 # all autogenerated files need to be generated in the srcdir,
 # so old versions get remade and are not confused with newer
 # versions in the build dir. thus a development setup requires
@@ -169,12 +191,17 @@ libgnome_2_la_LIBADD =		\
 	$(LIBGNOME_LIBS)
 
 noinst_PROGRAMS = \
-	test-libgnome
+	test-libgnome			\
+	test-sound
 
 test_libgnome_SOURCES = test-libgnome.c
 test_libgnome_LDADD = \
 	libgnome-2.la
 
+test_sound_SOURCES = test-sound.c
+test_sound_LDADD = \
+	libgnome-2.la
+
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = libgnome-2.0.pc
 
diff --git a/libgnome/gnome-sound-csl.c b/libgnome/gnome-sound-csl.c
new file mode 100644
index 0000000..c743ba8
--- /dev/null
+++ b/libgnome/gnome-sound-csl.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2001 SuSE Linux AG
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#include "config.h"
+#include "gnome-sound.h"
+
+#include <csl/csl.h>
+#include <csl/cslsample.h>
+
+struct _GnomeSoundSample {
+    CslSample *sample;
+};
+
+static GPtrArray *active_samples = NULL;
+static CslDriver *gnome_sound_csl_driver = NULL;
+
+static void
+gnome_sound_csl_play_file (const char *filename, GError **error)
+{
+    CslErrorType err;
+    CslSample *sample;
+
+    if (!gnome_sound_csl_driver)
+	return;
+
+    err = csl_sample_new_from_file (gnome_sound_csl_driver, filename,
+				    "gnome_sound_csl_play", NULL,
+				    &sample);
+    if (err) {
+	csl_warning ("unable to create sample from file '%s': %s",
+		     filename, csl_strerror (err));
+	return;
+    }
+
+    csl_sample_play (sample);
+    csl_sample_release (sample);
+}
+
+static GnomeSoundSample *
+gnome_sound_csl_sample_new_from_file (const char *filename, GError **error)
+{
+    CslErrorType err;
+    CslSample *sample;
+    GnomeSoundSample *retval;
+
+    if (!gnome_sound_csl_driver)
+	return NULL;
+
+    err = csl_sample_new_from_file (gnome_sound_csl_driver, filename,
+				    "gnome_sound_csl_sample_new", NULL,
+				    &sample);
+    if (err) {
+	csl_warning ("unable to create sample from file '%s': %s",
+		     filename, csl_strerror (err));
+	return NULL;
+    }
+
+    retval = g_new0 (GnomeSoundSample, 1);
+    retval->sample = sample;
+
+    g_ptr_array_add (active_samples, retval);
+
+    return retval;
+}
+
+static GnomeSoundSample *
+gnome_sound_csl_sample_new (const char *sample_name, GError **error)
+{
+    CslErrorType err;
+    CslSample *sample;
+    GnomeSoundSample *retval;
+
+    if (!gnome_sound_csl_driver)
+	return NULL;
+
+    err = csl_sample_new (gnome_sound_csl_driver, sample_name,
+			  "gnome_sound_csl_play", NULL,
+			  &sample);
+    if (err) {
+	csl_warning ("unable to create sample '%s': %s",
+		     sample_name, csl_strerror (err));
+	return NULL;
+    }
+
+    retval = g_new0 (GnomeSoundSample, 1);
+    retval->sample = sample;
+
+    g_ptr_array_add (active_samples, retval);
+
+    return retval;
+}
+
+static int
+gnome_sound_csl_sample_write (GnomeSoundSample *gs,
+			      guint n_bytes, gpointer bytes,
+			      GError **error)
+{
+    return csl_sample_write (gs->sample, n_bytes, bytes);
+}
+
+static void
+gnome_sound_csl_sample_write_done (GnomeSoundSample *gs)
+{
+    csl_sample_write_done (gs->sample);
+}
+
+static void
+gnome_sound_csl_sample_play (GnomeSoundSample *gs, GError **error)
+{
+    csl_sample_play (gs->sample);
+}
+
+static gboolean
+gnome_sound_csl_sample_is_playing (GnomeSoundSample *gs, GError **error)
+{
+    return csl_sample_is_playing (gs->sample);
+}
+
+static void
+gnome_sound_csl_sample_stop (GnomeSoundSample *gs, GError **error)
+{
+    csl_sample_stop (gs->sample);
+}
+
+static void
+gnome_sound_csl_sample_wait_done (GnomeSoundSample *gs, GError **error)
+{
+    csl_sample_wait_done (gs->sample);
+}
+
+static void
+gnome_sound_csl_sample_release (GnomeSoundSample *gs, GError **error)
+{
+    csl_sample_release (gs->sample);
+    g_ptr_array_remove (active_samples, gs);
+    g_free (gs);
+}
+
+static gboolean
+gnome_sound_csl_init (const gchar *backend_args, GError **error)
+{
+    CslErrorType err;
+    const gchar *name = "arts";
+
+    if (gnome_sound_csl_driver) {
+	g_warning ("Sound system already initialized!");
+	return TRUE;
+    }
+
+    err = csl_driver_init_mutex (name,
+				 CSL_DRIVER_CAP_PCM|CSL_DRIVER_CAP_SAMPLE,
+				 NULL, &gnome_sound_csl_driver);
+
+    if (err) {
+	g_warning ("Failed to initialize %s sound driver: %s (%d)",
+		   name ? name : "auto-selected", csl_strerror (err), err);
+	return FALSE;
+    }
+
+    active_samples = g_ptr_array_new ();
+    return TRUE;
+}
+
+static void
+gnome_sound_csl_shutdown (GError **error)
+{
+    if (gnome_sound_csl_driver) {
+
+	while (active_samples->len) {
+	    GnomeSoundSample *gs = g_ptr_array_index (active_samples, 0);
+
+	    gnome_sound_csl_sample_stop (gs, NULL);
+	    gnome_sound_csl_sample_release (gs, NULL);
+	}
+
+	csl_driver_shutdown (gnome_sound_csl_driver);
+	gnome_sound_csl_driver = NULL;
+    }
+}
+
+GnomeSoundPlugin gnome_sound_plugin = {
+    GNOME_PLUGIN_SERIAL,
+    "gnome-sound-csl",
+    gnome_sound_csl_init,
+    gnome_sound_csl_shutdown,
+    gnome_sound_csl_play_file,
+    gnome_sound_csl_sample_new,
+    gnome_sound_csl_sample_write,
+    gnome_sound_csl_sample_write_done,
+    gnome_sound_csl_sample_new_from_file,
+    gnome_sound_csl_sample_play,
+    gnome_sound_csl_sample_is_playing,
+    gnome_sound_csl_sample_stop,
+    gnome_sound_csl_sample_wait_done,
+    gnome_sound_csl_sample_release
+};
diff --git a/libgnome/gnome-sound.c b/libgnome/gnome-sound.c
index 69666c0..1fbf2a1 100644
--- a/libgnome/gnome-sound.c
+++ b/libgnome/gnome-sound.c
@@ -28,486 +28,198 @@
 #include "libgnome.h"
 #include "gnome-sound.h"
 
+#include <gmodule.h>
+#include <glib/gerror.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <time.h>
 
-#ifdef HAVE_ESD
-#include <esd.h>
-#endif
-
-static char *esound_hostname;
-
-int gnome_sound_connection = -1;
-
-typedef struct _sample
-  {
-    int rate, format, samples, id, size;
-    short *data;
-  }
-GnomeSoundSample;
-
-#ifndef HAVE_LIBAUDIOFILE
-typedef struct _WAVFormatChunk
-  {
-    char chunkID[4];
-    int chunkSize;
-
-    unsigned int dwSamplesPerSec;
-    unsigned int dwAvgBytesPerSec;
-    short wFormatTag;
-    unsigned short wChannels;
-    unsigned short wBlockAlign;
-    unsigned short wBitsPerSample;
-  }
-WAVFormatChunk;
+static const GnomeSoundPlugin *sound_plugin = NULL;
+static GModule *sound_plugin_module = NULL;
 
-#ifdef WORDS_BIGENDIAN
-#define SWAP_SHORT( x ) x = ( ( x & 0x00ff ) << 8 ) | ( ( x >> 8 ) & 0x00ff )
-#define SWAP_LONG( x ) x = ( ( ( x & 0x000000ff ) << 24 ) |\
-( ( x & 0x0000ff00 ) << 8 ) |\
-( ( x & 0x00ff0000 ) >> 8 ) |\
-( ( x & 0xff000000 ) >> 24 ) )
-#endif
-
-/**
- * gnome_sound_sample_load_wav:
- * @file: filename to try loading a WAV file from.
- * 
- * Used to load a .wav file into esound.
- *
- * Returns a GnomeSoundSample or NULL if file did not exist.
- *
- */
-static GnomeSoundSample *
-gnome_sound_sample_load_wav(const char *file)
+static void
+_gnome_sound_error_nodriver (GError **error)
 {
-#ifdef HAVE_ESD
-  FILE *f;
-  GnomeSoundSample *s;
-  char buf[4];
-  WAVFormatChunk fmt;
-  int skipl = 0;
-  int skipr = 0;
-  char bytes = 0;
-  char stereo = 0;
-  int len;
+    g_set_error (error, GNOME_SOUND_ERROR,
+		 GNOME_SOUND_ERROR_NODRIVER,
+		 _("No sound driver loaded"));
+}
 
-  /* int                 count; */
+void 
+gnome_sound_play (const char *filename, GError **error)
+{
+    if (sound_plugin)
+	sound_plugin->play_file (filename, error);
+    else
+    _gnome_sound_error_nodriver (error);
+}
 
-  f = fopen (file, "r");
-  if (!f)
-    return NULL;
-  s = g_malloc (sizeof (GnomeSoundSample));
-  if (!s)
-    {
-      fclose (f);
-      return NULL;
-    }
-  s->rate = 44100;
-  s->format = ESD_STREAM | ESD_PLAY;
-  s->samples = 0;
-  s->data = NULL;
-  s->id = 0;
-  fread (buf, 1, 4, f);
-  if ((buf[0] != 'R') ||
-      (buf[1] != 'I') ||
-      (buf[2] != 'F') ||
-      (buf[3] != 'F'))
-    {
-      /* not a RIFF WAV file */
-      fclose (f);
-      g_free (s);
-      return NULL;
+GnomeSoundSample *
+gnome_sound_sample_new_from_file (const char *filename, GError **error)
+{
+    if (sound_plugin)
+	return sound_plugin->sample_new_from_file (filename, error);
+    else {
+	_gnome_sound_error_nodriver (error);
+	return NULL;
     }
-  fread (buf, 1, 4, f);
-  fread (buf, 1, 4, f);
-  fread (fmt.chunkID, 1, 4, f);
-  fread (&(fmt.chunkSize), 1, 4, f);
-
-#ifdef WORDS_BIGENDIAN
-  SWAP_LONG (fmt.chunkSize);
-#endif
-
-  if ((fmt.chunkID[0] == 'f') &&
-      (fmt.chunkID[1] == 'm') &&
-      (fmt.chunkID[2] == 't') &&
-      (fmt.chunkID[3] == ' ') &&
-      16 == fmt.chunkSize)
-    /* fmt chunk */
-    {
-      fread (&(fmt.wFormatTag), 1, 2, f);
-      fread (&(fmt.wChannels), 1, 2, f);
-      fread (&(fmt.dwSamplesPerSec), 1, 4, f);
-      fread (&(fmt.dwAvgBytesPerSec), 1, 4, f);
-      fread (&(fmt.wBlockAlign), 1, 2, f);
-      fread (&(fmt.wBitsPerSample), 1, 2, f);
-#ifdef WORDS_BIGENDIAN
-      SWAP_SHORT (fmt.wFormatTag);
-      SWAP_SHORT (fmt.wChannels);
-      SWAP_LONG (fmt.dwSamplesPerSec);
-      SWAP_LONG (fmt.dwAvgBytesPerSec);
-      SWAP_SHORT (fmt.wBlockAlign);
-      SWAP_SHORT (fmt.wBitsPerSample);
-#endif
+}
 
-      if (fmt.wFormatTag != 1)
-	{
-	  /* unknown WAV encoding format - exit */
-	  fclose (f);
-	  g_free (s);
-	  return NULL;
-	}
-      skipl = 0;
-      skipr = 0;
-      bytes = 0;
-      stereo = 0;
-      if (fmt.wChannels == 1)
-	s->format |= ESD_MONO;
-      else if (fmt.wChannels == 2)
-	{
-	  stereo = 1;
-	  s->format |= ESD_STEREO;
-	}
-      else
-	{
-	  stereo = 1;
-	  s->format |= ESD_STEREO;
-	  if (fmt.wChannels == 3)
-	    {
-	      skipl = 0;
-	      skipr = 1;
-	    }
-	  else if (fmt.wChannels == 4)
-	    {
-	      skipl = 0;
-	      skipr = 2;
-	    }
-	  else if (fmt.wChannels == 4)
-	    {
-	      skipl = 0;
-	      skipr = 2;
-	    }
-	  else if (fmt.wChannels == 6)
-	    {
-	      skipl = 3;
-	      skipr = 1;
-	    }
-	  else
-	    {
-	      /* unknown channel encoding */
-	      fclose (f);
-	      g_free (s);
-	      return NULL;
-	    }
-	}
-      s->rate = fmt.dwSamplesPerSec;
-      if (fmt.wBitsPerSample <= 8)
-	{
-	  bytes = 1;
-	  s->format |= ESD_BITS8;
-	}
-      else if (fmt.wBitsPerSample <= 16)
-	s->format |= ESD_BITS16;
-      else
-	{
-	  /* unknown bits encoding encoding */
-	  fclose (f);
-	  g_free (s);
-	  return NULL;
-	}
+GnomeSoundSample *
+gnome_sound_sample_new (const char *sample_name, GError **error)
+{
+    if (sound_plugin)
+	return sound_plugin->sample_new (sample_name, error);
+    else {
+	_gnome_sound_error_nodriver (error);
+	return NULL;
     }
-  for (;;)
-    {
-      if (fread (buf, 1, 4, f) &&
-	  fread (&len, 4, 1, f))
-	{
-#ifdef WORDS_BIGENDIAN
-	  SWAP_LONG (len);
-#endif
-
-	  if ((buf[0] != 'd') ||
-	      (buf[1] != 'a') ||
-	      (buf[2] != 't') ||
-	      (buf[3] != 'a'))
-	    fseek (f, len, SEEK_CUR);
-	  else
-	    {
-	      s->data = g_malloc (len);
-	      if (!s->data)
-		{
-		  fclose (f);
-		  g_free (s);
-		  return NULL;
-		}
-	      if ((skipl == 0) && (skipr == 0))
-		{
-		  fread (s->data, len, 1, f);
-#ifdef WORDS_BIGENDIAN
-		  if (fmt.wBitsPerSample > 8 && fmt.wBitsPerSample <= 16)
-		    {
-		      char *tmp;
-		      char tmpval;
-		      int i;
-
-		      tmp = (char *) (s->data);
+}
 
-		      for (i = 0; i < len; i++)
-			{
-			  tmpval = tmp[i];
-			  tmp[i] = tmp[i + 1];
-			  tmp[i + 1] = tmpval;
-			}
-		    }
-#endif
-		}
-	      else
-		{
-		}
-	      s->samples = len;
-	      if (stereo)
-		s->samples /= 2;
-	      if (!bytes)
-		s->samples /= 2;
-	      fclose (f);
-	      return s;
-	    }
-	}
-      else
-	{
-	  fclose (f);
-	  return NULL;
-	}
+int
+gnome_sound_sample_write (GnomeSoundSample *gs,
+			  guint n_bytes, gpointer bytes,
+			  GError **error)
+{
+    if (sound_plugin)
+	return sound_plugin->sample_write (gs, n_bytes, bytes, error);
+    else {
+	_gnome_sound_error_nodriver (error);
+	return -1;
     }
-  fclose (f);
-  g_free (s);
-  if (s->data)
-    g_free (s->data);
-#endif
+}
 
-  return NULL;
+void
+gnome_sound_sample_write_done (GnomeSoundSample *gs, GError **error)
+{
+    if (sound_plugin)
+	sound_plugin->sample_write_done (gs, error);
+    else
+    _gnome_sound_error_nodriver (error);
 }
-#endif
 
-#ifdef HAVE_ESD
-/*
- * This does delayed initialization of Esound
- */
-static gboolean
-use_sound (void)
+void
+gnome_sound_sample_play (GnomeSoundSample *gs, GError **error)
+{
+    if (sound_plugin)
+	sound_plugin->sample_play (gs, error);
+    else
+	_gnome_sound_error_nodriver (error);
+}
+
+gboolean
+gnome_sound_sample_is_playing (GnomeSoundSample *gs, GError **error)
 {
-  if (gnome_sound_connection == -1){
-    if (esound_hostname){
-      gnome_sound_connection = esd_open_sound (esound_hostname);
-      if (gnome_sound_connection == -1){
-	g_free (esound_hostname);
-	esound_hostname = NULL;
+    if (sound_plugin)
+	return sound_plugin->sample_is_playing (gs, error);
+    else {
+	_gnome_sound_error_nodriver (error);
 	return FALSE;
-      }
     }
-  }
-  return TRUE;
 }
-#endif
 
-#if defined(HAVE_LIBAUDIOFILE) && defined(HAVE_ESD)
-#include <audiofile.h>
-
-static GnomeSoundSample *
-gnome_sound_sample_load_audiofile(const char *file)
+void
+gnome_sound_sample_stop (GnomeSoundSample *gs, GError **error)
 {
-  AFfilehandle in_file;
-  GnomeSoundSample *s;
-  int in_format, in_width, in_channels;
-  double in_rate;
-  int bytes_per_frame;
-  AFframecount frame_count, frames_read;
-
-  int out_bits, out_channels, out_rate;
-  int out_mode = ESD_STREAM, out_func = ESD_PLAY;
-  esd_format_t out_format;
-
-  in_file = afOpenFile(file, "r", NULL);
-  if(!in_file)
-    return NULL;
-
-  frame_count = afGetFrameCount(in_file, AF_DEFAULT_TRACK);
-  in_channels = afGetChannels(in_file, AF_DEFAULT_TRACK);
-  in_rate = afGetRate (in_file, AF_DEFAULT_TRACK);
-  afGetSampleFormat (in_file, AF_DEFAULT_TRACK, &in_format, &in_width);
-  if (in_width == 8)
-    out_bits = ESD_BITS8;
-  else if (in_width == 16)
-    out_bits = ESD_BITS16;
-  else {
-      g_warning ("only sample widths of 8 and 16 supported");
-      return NULL;
-  }
-
-  bytes_per_frame = in_width / 8;
-
-  if (in_channels == 1)
-    out_channels = ESD_MONO;
-  else if (in_channels == 2)
-    out_channels = ESD_STEREO;
-  else {
-      g_warning ("only 1 or 2 channel samples supported");
-      return NULL;
-  }
-
-  out_format = out_bits | out_channels | out_mode | out_func;
-
-  out_rate = (int) in_rate;
-
-  s = g_new0 (GnomeSoundSample, 1);
-
-  s->rate = out_rate;
-  s->format = out_format;
-  s->samples = frame_count;
-  s->data = g_malloc(frame_count * in_channels * bytes_per_frame);
-  s->id = 0;
-
-  frames_read = afReadFrames(in_file, AF_DEFAULT_TRACK, s->data,
-			     frame_count * in_channels);
-
-  afCloseFile(in_file);
+    if (sound_plugin)
+	sound_plugin->sample_stop (gs, error);
+    else
+	_gnome_sound_error_nodriver (error);
+}
 
-  return s;
+void
+gnome_sound_sample_wait_done (GnomeSoundSample *gs, GError **error)
+{
+    if (sound_plugin)
+	sound_plugin->sample_wait_done (gs, error);
+    else
+	_gnome_sound_error_nodriver (error);
 }
-#endif
 
+void
+gnome_sound_sample_release (GnomeSoundSample *gs, GError **error)
+{
+    if (sound_plugin)
+	sound_plugin->sample_release (gs, error);
+    else
+	_gnome_sound_error_nodriver (error);
+}
 
-/**
- * gnome_sound_sample_load:
- * @sample_name: the name of the sample
- * @filename: the filename where the audio is stored
- *
- * Loads the audio on @filename and XXXX
- *
- * Returns: a sample_id, or a negative number otherwise.
- */
-int
-gnome_sound_sample_load(const char *sample_name, const char *filename)
+GQuark
+gnome_sound_error_quark (void)
 {
-#ifdef HAVE_ESD
-  GnomeSoundSample *s = NULL;
-  int sample_id;
-  int size;
-  int confirm = 0;
+    static GQuark q = 0;
 
-  if (!use_sound ())
-    return -2;
+    if (q == 0)
+	q = g_quark_from_static_string ("gnome-sound-error-quark");
 
-  if(!filename || !*filename)
-    return -2;
+    return q;
+}
 
-#ifdef HAVE_LIBAUDIOFILE
-  s = gnome_sound_sample_load_audiofile(filename);
-#else
-  s = gnome_sound_sample_load_wav(filename);
-#endif
-  if(s)
-    goto playsamp;
+void
+gnome_sound_init (const gchar *name, const gchar *backend_args,
+		  const GnomeSoundPlugin *plugin, GError **error)
+{
+    if (sound_plugin)
+	return;
+
+    if (plugin)
+	sound_plugin = plugin;
+    else {
+	gchar *module_name;
+	gpointer plugin_ptr = NULL;
+	GModule *module;
+
+	module_name = g_strdup_printf (LIBGNOME_SOUNDPLUGINDIR
+				       "/gnomesoundplugin_%s",
+				       name);
+	module = g_module_open (module_name, G_MODULE_BIND_LAZY);
+	if (!module) {
+	    g_warning (G_STRLOC ": Can't open sound plugin `%s': %s",
+		       name, g_module_error ());
+	    return;
+	}
 
-  /* XXX: Add handlers for more formats here */
+	if (!g_module_symbol (module, "gnome_sound_plugin", &plugin_ptr)) {
+	    g_warning (G_STRLOC ": Not a valid sound plugin: `%s'", name);
+	    g_module_close (module);
+	    return;
+	}
 
- playsamp:
-  if (!s)
-    return -1;
+	sound_plugin = plugin_ptr;
+	sound_plugin_module = module;
+    }
 
-  size = s->samples;
-  if (s->format & ESD_STEREO)
-    size *= 2;
-  if (s->format & ESD_BITS16)
-    size *= 2;
+    if (sound_plugin->version != GNOME_PLUGIN_SERIAL) {
+	g_warning (G_STRLOC ": Sound plugin `%s' has invalid version %ld",
+		   name, sound_plugin->version);
+	sound_plugin = NULL;
 
-  if (gnome_sound_connection >= 0)
-    {
-      if (s->data)
-	{
-	  /* "name" of all samples is currently "E", should be name of sound 
-	   * file, or event type, for later identification */
-	  s->id = esd_sample_cache (gnome_sound_connection, s->format, s->rate,
-				    size, (char *)sample_name);
-	  write (gnome_sound_connection, s->data, size);
-	  confirm = esd_confirm_sample_cache (gnome_sound_connection);
-	  if (s->id <= 0 || confirm != s->id)
-	    {
-	      g_warning ("error caching sample <%d>!\n", s->id);
-	      s->id = 0;
-	    }
-	  g_free (s->data);
-	  s->data = NULL;
+	if (sound_plugin_module) {
+	    g_module_close (sound_plugin_module);
+	    sound_plugin_module = NULL;
 	}
     }
 
-  sample_id = s->id;
-
-  g_free(s->data); g_free(s);
-
-  return sample_id;
-#else
-  return -1;
-#endif
-}
-
-/**
- * gnome_sound_play:
- * @filename: file containing the sound sample
- *
- * Plays the audio stored in @filename
- */
-void 
-gnome_sound_play (const char * filename)
-{
-#ifdef HAVE_ESD
-  char buf[23];
-  int sample;
-
-  if(!use_sound ())
-    return;
-
-  srand(time(NULL));
-  g_snprintf(buf, sizeof(buf), "%d-%d", getpid(), rand());
-  sample = gnome_sound_sample_load (buf, filename);
-
-  esd_sample_play(gnome_sound_connection, sample);
-  fsync (gnome_sound_connection);
-  esd_sample_free(gnome_sound_connection, sample);
-#endif
+    if (sound_plugin)
+	sound_plugin->init (backend_args, error);
+    else
+	_gnome_sound_error_nodriver (error);
 }
 
-/**
- * gnome_sound_init:
- * @hostname: hostname where esd daemon resides.
- *
- * Initialize esd connection
- */
 void
-gnome_sound_init(const char *hostname)
+gnome_sound_shutdown (GError **error)
 {
-#ifdef HAVE_ESD
-  esound_hostname = g_strdup (hostname);
-  if(gnome_sound_connection < 0)
-    gnome_sound_connection = esd_open_sound((char *)hostname);
-#endif
-}
-
-/** 
- * gnome_sound_shutdown:
- *
- * shuts down the gnome sound support
- */
-void
-gnome_sound_shutdown(void)
-{
-#ifdef HAVE_ESD
-	if(gnome_sound_connection >= 0){
-		esd_close(gnome_sound_connection);
-		gnome_sound_connection = -1;
-		g_free (esound_hostname);
-		esound_hostname = NULL;
-	}
-#endif
+    if (sound_plugin)
+	sound_plugin->shutdown (error);
+    else
+	_gnome_sound_error_nodriver (error);
+
+    sound_plugin = NULL;
+    if (sound_plugin_module) {
+	g_module_close (sound_plugin_module);
+	sound_plugin_module = NULL;
+    }
 }
diff --git a/libgnome/gnome-sound.h b/libgnome/gnome-sound.h
index 06ace7d..8433fe0 100644
--- a/libgnome/gnome-sound.h
+++ b/libgnome/gnome-sound.h
@@ -30,20 +30,107 @@
 
 G_BEGIN_DECLS
 
-/* Use this with the Esound functions */
-extern int gnome_sound_connection;
+typedef struct _GnomeSoundSample GnomeSoundSample;
+typedef struct _GnomeSoundPlugin GnomeSoundPlugin;
 
-/* Initialize esd connection */
-void gnome_sound_init(const char *hostname);
+struct _GnomeSoundPlugin {
+    gulong version;
+    const gchar *name;
 
-/* Closes esd connection */
-void gnome_sound_shutdown(void);
+    gboolean (*init) (const gchar *backend_args,
+		      GError **error);
+    void (*shutdown) (GError **error);
 
-/* Returns the Esound sample ID for the sample */
-int gnome_sound_sample_load(const char *sample_name, const char *filename);
+    void (*play_file) (const gchar *filename,
+		       GError **error);
 
-/* Loads sample, plays sample, frees sample */
-void gnome_sound_play (const char * filename);
+    GnomeSoundSample * (*sample_new) (const gchar *name,
+				      GError **error);
+    int (*sample_write) (GnomeSoundSample *gs,
+			 guint n_bytes, gpointer bytes,
+			 GError **error);
+    void (*sample_write_done) (GnomeSoundSample *gs,
+			       GError **error);
+
+    GnomeSoundSample * (*sample_new_from_file) (const gchar *filename,
+						GError **error);
+    void (*sample_play) (GnomeSoundSample *gs,
+			 GError **error);
+    gboolean (*sample_is_playing) (GnomeSoundSample *gs,
+				   GError **error);
+    void (*sample_stop) (GnomeSoundSample *gs,
+			 GError **error);
+    void (*sample_wait_done) (GnomeSoundSample *gs,
+			      GError **error);
+    void (*sample_release) (GnomeSoundSample *gs,
+			    GError **error);
+};
+
+typedef enum
+{
+    /* no sound driver */
+    GNOME_SOUND_ERROR_NODRIVER,
+    /* not implemented */
+    GNOME_SOUND_ERROR_NOT_IMPLEMENTED,
+    /* device busy */
+    GNOME_SOUND_ERROR_DEVICE_BUSY,
+    /* I/O eror */
+    GNOME_SOUND_ERROR_IO,
+    /* Insufficient permissions */
+    GNOME_SOUND_ERROR_PERMS,
+    /* misc error */
+    GNOME_SOUND_ERROR_MISC
+} GnomeSoundError;
+
+#define GNOME_SOUND_ERROR gnome_sound_error_quark ()
+GQuark gnome_sound_error_quark (void) G_GNUC_CONST;
+
+void gnome_sound_init (const gchar *driver_name,
+		       const gchar *backend_args,
+		       const GnomeSoundPlugin *opt_plugin,
+		       GError **error);
+
+void gnome_sound_shutdown (GError **error);
+
+void gnome_sound_play (const char *filename,
+		       GError **error);
+
+GnomeSoundSample *
+gnome_sound_sample_new_from_file (const char *filename,
+				  GError **error);
+
+GnomeSoundSample *
+gnome_sound_sample_new (const char *sample_name,
+			GError **error);
+
+int
+gnome_sound_sample_write (GnomeSoundSample *gs,
+			  guint n_bytes, gpointer bytes,
+			  GError **error);
+
+void
+gnome_sound_sample_write_done (GnomeSoundSample *gs,
+			       GError **error);
+
+void
+gnome_sound_sample_play (GnomeSoundSample *gs,
+			 GError **error);
+
+gboolean
+gnome_sound_sample_is_playing (GnomeSoundSample *gs,
+			       GError **error);
+
+void
+gnome_sound_sample_stop (GnomeSoundSample *gs,
+			 GError **error);
+
+void
+gnome_sound_sample_wait_done (GnomeSoundSample *gs,
+			      GError **error);
+
+void
+gnome_sound_sample_release (GnomeSoundSample *gs,
+			    GError **error);
 
 G_END_DECLS
 
diff --git a/libgnome/libgnome.h b/libgnome/libgnome.h
index 524b5c9..6334901 100644
--- a/libgnome/libgnome.h
+++ b/libgnome/libgnome.h
@@ -31,8 +31,8 @@
 
 #include <libgnome/gnome-exec.h>
 
-/* Should this be in gnome-print? */
 #include <libgnome/gnome-triggers.h>
+#include <libgnome/gnome-sound.h>
 #include <libgnome/gnome-util.h>
 #include <libgnome/gnome-url.h>
 
diff --git a/libgnome/test-sound.c b/libgnome/test-sound.c
new file mode 100644
index 0000000..08e581a
--- /dev/null
+++ b/libgnome/test-sound.c
@@ -0,0 +1,31 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <libgnome/libgnome-init.h>
+#include <libgnome/gnome-sound.h>
+
+int
+main (int argc, char **argv)
+{
+    GnomeProgram *program;
+
+    program = gnome_program_init ("test-sound", VERSION,
+				  &libgnome_module_info,
+				  argc, argv, NULL);
+
+    gnome_sound_init ("csl", NULL, NULL, NULL);
+
+    gnome_sound_play ("gameover.wav", NULL);
+
+    sleep(5);
+
+    gnome_sound_shutdown (NULL);
+
+    return 0;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]