<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40582 >

Hello all,

I tried to make a GStreamer audio plugin for Freeciv. It's a work in
progress but it already works well. It's my first contribution so,
please let me know if there are any rules I break.
I'm working on a Linux machine so I didn't test this on other
platforms but because GStreamer can run on all the other supported
platforms it should not be a problem I think.

Gr,
Thijs

---
 client/Makefile.am |   20 ++++-
 client/audio.c     |   17 ++++-
 client/audio_gst.c |  180 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 client/audio_gst.h |   18 +++++
 configure.ac       |   13 +++
 5 files changed, 240 insertions(+), 8 deletions(-)

--- freeciv.orig/client/Makefile.am
+++ freeciv/client/Makefile.am
@@ -33,11 +33,17 @@
 AUDIO_SDL_FILES=$(ALL_AUDIO_SDL_FILES)
 endif
 
+ALL_AUDIO_GST_FILES=audio_gst.c audio_gst.h
+
+if AUDIO_GST
+AUDIO_GST_FILES=$(ALL_AUDIO_GST_FILES)
+endif
+
 if MINGW32
 CLIENTICON=../win32/clienticon.o
 endif
 
-EXTRA_DIST= $(ALL_AUDIO_SDL_FILES)
+EXTRA_DIST= $(ALL_AUDIO_SDL_FILES) $(ALL_AUDIO_GST_FILES)
 
 ## This is usually false, so "include" is not recursed into 
 ## by 'make', but it can be enabled in configure, and it is
@@ -53,9 +59,10 @@
 
 bin_PROGRAMS = civclient
 
-AM_CPPFLAGS = -I$(top_srcdir)/utility -I$(srcdir)/include -I$(top_srcdir)/common -I$(top_srcdir)/common/aicore -I$(srcdir)/agents $(CLIENT_CFLAGS) $(SOUND_CFLAGS) $(LIBGGZ_INCLUDES) $(GGZMOD_INCLUDES) $(GGZ_GTK_INCLUDES)
+AM_CPPFLAGS = -I$(top_srcdir)/utility -I$(srcdir)/include -I$(top_srcdir)/common -I$(top_srcdir)/common/aicore -I$(srcdir)/agents $(CLIENT_CFLAGS) $(SOUND_CFLAGS) $(LIBGGZ_INCLUDES) $(GGZMOD_INCLUDES) $(GGZ_GTK_INCLUDES) $(GSTREAMER_CFLAGS)
 
 civclient_SOURCES = $(AUDIO_SDL_FILES) \
+	$(AUDIO_GST_FILES)	\
 	attribute.h	\
 	attribute.c	\
 	citydlg_common.c \
@@ -114,9 +121,9 @@
 	themes_common.h	\
 	tilespec.c	\
 	tilespec.h	\
-	audio.c         \
-	audio.h         \
-	audio_none.c    \
+	audio.c	\
+	audio.h	\
+	audio_none.c	\
 	audio_none.h
 
 # packhand_gen.c & packhand_gen.h are generated files, but as they are
@@ -132,7 +139,8 @@
 		 	$(gui_sources)/libguiclient.a
 civclient_DEPENDENCIES = $(fc_civclient_libs)
 civclient_LDADD        = $(fc_civclient_libs) $(fc_civclient_libs) \
-	$(INTLLIBS) $(CLIENT_LIBS) $(SOUND_LIBS) $(LIB_GGZMOD) $(CLIENTICON)
+	$(INTLLIBS) $(CLIENT_LIBS) $(SOUND_LIBS) $(LIB_GGZMOD) $(CLIENTICON) \
+	$(GSTREAMER_LIBS)
 desktopfiledir = $(prefix)/share/applications
 desktopfile_DATA = \
 	freeciv.desktop
--- freeciv.orig/client/audio.c
+++ freeciv/client/audio.c
@@ -29,13 +29,18 @@
 #include "support.h"
 
 #include "audio_none.h"
+
+#ifdef AUDIO_GST
+#include "audio_gst.h"
+#endif
+
 #ifdef AUDIO_SDL
 #include "audio_sdl.h"
 #endif
 
 #include "audio.h"
 
-#define MAX_NUM_PLUGINS		2
+#define MAX_NUM_PLUGINS		3
 #define SNDSPEC_SUFFIX		".soundspec"
 
 /* keep it open throughout */
@@ -142,6 +147,10 @@
   assert(num_plugins_used == 1);
   selected_plugin = 0;
 
+#ifdef AUDIO_GST
+  audio_gst_init ();
+#endif
+
 #ifdef AUDIO_SDL
   audio_sdl_init();
 #endif
@@ -248,8 +257,12 @@
     return;
   }
 
+#ifdef AUDIO_GST
+  if (audio_select_plugin ("gst")) return;
+#endif
+
 #ifdef AUDIO_SDL
-  if (audio_select_plugin("sdl")) return; 
+  if (audio_select_plugin("sdl")) return;
 #endif
   freelog(LOG_NORMAL, _("No real audio subsystem managed to initialize!"));
   freelog(LOG_NORMAL,
--- /dev/null
+++ freeciv/client/audio_gst.c
@@ -0,0 +1,180 @@
+/**********************************************************************
+ Freeciv - Copyright (C) 2008 Thijs Vermeir <[EMAIL PROTECTED]>
+   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 2, 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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "support.h"
+
+#include "audio.h"
+#include "gui_main_g.h"
+
+#include "audio_gst.h"
+
+#include <gst/gst.h>
+
+static void my_stop(void);
+static void my_wait(void);
+
+GstElement *pipeline;
+GstElement *playbin;
+gchar *last_fullpath;
+GMutex *audio_lock;
+
+static void my_shutdown(void)
+{
+  GstState new_state;
+  GstStateChangeReturn ret;
+
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
+  gst_element_get_state (pipeline, &new_state, NULL, GST_CLOCK_TIME_NONE);
+
+  gst_object_unref (pipeline);
+  gst_object_unref (playbin);
+  if (last_fullpath)
+    g_free (last_fullpath);
+  if (audio_lock)
+    g_mutex_free (audio_lock);
+}
+
+static void my_stop(void)
+{
+  g_mutex_lock (audio_lock);
+  gst_element_set_state (pipeline, GST_STATE_READY);
+  g_mutex_unlock (audio_lock);
+}
+
+static void my_wait(void)
+{
+  GstState new_state;
+  GstStateChangeReturn ret;
+
+  g_mutex_lock (audio_lock);
+  ret = gst_element_get_state (pipeline, &new_state, NULL, GST_CLOCK_TIME_NONE);
+  while (ret == GST_STATE_CHANGE_SUCCESS && new_state == GST_STATE_PLAYING) {
+    ret = gst_element_get_state (pipeline, &new_state, NULL, GST_CLOCK_TIME_NONE);
+  }
+  g_mutex_unlock (audio_lock);
+}
+
+static bool my_play(const char *const tag, const char *const fullpath,
+        bool repeat)
+{
+  if (fullpath) {
+    gboolean last_fullpath_changed = FALSE;
+    GstState new_state;
+    GstStateChangeReturn ret;
+
+    g_mutex_lock (audio_lock);
+
+    if (!last_fullpath || g_strcmp0 (fullpath, last_fullpath) != 0) {
+      if (last_fullpath)
+        g_free (last_fullpath);
+      last_fullpath = g_strdup (fullpath);
+      gchar *full_uri = g_strdup_printf ("file://%s", fullpath);
+      g_object_set (G_OBJECT (playbin), "uri", full_uri, NULL);
+      g_free (full_uri);
+      last_fullpath_changed = TRUE;
+    }
+
+    ret = gst_element_get_state (pipeline, &new_state, NULL, GST_CLOCK_TIME_NONE);
+    if (ret != GST_STATE_CHANGE_SUCCESS)
+      goto no_change_succes;
+
+    if (new_state != GST_STATE_PAUSED || new_state != GST_STATE_PLAYING ||
+        last_fullpath_changed) {
+      gst_element_set_state (pipeline , GST_STATE_READY);
+      ret = gst_element_get_state (pipeline, &new_state, NULL, GST_CLOCK_TIME_NONE);
+      if (ret != GST_STATE_CHANGE_SUCCESS)
+        goto no_change_succes;
+
+      gst_element_set_state (pipeline , GST_STATE_PAUSED);
+      ret = gst_element_get_state (pipeline, &new_state, NULL, GST_CLOCK_TIME_NONE);
+      if (ret != GST_STATE_CHANGE_SUCCESS)
+        goto no_change_succes;
+
+    }
+    gst_element_seek_simple (pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, 0 * GST_SECOND);
+    gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
+
+no_change_succes:
+    g_mutex_unlock (audio_lock);
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+static void
+message_cb (GstBus *bus, GstMessage *message, gpointer user_data) {
+
+  g_mutex_lock (audio_lock);
+  switch (GST_MESSAGE_TYPE (message)) {
+    default:
+      break;
+  }
+  g_mutex_unlock (audio_lock);
+}
+
+static bool my_init(void)
+{
+  GstBus *bus;
+
+  pipeline = gst_pipeline_new ("freeciv_pipeline");
+  playbin = gst_element_factory_make ("playbin", NULL);
+  gst_object_ref (playbin);
+  gst_bin_add (GST_BIN (pipeline), playbin);
+  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+
+  gst_bus_add_signal_watch (bus);
+  g_signal_connect (bus, "message", (GCallback) message_cb,
+      NULL);
+
+  last_fullpath = NULL;
+  audio_lock = g_mutex_new ();
+
+  gst_object_unref (bus);
+
+  return TRUE;
+}
+
+static void my_set_volume (double volume) {
+  g_object_set (G_OBJECT (playbin), "volume", volume, NULL);
+}
+
+static double my_get_volume (void) {
+  double temp;
+  g_object_get (G_OBJECT (playbin), "volume", &temp, NULL);
+  return temp;
+}
+
+void audio_gst_init(void)
+{
+  gst_init (NULL, NULL);
+
+  struct audio_plugin self;
+
+  sz_strlcpy(self.name, "gst");
+  sz_strlcpy(self.descr, "GStreamer audio plugin");
+  self.init = my_init;
+  self.shutdown = my_shutdown;
+  self.stop = my_stop;
+  self.wait = my_wait;
+  self.play = my_play;
+  self.get_volume = my_get_volume;
+  self.set_volume = my_set_volume;
+  audio_add_plugin(&self);
+}
--- /dev/null
+++ freeciv/client/audio_gst.h
@@ -0,0 +1,18 @@
+/**********************************************************************
+ Freeciv - Copyright (C) 2008 - Thijs Vermeir <[EMAIL PROTECTED]>
+   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 2, 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.
+***********************************************************************/
+#ifndef FC__AUDIO_GST_H
+#define FC__AUDIO_GST_H
+
+void audio_gst_init(void);
+
+#endif				/* FC__AUDIO_GST_H */
--- freeciv.orig/configure.ac
+++ freeciv/configure.ac
@@ -566,6 +566,16 @@
   AC_CHECK_FUNCS([chdir mkdtemp])
 fi
 
+dnl Check for GStreamer
+PKG_CHECK_MODULES(GSTREAMER,
+                  gstreamer-0.10,
+                  HAVE_GST="yes",
+                  HAVE_GST="no")
+
+if test "x$HAVE_GST" = "xyes" ; then
+  AC_DEFINE(AUDIO_GST, 1, [Enable GStreamer audio])
+fi
+
 AC_SUBST(gui_sources)
 AC_SUBST(CLIENT_CFLAGS)
 AC_SUBST(CLIENT_CXXFLAGS)
@@ -577,7 +587,10 @@
 AC_SUBST([VERSION_WITHOUT_LABEL])
 AC_SUBST([VERSION_LABEL])
 AC_SUBST([HOST_PATH_SEPARATOR])
+AC_SUBST(GSTREAMER_CFLAGS)
+AC_SUBST(GSTREAMER_LIBS)
 AM_CONDITIONAL(AUDIO_SDL, test "x$SDL_mixer" = "xyes")
+AM_CONDITIONAL(AUDIO_GST, test "x$HAVE_GST" = "xyes")
 AM_CONDITIONAL(CLIENT_GUI_SDL, test "$gui_sources" = "gui-sdl")
 AM_CONDITIONAL(CLIENT_GUI_GTK_2_0, test "$gui_sources" = "gui-gtk-2.0")
 AM_CONDITIONAL(CLIENT_GUI_XAW, test "$gui_sources" = "gui-xaw")
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to