Mercurial > pidgin
changeset 13718:988186eb1688
[gaim-migrate @ 16127]
Use Gstreamer for IM sounds, kill ao/audiofile
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Tue, 02 May 2006 22:24:46 +0000 |
parents | 3b3430042849 |
children | e053c843700f |
files | configure.ac src/Makefile.am src/gtkdialogs.c src/gtkprefs.c src/gtksound.c |
diffstat | 5 files changed, 89 insertions(+), 223 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.ac Tue May 02 20:07:55 2006 +0000 +++ b/configure.ac Tue May 02 22:24:46 2006 +0000 @@ -159,6 +159,17 @@ ] ) +dnl ####################################################################### +dnl # GStreamer +dnl ####################################################################### +enable_gst=yes +PKG_CHECK_MODULES(GSTREAMER, gstreamer-0.10, ,enable_gst=no) +AC_SUBST(GSTREAMER_CFLAGS) +AC_SUBST(GSTREAMER_LIBS) +AC_ARG_ENABLE(gstreamer,[ --disable-gstreamer compile with GStreamer audio support],enable_gst=no) +if test "x$enable_gst" = "xyes"; then + AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer for making sounds]) +fi dnl ####################################################################### dnl # Check for Meanwhile headers (for Sametime) @@ -468,7 +479,6 @@ AM_CONDITIONAL(DYNAMIC_YAHOO, test "x$dynamic_yahoo" = "xyes") AM_CONDITIONAL(DYNAMIC_ZEPHYR, test "x$dynamic_zephyr" = "xyes") -AC_ARG_ENABLE(audio, [ --disable-audio compile without libao/libaudiofile for sound playing],,enable_audio=yes) AC_ARG_ENABLE(mono, [ --enable-mono compile with Mono runtime support],,enable_mono=no) AC_ARG_ENABLE(plugins, [ --disable-plugins compile without plugin support],,enable_plugins=yes) AC_ARG_ENABLE(perl, [ --disable-perl compile without perl scripting],,enable_perl=yes) @@ -1530,23 +1540,6 @@ fi fi -if test "$enable_audio" = yes ; then - GAIM_PATH_AO(found_ao_lib=true) - - AM_PATH_AUDIOFILE([0.2.0], found_af_lib=true) - - if test "$found_ao_lib" = "true" -a "$found_af_lib" = "true"; then - SOUND_LIBS="$SOUND_LIBS $AO_LIBS $AUDIOFILE_LIBS" - AC_SUBST(SOUND_LIBS) - AC_DEFINE(USE_AO, 1, [Define if we're using libao and libaudiofile for sound playing]) - enable_audio=yes - else - enable_audio=no - fi -else - enable_audio=no -fi - if test "$ac_cv_cygwin" = yes ; then LDADD="$LDADD -static" AC_DEFINE(DEBUG, 1, [Define if debugging is enabled.]) @@ -1767,12 +1760,12 @@ echo UI Library.................... : GTK+ 2.x echo SSL Library/Libraries......... : $msg_ssl echo +echo Build with GStreamer support.. : $enable_gst echo Build with Plugin support..... : $enable_plugins echo Build with Mono support....... : $enable_mono echo Build with Perl support....... : $enable_perl echo Build with Tcl support........ : $enable_tcl echo Build with Tk support......... : $enable_tk -echo Build with Audio support...... : $enable_audio echo Build with GtkSpell support... : $enable_gtkspell echo Build with DBUS support....... : $enable_dbus if test x$enable_dbus = xyes ; then
--- a/src/Makefile.am Tue May 02 20:07:55 2006 +0000 +++ b/src/Makefile.am Tue May 02 22:24:46 2006 +0000 @@ -336,7 +336,7 @@ @LIBOBJS@ \ $(GTK_LIBS) \ $(DBUS_LIBS) \ - $(SOUND_LIBS) \ + $(GSTREAMER_LIBS) \ $(STATIC_LINK_LIBS) \ $(XSS_LIBS) \ $(SM_LIBS) \ @@ -351,8 +351,7 @@ -DLOCALEDIR=\"$(datadir)/locale\" \ -DSYSCONFDIR=\"$(sysconfdir)\" \ -I$(top_srcdir)/plugins \ - $(AUDIOFILE_CFLAGS) \ - $(AO_CFLAGS) \ + $(GSTREAMER_CFLAGS) \ $(DEBUG_CFLAGS) \ $(GTK_CFLAGS) \ $(DBUS_CFLAGS) \
--- a/src/gtkdialogs.c Tue May 02 20:07:55 2006 +0000 +++ b/src/gtkdialogs.c Tue May 02 22:24:46 2006 +0000 @@ -456,10 +456,10 @@ #endif #ifndef _WIN32 -#ifdef USE_AO - g_string_append(str, " <b>libao:</b> Enabled<br/>"); +#ifdef USE_GSTREAMER + g_string_append(str, " <b>gstreamer:</b> Enabled<br/>"); #else - g_string_append(str, " <b>libao:</b> Disabled<br/>"); + g_string_append(str, " <b>gstreamer:</b> Disabled<br/>"); #endif #endif
--- a/src/gtkprefs.c Tue May 02 20:07:55 2006 +0000 +++ b/src/gtkprefs.c Tue May 02 22:24:46 2006 +0000 @@ -1354,7 +1354,7 @@ gtk_widget_set_sensitive(vbox, strcmp(method, "none")); } -#ifdef USE_AO +#ifdef USE_GSTREAMER static void sound_changed3_cb(const char *name, GaimPrefType type, gconstpointer value, gpointer data) @@ -1368,7 +1368,7 @@ !strcmp(method, "esd") || !strcmp(method, "nas")); } -#endif /* USE_AO */ +#endif /* USE_GSTREAMER */ #endif /* !_WIN32 */ @@ -1470,7 +1470,7 @@ G_CALLBACK(sound_chosen_cb), NULL, GINT_TO_POINTER(sound_row_sel)); } -#ifdef USE_AO +#ifdef USE_GSTREAMER static gchar* prefs_sound_volume_format(GtkScale *scale, gdouble val) { if(val < 15) { @@ -1553,7 +1553,7 @@ dd = gaim_gtk_prefs_dropdown(vbox, _("_Method:"), GAIM_PREF_STRING, "/gaim/gtk/sound/method", _("Console beep"), "beep", -#ifdef USE_AO +#ifdef USE_GSTREAMER _("Automatic"), "automatic", "Arts", "arts", "ESD", "esd", @@ -1600,7 +1600,7 @@ gaim_gtk_prefs_checkbox(_("_Sounds while away"), "/core/sound/while_away", vbox); -#ifdef USE_AO +#ifdef USE_GSTREAMER hbox = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
--- a/src/gtksound.c Tue May 02 20:07:55 2006 +0000 +++ b/src/gtksound.c Tue May 02 22:24:46 2006 +0000 @@ -31,10 +31,9 @@ #include <mmsystem.h> #endif -#ifdef USE_AO -# include <ao/ao.h> -# include <audiofile.h> -#endif /* USE_AO */ +#ifdef USE_GSTREAMER +# include <gst/gst.h> +#endif /* USE_GSTREAMER */ #include "debug.h" #include "notify.h" @@ -55,7 +54,6 @@ static guint mute_login_sounds_timeout = 0; static gboolean mute_login_sounds = FALSE; -static gboolean sound_initialized = FALSE; static struct gaim_sound_event sounds[GAIM_NUM_SOUNDS] = { {N_("Buddy logs in"), "login", "login.wav"}, @@ -72,10 +70,6 @@ {N_("Someone says your screen name in chat"), "nick_said", "alert.wav"} }; -#ifdef USE_AO -static int ao_driver = -1; -#endif /* USE_AO */ - static gboolean unmute_login_sounds_cb(gpointer data) { @@ -235,35 +229,6 @@ mute_login_sounds_timeout = gaim_timeout_add(10000, unmute_login_sounds_cb, NULL); } -static void -_pref_sound_method_changed(const char *name, GaimPrefType type, - gconstpointer val, gpointer data) -{ - if(type != GAIM_PREF_STRING || strcmp(name, "/gaim/gtk/sound/method")) - return; - - sound_initialized = TRUE; - -#ifdef USE_AO - ao_driver = -1; - - if(!strcmp(val, "esd")) - ao_driver = ao_driver_id("esd"); - else if(!strcmp(val, "arts")) - ao_driver = ao_driver_id("arts"); - else if(!strcmp(val, "nas")) - ao_driver = ao_driver_id("nas"); - else if(!strcmp(val, "automatic")) - ao_driver = ao_default_driver_id(); - - if(ao_driver != -1) { - ao_info *info = ao_driver_info(ao_driver); - gaim_debug_info("sound", - "Sound output driver loaded: %s\n", info->name); - } -#endif /* USE_AO */ -} - const char * gaim_gtk_sound_get_event_option(GaimSoundEventID event) { @@ -332,13 +297,10 @@ gaim_prefs_add_string("/gaim/gtk/sound/method", "automatic"); gaim_prefs_add_int("/gaim/gtk/sound/volume", 50); -#ifdef USE_AO +#ifdef USE_GSTREAMER gaim_debug_info("sound", "Initializing sound output drivers.\n"); - ao_initialize(); -#endif /* USE_AO */ - - gaim_prefs_connect_callback(gaim_gtk_sound_get_handle(), "/gaim/gtk/sound/method", - _pref_sound_method_changed, NULL); + gst_init(NULL, NULL); +#endif /* USE_GSTREAMER */ gaim_signal_connect(blist_handle, "buddy-signed-on", gtk_sound_handle, GAIM_CALLBACK(buddy_state_cb), @@ -369,15 +331,14 @@ static void gaim_gtk_sound_uninit(void) { -#ifdef USE_AO - ao_shutdown(); +#ifdef USE_GSTREAMER + gst_deinit(); #endif - sound_initialized = FALSE; gaim_signals_disconnect_by_handle(gaim_gtk_sound_get_handle()); } -#ifdef USE_AO +#ifdef USE_GSTREAMER static gboolean expire_old_child(gpointer data) { @@ -395,80 +356,47 @@ return FALSE; /* do not run again */ } -/* Uncomment the following line to enable debugging of clipping in the scaling. */ -/* #define DEBUG_CLIPPING */ - -static void -scale_pcm_data(char *data, int nframes, int bits, int channels, - double intercept, double minclip, double maxclip, - float scale) +static gboolean +bus_call (GstBus *bus, + GstMessage *msg, + gpointer data) { - int i; - float v; - gint16 *data16 = (gint16*)data; - gint32 *data32 = (gint32*)data; - gint64 *data64 = (gint64*)data; + GstElement *play = data; + GError *err; - switch(bits) { - case 16: - for(i = 0; i < nframes * channels; i++) { - v = ((data16[i] - intercept) * scale) + intercept; -#ifdef DEBUG_CLIPPING - if (v > maxclip) - printf("Clipping detected!\n"); - else if (v < minclip) - printf("Clipping detected!\n"); + switch (GST_MESSAGE_TYPE (msg)) { + case GST_MESSAGE_EOS: + gst_element_set_state(play, GST_STATE_NULL); + gst_object_unref(GST_OBJECT(play)); + break; + case GST_MESSAGE_ERROR: + gst_message_parse_error(msg, &err, NULL); + gaim_debug_error("gstreamer", err->message); + g_error_free(err); + break; + case GST_MESSAGE_WARNING: + gst_message_parse_warning(msg, &err, NULL); + gaim_debug_warning("gstreamer", err->message); + g_error_free(err); + break; + default: + break; + } + return TRUE; +} #endif - v = CLAMP(v, minclip, maxclip); - data16[i]=(gint16)v; - } - break; - case 32: - for(i = 0; i < nframes * channels; i++) { - v = ((data32[i] - intercept) * scale) + intercept; -#ifdef DEBUG_CLIPPING - if (v > maxclip) - printf("Clipping detected!\n"); - else if (v < minclip) - printf("Clipping detected!\n"); -#endif - v = CLAMP(v, minclip, maxclip); - data32[i]=(gint32)v; - } - break; - case 64: - for(i = 0; i < nframes * channels; i++) { - v = ((data64[i] - intercept) * scale) + intercept; -#ifdef DEBUG_CLIPPING - if (v > maxclip) - printf("Clipping detected!\n"); - else if (v < minclip) - printf("Clipping detected!\n"); -#endif - v = CLAMP(v, minclip, maxclip); - data64[i]=(gint64)v; - } - break; - default: - gaim_debug_warning("gtksound", "Scaling of %d bit pcm data not supported.\n", bits); - break; - } -} -#endif /* USE_AO */ static void gaim_gtk_sound_play_file(const char *filename) { const char *method; -#ifdef USE_AO - pid_t pid; - AFfilehandle file; - int volume = 50; +#ifdef USE_GSTREAMER + float volume; + char *uri; + GstElement *sink = NULL; + GstElement *play = NULL; #endif - if (!sound_initialized) - gaim_prefs_trigger_callback("/gaim/gtk/sound/method"); - if (gaim_prefs_get_bool("/gaim/gtk/sound/mute")) return; @@ -519,91 +447,37 @@ g_free(command); return; } -#ifdef USE_AO - volume = gaim_prefs_get_int("/gaim/gtk/sound/volume"); - volume = CLAMP(volume, 0, 100); - - pid = fork(); - if (pid < 0) - return; - else if (pid == 0) { - /* Child process */ - - /* calculating the scaling factor: - * scale(x) = (x+30)^2 / 6400 - * scale(0) = 0.1406 (quiet) - * scale(50) = 1.0 (no scaling, normal volume) - * scale(100) = 2.6406 (roughly maximized without clipping) - */ - float scale = ( ((float)volume + 30) * ((float)volume + 30) ) / 6400; - file = afOpenFile(filename, "rb", NULL); - if(file) { - ao_device *device; - ao_sample_format format; - int in_fmt; - int bytes_per_frame; - double slope, intercept, minclip, maxclip; - - format.rate = afGetRate(file, AF_DEFAULT_TRACK); - format.channels = afGetChannels(file, AF_DEFAULT_TRACK); - afGetSampleFormat(file, AF_DEFAULT_TRACK, &in_fmt, - &format.bits); - - afGetPCMMapping(file, AF_DEFAULT_TRACK, &slope, - &intercept, &minclip, &maxclip); - - /* XXX: libao doesn't seem to like 8-bit sounds, so we'll - * let libaudiofile make them a bit better for us */ - if(format.bits == 8) - format.bits = 16; - - afSetVirtualSampleFormat(file, AF_DEFAULT_TRACK, - AF_SAMPFMT_TWOSCOMP, format.bits); +#ifdef USE_GSTREAMER + volume = (float)(CLAMP(gaim_prefs_get_int("/gaim/gtk/sound/volume"),0,100)) / 50; + if (!strcmp(method, "automatic")) { + if (gaim_running_gnome()) { + sink = gst_element_factory_make("gconfaudiosink", "sink"); + } + } else if (!strcmp(method, "esd")) { + sink = gst_element_factory_make("esdsink", "sink"); + } else if (!strcmp(method, "arts")) { + sink = gst_element_factory_make("artssink", "sink"); + } else if (!strcmp(method, "nas")) { + sink = gst_element_factory_make("nassink", "sink"); + } -#if G_BYTE_ORDER == G_BIG_ENDIAN - format.byte_format = AO_FMT_BIG; - afSetVirtualByteOrder(file, AF_DEFAULT_TRACK, - AF_BYTEORDER_BIGENDIAN); -#elif G_BYTE_ORDER == G_LITTLE_ENDIAN - format.byte_format = AO_FMT_LITTLE; - afSetVirtualByteOrder(file, AF_DEFAULT_TRACK, - AF_BYTEORDER_LITTLEENDIAN); -#else -#warning Unknown endianness -#endif - - bytes_per_frame = format.bits * format.channels / 8; - - device = ao_open_live(ao_driver, &format, NULL); - - if(device) { - int frames_read; - char buf[4096]; - int buf_frames = sizeof(buf) / bytes_per_frame; + uri = g_strdup_printf("file://%s", filename); + play = gst_element_factory_make("playbin", "play"); + + g_object_set(G_OBJECT(play), "uri", uri, + "volume", volume, + "audio-sink", sink, NULL); - while((frames_read = afReadFrames(file, AF_DEFAULT_TRACK, - buf, buf_frames))) { - /* no need to scale at volume == 50 */ - if(volume != 50) - scale_pcm_data(buf, frames_read, format.bits, format.channels, - intercept, minclip, maxclip, scale); - if(!ao_play(device, buf, frames_read * bytes_per_frame)) - break; - } - ao_close(device); - } - afCloseFile(file); - } - ao_shutdown(); - _exit(0); - } else { - /* Parent process */ - gaim_timeout_add(PLAY_SOUND_TIMEOUT, expire_old_child, GINT_TO_POINTER(pid)); - } -#else /* USE_AO */ + gst_bus_add_watch(gst_pipeline_get_bus(GST_PIPELINE(play)), + bus_call, play); + gst_element_set_state(play, GST_STATE_PLAYING); + + g_free(uri); + +#else /* USE_GSTREAMER */ gdk_beep(); return; -#endif /* USE_AO */ +#endif /* USE_GSTREAMER */ #else /* _WIN32 */ gaim_debug_info("sound", "Playing %s\n", filename);