[gcompris] Reorganisation of the sound playing in GCompris to split the



commit f3373a11998b5269a9fbf22ca717a3c33051d059
Author: Bruno Coudoin <bruno coudoin free fr>
Date:   Tue Jul 14 23:53:12 2009 +0200

    Reorganisation of the sound playing in GCompris to split the
    high level audio file management and the low level audio player
    (gstreamer based for instance).
    The goal behind this is to make room for an integration of
    the GCOMPRIS 8.3 branch SDL Mixer player. This way we will
    be able to resync the windows and master branch.

 configure.in             |   24 ++++-
 src/gcompris/Makefile.am |    3 +
 src/gcompris/gcompris.c  |    2 +
 src/gcompris/gstreamer.c |  269 ++++++++++++++++++++++++++++++++++++++++
 src/gcompris/soundutil.c |  309 +++++-----------------------------------------
 src/gcompris/soundutil.h |    9 ++
 6 files changed, 334 insertions(+), 282 deletions(-)
---
diff --git a/configure.in b/configure.in
index 2c7b8e5..91e0f98 100644
--- a/configure.in
+++ b/configure.in
@@ -19,8 +19,7 @@ dnl
 PKG_PROG_PKG_CONFIG()
 
 PKG_CHECK_MODULES(GCOMPRIS, dnl
- [gtk+-2.0 >= $GTK_REQUIRED dnl
-  gstreamer-0.10])
+ [gtk+-2.0 >= $GTK_REQUIRED])
 
 AC_SUBST(GCOMPRIS_CFLAGS)
 AC_SUBST(GCOMPRIS_LIBS)
@@ -362,6 +361,26 @@ if test x$TETEX = xno; then
 fi
 
 
+dnl SDLMixer support
+AC_MSG_CHECKING([wether we build with SDLMixer (will replace gstreamer by sdl mixer if enabled)])
+AC_ARG_ENABLE(sdlmixer,
+          AC_HELP_STRING(
+          [--enable-sdlmixer],
+          [Turn on sdl mixer (will replace gstreamer by sdl mixer)]),
+          with_sdlmixer="$enableval", with_sdlmixer="no")
+AC_MSG_RESULT($with_sdlmixer)
+
+if test x$with_sdlmixer = xyes; then
+  PKG_CHECK_MODULES(AUDIO, sdl,, AC_MSG_ERROR([*** SDL Mixer not found!]))
+  AC_DEFINE([USE_SDLMIXER], 1,[sdl mixer is enabled])
+else
+  dnl Default is gstreamer
+  PKG_CHECK_MODULES(AUDIO, gstreamer-0.10,, AC_MSG_ERROR([*** GSTREAMER not found!]))
+  AC_DEFINE([USE_GSTREAMER], 1,[gstreamer is enabled])
+fi
+AC_SUBST(AUDIO_CFLAGS)
+AC_SUBST(AUDIO_LIBS)
+
 dnl GNET support
 AC_MSG_CHECKING([wether we build with GNET (if not, networking will be disabled)])
 AC_ARG_ENABLE(gnet,
@@ -554,6 +573,7 @@ echo "SQLITE database (--enable-sqlite)        = $with_sqlite (profiles depend o
 echo "GNET Networking (--enable-gnet)          = $with_gnet (networking depends on this)"
 echo "BINRELOC (--enable-binreloc)             = $br_cv_binreloc"
 echo "NSBundle (--enable-nsbundle)             = $nsbundle"
+echo "SDL Mixer (--enable-sdlmixer)            = $with_sdlmixer (default is gstreamer)"
 
 
 echo
diff --git a/src/gcompris/Makefile.am b/src/gcompris/Makefile.am
index d91bbf2..4d4b1bc 100644
--- a/src/gcompris/Makefile.am
+++ b/src/gcompris/Makefile.am
@@ -55,6 +55,7 @@ INCLUDES = \
         $(sqlite_cflags) \
 	$(GNET_CFLAGS) \
 	$(cairo_cflags) \
+	$(AUDIO_CFLAGS) \
 	$(NSBUNDLE_CPPFLAGS)
 
 gcompris_SOURCES = \
@@ -114,6 +115,7 @@ gcompris_SOURCES = \
 	skin.h \
 	soundutil.c \
 	soundutil.h \
+	gstreamer.c \
 	timer.c \
 	timer.h \
 	wordlist.c \
@@ -126,6 +128,7 @@ gcompris_LDFLAGS = \
 
 gcompris_LDADD = \
 	$(GCOMPRIS_LIBS) $(sqlite_ldadd) $(XML_LIBS) $(GNET_LIBS) \
+	$(AUDIO_LIBS) \
         $(INTLLIBS) $(NSBUNDLE_LDFLAGS) $(XF86VM_LIBS)
 
 EXTRA_DIST = \
diff --git a/src/gcompris/gcompris.c b/src/gcompris/gcompris.c
index a3465f0..7c901c4 100644
--- a/src/gcompris/gcompris.c
+++ b/src/gcompris/gcompris.c
@@ -1914,6 +1914,8 @@ main (int argc, char *argv[])
 
   gc_skin_load(properties->skin);
 
+  gc_sound_build_music_list();
+
   if(properties->music || properties->fx)
     gc_sound_init();
 
diff --git a/src/gcompris/gstreamer.c b/src/gcompris/gstreamer.c
new file mode 100644
index 0000000..a904bea
--- /dev/null
+++ b/src/gcompris/gstreamer.c
@@ -0,0 +1,269 @@
+/* gcompris - gstreamer.c
+ *
+ * Copyright (C) 2009 Bruno Coudoin
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program 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 General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "string.h"
+
+#include "gcompris.h"
+#include <signal.h>
+#include <glib.h>
+#include <gst/gst.h>
+
+static GstElement *bg_pipeline = NULL;
+static GstElement *fx_pipeline = NULL;
+
+static gboolean	 fx_paused = FALSE;
+static gboolean	 bg_paused = FALSE;
+
+/* Singleton */
+static guint	 sound_init = 0;
+
+/* =====================================================================
+ *
+ * =====================================================================*/
+void
+gc_sound_init()
+{
+
+  /* Check to run the init only once */
+  if(sound_init == 1)
+    return;
+
+  sound_init = 1;
+
+  /* gstreamer init */
+  gst_init(NULL, NULL);
+
+  gc_sound_policy_set(PLAY_AFTER_CURRENT);
+
+}
+
+static gboolean
+fx_bus(GstBus* bus, GstMessage* msg, gpointer data)
+{
+  switch( GST_MESSAGE_TYPE( msg ) )
+    {
+    case GST_MESSAGE_EOS:
+      g_warning("fx_bus: EOS START");
+      gc_sound_fx_close();
+      gc_sound_callback((gchar *)data);
+      fx_play();
+      g_warning("fx_bus: EOS END");
+      break;
+    default:
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+bg_bus(GstBus* bus, GstMessage* msg, gpointer data)
+{
+  switch( GST_MESSAGE_TYPE( msg ) ) {
+    case GST_MESSAGE_EOS:
+        g_warning("bg_bus: EOS");
+	gc_sound_bg_close();
+	bg_play(NULL);
+	break;
+    default:
+      return TRUE;
+  }
+  return FALSE;
+}
+
+void
+gc_sound_close()
+{
+  gc_sound_bg_close();
+  gc_sound_fx_close();
+}
+
+void
+gc_sound_bg_close()
+{
+  if (bg_pipeline)
+    {
+      gst_element_set_state(bg_pipeline, GST_STATE_NULL);
+      gst_object_unref(GST_OBJECT(bg_pipeline));
+      bg_pipeline = NULL;
+    }
+}
+
+void
+gc_sound_fx_close()
+{
+  g_warning("gc_sound_fx_close");
+  if (fx_pipeline)
+    {
+      gst_element_set_state(fx_pipeline, GST_STATE_NULL);
+      gst_object_unref(GST_OBJECT(fx_pipeline));
+      fx_pipeline = NULL;
+    }
+  g_warning("gc_sound_fx_close done");
+}
+
+void
+gc_sound_bg_reopen()
+{
+  if(gc_prop_get()->music)
+    bg_play(NULL);
+}
+
+void
+gc_sound_fx_reopen()
+{
+}
+
+void
+gc_sound_reopen()
+{
+  gc_sound_bg_reopen();
+  gc_sound_fx_reopen();
+}
+
+void
+gc_sound_bg_pause()
+{
+  if (bg_pipeline)
+  {
+    gst_element_set_state(bg_pipeline, GST_STATE_PAUSED);
+  }
+  bg_paused = TRUE;
+}
+
+void
+gc_sound_bg_resume()
+{
+  if(bg_pipeline)
+    gst_element_set_state(bg_pipeline, GST_STATE_PLAYING);
+  else
+    {
+      bg_paused = FALSE;
+      gc_sound_bg_reopen();
+    }
+
+  bg_paused = FALSE;
+}
+
+void
+gc_sound_fx_pause()
+{
+  if (fx_pipeline)
+  {
+    gst_element_set_state(fx_pipeline, GST_STATE_PAUSED);
+  }
+  fx_paused = TRUE;
+}
+
+void
+gc_sound_fx_resume()
+{
+  if(fx_pipeline)
+  {
+    gst_element_set_state(fx_pipeline, GST_STATE_PLAYING);
+  }
+  fx_paused = FALSE;
+}
+
+/* background play
+ *
+ */
+gpointer
+bg_play(gpointer dummy)
+{
+  gchar *absolute_file = gc_sound_get_next_music();
+
+  if (!absolute_file)
+    return NULL;
+
+  bg_pipeline = gst_element_factory_make ("playbin", "play");
+
+  if(!bg_pipeline)
+    {
+      g_warning("Failed to build the gstreamer pipeline (for background music)");
+      gc_prop_get()->music = 0;
+      return NULL;
+    }
+
+  gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (bg_pipeline)),
+		     bg_bus, bg_pipeline);
+
+
+  gchar *uri = g_strconcat("file://", absolute_file, NULL);
+  g_free(absolute_file);
+  g_warning("  bg_play %s", uri);
+
+  g_object_set (G_OBJECT (bg_pipeline), "uri", uri, NULL);
+
+  gst_element_set_state (bg_pipeline, GST_STATE_PLAYING);
+
+  g_free(uri);
+
+  return(NULL);
+}
+
+/* playing a single file
+ *
+ */
+void
+fx_play()
+{
+  gchar *file;
+  gchar *absolute_file;
+  GcomprisProperties *properties = gc_prop_get();
+
+  if(fx_pipeline)
+    return;
+
+  file = get_next_sound_to_play();
+
+  if(!file)
+    return;
+
+  g_warning("  fx_play %s", file);
+
+  absolute_file = gc_file_find_absolute(file);
+
+  if (!absolute_file ||
+      !properties->fx)
+    return;
+
+  fx_pipeline = gst_element_factory_make ("playbin", "play");
+
+  if (!fx_pipeline)
+    {
+      g_warning("Failed to build the gstreamer pipeline");
+      gc_prop_get()->fx = 0;
+      return;
+    }
+
+  gchar *uri = g_strconcat("file://", absolute_file, NULL);
+  g_free(absolute_file);
+  g_warning("   uri '%s'", uri);
+
+  g_object_set (G_OBJECT (fx_pipeline), "uri", uri, NULL);
+  gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (fx_pipeline)),
+		     fx_bus, file);
+
+  gst_element_set_state (fx_pipeline, GST_STATE_PLAYING);
+
+  g_free(uri);
+
+  return;
+}
+
diff --git a/src/gcompris/soundutil.c b/src/gcompris/soundutil.c
index abe1a5f..38dd1cb 100644
--- a/src/gcompris/soundutil.c
+++ b/src/gcompris/soundutil.c
@@ -18,193 +18,23 @@
 
 #include "string.h"
 
-#ifdef __APPLE__
-#   include <sys/types.h>
-#endif
 #include "gcompris.h"
 #include <signal.h>
 #include <glib.h>
-#include <gst/gst.h>
+
+#include <soundutil.h>
 
 static GList	*pending_queue = NULL;
 static int	 sound_policy;
-static gboolean	 fx_paused = FALSE;
-static gboolean	 bg_paused = FALSE;
-
-static GstElement *bg_pipeline = NULL;
-static GstElement *fx_pipeline = NULL;
-
-static guint bg_music_index;
-
-GSList *music_list;
-
-/* Singleton */
-static guint	 sound_init = 0;
 
-/* Forward function declarations */
-static void	 fx_play ();
-static char	*get_next_sound_to_play( );
+static GSList *music_list = NULL;
 
-static gpointer  bg_play (gpointer dummy);
-static GSList   *bg_build_music_list();
-
-/* sound control */
-void gc_sound_callback(gchar *file);
 GHashTable *sound_callbacks = NULL;
 
 /* =====================================================================
  *
  * =====================================================================*/
 void
-gc_sound_init()
-{
-
-  /* Check to run the init only once */
-  if(sound_init == 1)
-    return;
-
-  sound_init = 1;
-
-  /* gstreamer init */
-  gst_init(NULL, NULL);
-
-  sound_policy = PLAY_AFTER_CURRENT;
-
-  music_list = bg_build_music_list();
-}
-
-static gboolean
-fx_bus(GstBus* bus, GstMessage* msg, gpointer data)
-{
-  switch( GST_MESSAGE_TYPE( msg ) )
-    {
-    case GST_MESSAGE_EOS:
-      g_warning("fx_bus: EOS START");
-      gc_sound_fx_close();
-      gc_sound_callback((gchar *)data);
-      fx_play();
-      g_warning("fx_bus: EOS END");
-      break;
-    default:
-      return TRUE;
-    }
-
-  return FALSE;
-}
-
-static gboolean
-bg_bus(GstBus* bus, GstMessage* msg, gpointer data)
-{
-  switch( GST_MESSAGE_TYPE( msg ) ) {
-    case GST_MESSAGE_EOS:
-        g_warning("bg_bus: EOS");
-	gc_sound_bg_close();
-	bg_play(NULL);
-	break;
-    default:
-      return TRUE;
-  }
-  return FALSE;
-}
-
-void
-gc_sound_close()
-{
-  gc_sound_bg_close();
-  gc_sound_fx_close();
-}
-
-void
-gc_sound_bg_close()
-{
-  if (bg_pipeline)
-    {
-      gst_element_set_state(bg_pipeline, GST_STATE_NULL);
-      gst_object_unref(GST_OBJECT(bg_pipeline));
-      bg_pipeline = NULL;
-    }
-}
-
-void
-gc_sound_fx_close()
-{
-  g_warning("gc_sound_fx_close");
-  if (fx_pipeline)
-    {
-      gst_element_set_state(fx_pipeline, GST_STATE_NULL);
-      gst_object_unref(GST_OBJECT(fx_pipeline));
-      fx_pipeline = NULL;
-    }
-  g_warning("gc_sound_fx_close done");
-}
-
-void
-gc_sound_bg_reopen()
-{
-  if(gc_prop_get()->music)
-    bg_play(NULL);
-}
-
-void
-gc_sound_fx_reopen()
-{
-}
-
-void
-gc_sound_reopen()
-{
-  gc_sound_bg_reopen();
-  gc_sound_fx_reopen();
-}
-
-void
-gc_sound_bg_pause()
-{
-  if (bg_pipeline)
-  {
-    gst_element_set_state(bg_pipeline, GST_STATE_PAUSED);
-  }
-  bg_paused = TRUE;
-}
-
-void
-gc_sound_bg_resume()
-{
-  if(bg_pipeline)
-    gst_element_set_state(bg_pipeline, GST_STATE_PLAYING);
-  else
-    {
-      bg_paused = FALSE;
-      gc_sound_bg_reopen();
-    }
-
-  bg_paused = FALSE;
-}
-
-void
-gc_sound_fx_pause()
-{
-  if (fx_pipeline)
-  {
-    gst_element_set_state(fx_pipeline, GST_STATE_PAUSED);
-  }
-  fx_paused = TRUE;
-}
-
-void
-gc_sound_fx_resume()
-{
-  if(fx_pipeline)
-  {
-    gst_element_set_state(fx_pipeline, GST_STATE_PLAYING);
-  }
-  fx_paused = FALSE;
-}
-
-/* =====================================================================
- *
- * =====================================================================*/
-void
 gc_sound_policy_set(int policy)
 {
   switch (policy)
@@ -224,18 +54,33 @@ gc_sound_policy_get()
   return sound_policy;
 }
 
-static GSList *
-bg_build_music_list()
+GSList *
+gc_sound_get_music_list()
+{
+  return music_list;
+}
+
+char *gc_sound_get_next_music()
+{
+  static guint bg_music_index = 0;
+
+  /* Music wrapping */
+  if(bg_music_index++ >= g_slist_length(gc_sound_get_music_list()))
+    bg_music_index = 0;
+
+  return gc_file_find_absolute(g_slist_nth_data(gc_sound_get_music_list(),
+							 bg_music_index));
+}
+
+void
+gc_sound_build_music_list()
 {
   GcomprisProperties *properties = gc_prop_get();
   gchar *str;
   gchar *music_dir;
-  GSList *musiclist = NULL;
   GDir *dir;
   const gchar *one_dirent;
 
-  bg_music_index = 0;
-
   /* Load the Music directory file names */
   music_dir = g_strconcat(properties->package_data_dir, "/music/background",
 			  NULL);
@@ -245,7 +90,7 @@ bg_build_music_list()
   if (!dir) {
     g_warning ("Couldn't open music dir: %s", music_dir);
     g_free(music_dir);
-    return NULL;
+    return;
   }
 
   /* Fill up the music list */
@@ -254,122 +99,26 @@ bg_build_music_list()
       if (g_str_has_suffix(one_dirent, ".ogg"))
 	{
 	  str = g_strdup_printf("%s/%s", music_dir, one_dirent);
-	  musiclist = g_slist_insert (musiclist, str,
-				      RAND(0, g_slist_length(musiclist)));
+	  music_list = g_slist_insert (music_list, str,
+				      RAND(0, g_slist_length(music_list)));
 	}
     }
   g_dir_close(dir);
 
   /* No music no play */
-  if(g_slist_length(musiclist)==0)
+  if(g_slist_length(music_list)==0)
     {
       g_free(music_dir);
-      return NULL;
-    }
-
-  return(musiclist);
-}
-
-/* =====================================================================
- * Thread scheduler background :
- *	- launches a single thread for playing and play any file found
- *        in the gcompris music directory
- ======================================================================*/
-static gpointer
-bg_play(gpointer dummy)
-{
-  gchar *absolute_file;
-
-  /* Music wrapping */
-  if(bg_music_index >= g_slist_length(music_list))
-    bg_music_index = 0;
-
-  absolute_file = gc_file_find_absolute(g_slist_nth_data(music_list,
-							 bg_music_index));
-
-  if (!absolute_file)
-    return NULL;
-
-  bg_pipeline = gst_element_factory_make ("playbin", "play");
-
-  if(!bg_pipeline)
-    {
-      g_warning("Failed to build the gstreamer pipeline (for background music)");
-      gc_prop_get()->music = 0;
-      return NULL;
-    }
-
-  gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (bg_pipeline)),
-		     bg_bus, bg_pipeline);
-
-
-  gchar *uri = g_strconcat("file://", absolute_file, NULL);
-  g_free(absolute_file);
-  g_warning("  bg_play %s", uri);
-
-  g_object_set (G_OBJECT (bg_pipeline), "uri", uri, NULL);
-
-  gst_element_set_state (bg_pipeline, GST_STATE_PLAYING);
-
-  g_free(uri);
-
-  return(NULL);
-}
-
-/* =====================================================================
- * Thread function for playing a single file
- ======================================================================*/
-static void
-fx_play()
-{
-  gchar *file;
-  gchar *absolute_file;
-  GcomprisProperties *properties = gc_prop_get();
-
-  if(fx_pipeline)
-    return;
-
-  file = get_next_sound_to_play();
-
-  if(!file)
-    return;
-
-  g_warning("  fx_play %s", file);
-
-  absolute_file = gc_file_find_absolute(file);
-
-  if (!absolute_file ||
-      !properties->fx)
-    return;
-
-  fx_pipeline = gst_element_factory_make ("playbin", "play");
-
-  if (!fx_pipeline)
-    {
-      g_warning("Failed to build the gstreamer pipeline");
-      gc_prop_get()->fx = 0;
       return;
     }
 
-  gchar *uri = g_strconcat("file://", absolute_file, NULL);
-  g_free(absolute_file);
-  g_warning("   uri '%s'", uri);
-
-  g_object_set (G_OBJECT (fx_pipeline), "uri", uri, NULL);
-  gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (fx_pipeline)),
-		     fx_bus, file);
-
-  gst_element_set_state (fx_pipeline, GST_STATE_PLAYING);
-
-  g_free(uri);
-
-  return;
 }
 
+
 /* =====================================================================
  * Returns the next sound play, or NULL if there is no
  ======================================================================*/
-static char*
+char*
 get_next_sound_to_play( )
 {
   char* tmpSound = NULL;
diff --git a/src/gcompris/soundutil.h b/src/gcompris/soundutil.h
index 05eadaf..364f957 100644
--- a/src/gcompris/soundutil.h
+++ b/src/gcompris/soundutil.h
@@ -58,4 +58,13 @@ void	 gc_sound_fx_resume(void);
 gchar   *gc_sound_alphabet(gchar *chars);
 
 
+void	 fx_play ();
+char	*get_next_sound_to_play( );
+
+gpointer bg_play (gpointer dummy);
+char	*gc_sound_get_next_music();
+void	 gc_sound_build_music_list();
+
+void gc_sound_callback(gchar *file);
+
 #endif



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