Complete.Org: Mailing Lists: Archives: freeciv-dev: October 2005:
[Freeciv-Dev] (PR#14466) gstreamer audio support
Home

[Freeciv-Dev] (PR#14466) gstreamer audio support

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#14466) gstreamer audio support
From: "David A Knight" <david@xxxxxxxxxxxxxxxxxx>
Date: Wed, 26 Oct 2005 10:48:50 -0700
Reply-to: bugs@xxxxxxxxxxx

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

I've attached a quick hack for using gstreamer for sound.

audio_gst.c uses some glib functions, as gst requires glib and pulls in
glib.h itself this isn't an added dependancy.

current problems:

some of the stdsounds appear to have problems with gstreamer on my
system.

foot3.ogg for instance will result in 100% cpu usage, and also won't
play in gstreamer from the command line.  others play fine, but all can
be checked with

gst-launch-0.8 playbin uri=file:///path/to/the/file.ogg

if they play with that they should be fine with audio_gst.c

This code isn't tested much yet, nor with any other audio files than the
standard ogg files. (should work with any audio format gstreamer has
support for)


David

diff -urN -Xfreeciv/diff_ignore freeciv.orig/client/audio.c 
freeciv/client/audio.c
--- freeciv.orig/client/audio.c 2005-10-26 18:31:04.000000000 +0100
+++ freeciv/client/audio.c      2005-10-26 16:14:12.000000000 +0100
@@ -32,6 +32,9 @@
 #ifdef SDL
 #include "audio_sdl.h"
 #endif
+#ifdef GST
+#include "audio_gst.h"
+#endif
 
 #include "audio.h"
 
@@ -145,6 +148,9 @@
 #ifdef SDL
   audio_sdl_init();
 #endif
+#ifdef GST
+  audio_gst_init();
+#endif
 }
 
 /**************************************************************************
@@ -200,6 +206,8 @@
       _("For sound support, install SDL_mixer"));
     freelog(LOG_NORMAL, _("http://www.libsdl.org/";
       "projects/SDL_mixer/index.html"));
+    freelog(LOG_NORMAL, _("Or gstreamer 0.8.x"));
+    freelog(LOG_NORMAL, _("http://gstreamer.freedesktop.org/";));
     tagfile = NULL;
     return;
   }
@@ -253,6 +261,9 @@
 #ifdef SDL
   if (audio_select_plugin("sdl")) return; 
 #endif
+#ifdef GST
+  if (audio_select_plugin("gst")) return;
+#endif
   freelog(LOG_ERROR,
     _("No real audio subsystem managed to initialize!"));
   freelog(LOG_ERROR,
diff -urN -Xfreeciv/diff_ignore freeciv.orig/client/audio_gst.c 
freeciv/client/audio_gst.c
--- freeciv.orig/client/audio_gst.c     1970-01-01 01:00:00.000000000 +0100
+++ freeciv/client/audio_gst.c  2005-10-26 18:07:51.000000000 +0100
@@ -0,0 +1,187 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
+   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 <gst/gst.h>
+
+#include <unistd.h>
+
+#include "log.h"
+#include "support.h"
+
+#include "audio.h"
+
+#include "audio_gst.h"
+
+GstElement *play;
+
+static void cb_eos (GstElement *play, gpointer data)
+{
+  bool repeat;
+
+  repeat = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (play),
+                         "repeating"));
+  gst_element_set_state (play, GST_STATE_NULL);
+  
+  if (repeat) {
+    if (gst_element_set_state (play, GST_STATE_PLAYING) != GST_STATE_SUCCESS) {
+       /* failed to play again */
+     }
+
+  }
+}
+
+static void cb_error (GstElement *play, GstElement *src, GError *err,
+               gchar *debug, gpointer data )
+{
+  g_print ("Error: %s\n", err->message);
+}
+
+/**************************************************************************
+  Set the volume.
+**************************************************************************/
+static void my_set_volume(double volume)
+{
+  if (play) {
+    g_object_set (G_OBJECT (play), "volume", volume, NULL);
+  }
+}
+
+/**************************************************************************
+  Get the volume.
+**************************************************************************/
+static double my_get_volume(void)
+{
+  double vol;
+
+  vol = 1.0;
+  if (play) {
+    g_object_get (G_OBJECT (play), "volume", &vol, NULL);
+  }
+
+  return vol;
+}
+
+/**************************************************************************
+  Play sound
+**************************************************************************/
+static bool my_play(const char *const tag, const char *const fullpath,
+                   bool repeat)
+{
+  int ret;
+  char buf[PATH_MAX];
+  char *tmp;
+  
+  ret = FALSE;
+  
+  if (fullpath && play) {
+    if (getcwd (buf, PATH_MAX) && *fullpath != "/") {
+        tmp = g_strconcat ("file://", buf, "/", fullpath, NULL);
+    } else {
+       tmp = g_strdup (fullpath);
+    }
+    
+    gst_element_set_state (play, GST_STATE_NULL);
+    g_object_set (G_OBJECT (play), "uri", tmp, NULL);
+    if (gst_element_set_state (play, GST_STATE_PLAYING) == GST_STATE_SUCCESS) {
+      ret = TRUE;
+     }
+    g_object_set_data (G_OBJECT (play), "repeating",
+                     GINT_TO_POINTER (repeat & ret));
+    g_free (tmp);
+  }
+  
+  return ret;
+}
+
+/**************************************************************************
+  Stop music
+**************************************************************************/
+static void my_stop(void)
+{
+  if (play) {
+    if (gst_element_set_state (play, GST_STATE_NULL) != GST_STATE_SUCCESS) {
+      /* not much we can do, stopping has failed */
+
+    }
+  }
+}
+
+/**************************************************************************
+  Wait for audio to die on all channels.
+  WARNING: If a channel is looping, it will NEVER exit! Always call
+  music_stop() first!
+**************************************************************************/
+static void my_wait(void)
+{
+  if (play) {
+    gst_element_wait_state_change (play);
+  }
+}
+
+/**************************************************************************
+  Clean up.
+**************************************************************************/
+static void my_shutdown(void)
+{
+  if (play) {
+    gst_element_set_state (play, GST_STATE_NULL);
+    gst_object_unref (GST_OBJECT (play));
+  }
+}
+
+/**************************************************************************
+  Initialize.
+**************************************************************************/
+static bool my_init(void)
+{
+  int ret;
+  
+  g_thread_init(NULL); 
+  ret = FALSE;
+  if (gst_init_check (NULL, NULL)) {
+    play = gst_element_factory_make ("playbin", "play");
+    if (play) {
+      g_signal_connect (play, "eos", G_CALLBACK (cb_eos), NULL);
+      g_signal_connect (play, "error", G_CALLBACK (cb_error), NULL);
+      ret = TRUE;
+    }
+  }
+
+  return ret;
+}
+
+/**************************************************************************
+  Initialize. Note that this function is called very early at the
+  client startup. So for example logging isn't available.
+**************************************************************************/
+void audio_gst_init(void)
+{
+  struct audio_plugin self;
+
+  sz_strlcpy(self.name, "gst");
+  sz_strlcpy(self.descr, "Gstreamer plugin");
+  self.init = my_init;
+  self.shutdown = my_shutdown;
+  self.stop = my_stop;
+  self.wait = my_wait;
+  self.play = my_play;
+  self.set_volume = my_set_volume;
+  self.get_volume = my_get_volume;
+  audio_add_plugin(&self);
+}
diff -urN -Xfreeciv/diff_ignore freeciv.orig/client/audio_gst.h 
freeciv/client/audio_gst.h
--- freeciv.orig/client/audio_gst.h     1970-01-01 01:00:00.000000000 +0100
+++ freeciv/client/audio_gst.h  2005-10-26 15:06:48.000000000 +0100
@@ -0,0 +1,18 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
+   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 */
diff -urN -Xfreeciv/diff_ignore freeciv.orig/client/Makefile.am 
freeciv/client/Makefile.am
--- freeciv.orig/client/Makefile.am     2005-10-26 18:31:04.000000000 +0100
+++ freeciv/client/Makefile.am  2005-10-26 15:33:02.000000000 +0100
@@ -33,6 +33,12 @@
 SDL_FILES=$(ALL_SDL_FILES)
 endif
 
+ALL_GST_FILES=audio_gst.c audio_gst.h
+
+if GST
+GST_FILES=$(ALL_GST_FILES)
+endif
+
 EXTRA_DIST=    gui-mui/autogroupclass.c         \
                gui-mui/autogroupclass.h         \
                gui-mui/chatline.c               \
@@ -101,7 +107,8 @@
                gui-mui/worklistclass.c          \
                gui-mui/worklistclass.h          \
                \
-               $(ALL_SDL_FILES)
+               $(ALL_SDL_FILES)                 \
+               $(ALL_GST_FILES)
 
 
 ## This is usually false, so "include" is not recursed into 
@@ -122,7 +129,7 @@
 
 ## Above, note -I../intl instead of -I$(top_srdir/intl) is deliberate.
 
-civclient_SOURCES = $(ESD_FILES) $(SDL_FILES) $(ALSA_FILES) $(WINMM_FILES) \
+civclient_SOURCES = $(ESD_FILES) $(SDL_FILES) $(GST_FILES) $(ALSA_FILES) 
$(WINMM_FILES) \
        attribute.h     \
        attribute.c     \
        citydlg_common.c \
diff -urN -Xfreeciv/diff_ignore freeciv.orig/configure.ac freeciv/configure.ac
--- freeciv.orig/configure.ac   2005-10-26 18:31:04.000000000 +0100
+++ freeciv/configure.ac        2005-10-26 15:40:10.000000000 +0100
@@ -426,7 +426,7 @@
     AC_MSG_ERROR(could not guess which client to compile)
   fi
 
-  dnl Check for sound support, sets SOUND_CFLAGS, SOUND_LIBS, SDL
+  dnl Check for sound support, sets SOUND_CFLAGS, SOUND_LIBS, SDL, GST
   FC_CHECK_SOUND()
 
   gui_sources="gui-$client"
@@ -442,6 +442,7 @@
 AC_SUBST(VERSION_WITHOUT_LABEL)
 AC_SUBST(VERSION_LABEL)
 AM_CONDITIONAL(SDL, test "x$SDL_mixer" = "xyes")
+AM_CONDITIONAL(GST, test "x$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")
diff -urN -Xfreeciv/diff_ignore freeciv.orig/m4/sound.m4 freeciv/m4/sound.m4
--- freeciv.orig/m4/sound.m4    2005-10-26 18:26:14.000000000 +0100
+++ freeciv/m4/sound.m4 2005-10-26 16:08:14.000000000 +0100
@@ -1,7 +1,7 @@
 AC_DEFUN([FC_CHECK_SOUND],[
  AC_ARG_ENABLE(sdl-mixer,
    [  --disable-sdl-mixer     Do not try to use the SDL mixer],
-   USE_SOUND=no, USE_SOUND_SDL=yes)
+   USE_SOUND_SDL=no, USE_SOUND_SDL=yes)
 
  if test "x$USE_SOUND_SDL" = "xyes"; then
   dnl Add SDL support to client
@@ -26,4 +26,22 @@
     fi
   fi
  fi
+
+ AC_ARG_ENABLE(gst,
+   [  --disable-gst     Do not try to use gstreamer],
+   USE_SOUND_GST=no, USE_SOUND_GST=yes)
+ if test "x$USE_SOUND_GST" = "xyes"; then
+  dnl Add Gstreamer support to client
+  GST_VERSION=0.8.0
+  AC_PATH_PROG([PKG_CONFIG], [pkg-config], [no])
+  PKG_CHECK_MODULES(GST, gstreamer-0.8 >= $GST_VERSION)
+  AC_DEFINE(GST, 1, [GStreamer support])
+  GST=yes
+  SOUND_CFLAGS="$SOUND_CFLAGS $GST_CFLAGS"
+  SOUND_LIBS="$SOUND_LIBS $GST_LIBS"
+ fi
+
+ if test "x$USE_SOUND_SDL" = "xyes" || "x$USE_SOUND_GST" = "xyes"; then
+   USE_SOUND="yes"
+ fi
 ])

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#14466) gstreamer audio support, David A Knight <=