diff options
-rw-r--r-- | configure.in | 24 | ||||
-rw-r--r-- | src/gcompris/Makefile.am | 3 | ||||
-rw-r--r-- | src/gcompris/gcompris.c | 2 | ||||
-rw-r--r-- | src/gcompris/gstreamer.c | 269 | ||||
-rw-r--r-- | src/gcompris/soundutil.c | 309 | ||||
-rw-r--r-- | 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 |