check for GStreamer, make it possible to disable ALSA support even if the
2004-02-25 Bastien Nocera <hadess@hadess.net> * configure.in: check for GStreamer, make it possible to disable ALSA support even if the libraries are there 2004-02-25 Bastien Nocera <hadess@hadess.net> * actions/Makefile.am: * actions/acme-volume-gstreamer.[ch]: * actions/acme-volume.c: (acme_volume_class_init), (acme_volume_new): add GStreamer mixer support
This commit is contained in:
parent
3fbbd4ad1e
commit
b87b234730
7 changed files with 406 additions and 6 deletions
|
@ -1,3 +1,8 @@
|
|||
2004-02-25 Bastien Nocera <hadess@hadess.net>
|
||||
|
||||
* configure.in: check for GStreamer, make it possible to disable
|
||||
ALSA support even if the libraries are there
|
||||
|
||||
2004-02-21 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* configure.in: Added "en_CA" to ALL_LINGUAS.
|
||||
|
|
53
configure.in
53
configure.in
|
@ -272,7 +272,7 @@ fi
|
|||
AM_GCONF_SOURCE_2
|
||||
|
||||
dnl ==============================================
|
||||
dnl OSS and FB Level section
|
||||
dnl OSS section
|
||||
dnl ==============================================
|
||||
have_oss=no
|
||||
AC_TRY_COMPILE([
|
||||
|
@ -290,14 +290,59 @@ AC_MSG_CHECKING(for OSS audio support)
|
|||
AC_MSG_RESULT($have_oss)
|
||||
AM_CONDITIONAL(HAVE_OSS, test x"$have_oss" = "xyes")
|
||||
|
||||
dnl ==============================================
|
||||
dnl ALSA section
|
||||
dnl ==============================================
|
||||
have_alsa=no
|
||||
PKG_CHECK_MODULES(ALSA, alsa >= 0.9.0,
|
||||
have_alsa=yes,
|
||||
AC_MSG_RESULT(*** All of ALSA dependent parts will be disabled ***))
|
||||
AC_ARG_ENABLE(alsa,
|
||||
AC_HELP_STRING([--disable-alsa],[Turn off support for ALSA version 0.9 or higher]),
|
||||
[case "${enableval}" in
|
||||
yes) WANT_ALSA=yes ;;
|
||||
no) WANT_ALSA=no ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-alsa) ;;
|
||||
esac],
|
||||
[WANT_ALSA=yes]) dnl Default value
|
||||
|
||||
if test x$WANT_ALSA = xyes ; then
|
||||
PKG_CHECK_MODULES(ALSA, alsa >= 0.9.0,
|
||||
have_alsa=yes,
|
||||
AC_MSG_RESULT(*** All of ALSA dependent parts will be disabled ***))
|
||||
else
|
||||
have_alsa=no
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(HAVE_ALSA, test x"$have_alsa" = "xyes")
|
||||
AC_SUBST(ALSA_LIBS)
|
||||
AC_SUBST(ALSA_CFLAGS)
|
||||
|
||||
dnl ==============================================
|
||||
dnl GStreamer section
|
||||
dnl ==============================================
|
||||
AC_ARG_ENABLE(gstreamer,
|
||||
AC_HELP_STRING([--enable-gstreamer],[use gstreamer, if available]),
|
||||
[case "${enableval}" in
|
||||
yes) ENABLE_GSTREAMER=yes ;;
|
||||
no) ENABLE_GSTREAMER=no ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-gstreamer) ;;
|
||||
esac],
|
||||
[ENABLE_GSTREAMER=yes]) dnl Default value
|
||||
|
||||
if test "x$ENABLE_GSTREAMER" = "xyes"; then
|
||||
have_gstreamer=no
|
||||
PKG_CHECK_MODULES(GST, gstreamer-interfaces-0.7 >= 0.7.3.1,
|
||||
have_gstreamer=yes,
|
||||
AC_MSG_RESULT(*** All of GStreamer dependent parts will be disabled ***))
|
||||
else
|
||||
have_gstreamer=disabled
|
||||
AC_MSG_RESULT(*** GStreamer has been explicitly disabled ***)
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_GSTREAMER, test x"$have_gstreamer" = "xyes")
|
||||
AC_SUBST(GST_LIBS)
|
||||
AC_SUBST(GST_CFLAGS)
|
||||
|
||||
dnl ==============================================
|
||||
dnl FB Level section
|
||||
dnl ==============================================
|
||||
have_fb=no
|
||||
AC_TRY_COMPILE([
|
||||
#include <linux/fb.h>
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2004-02-25 Bastien Nocera <hadess@hadess.net>
|
||||
|
||||
* actions/Makefile.am:
|
||||
* actions/acme-volume-gstreamer.[ch]:
|
||||
* actions/acme-volume.c: (acme_volume_class_init),
|
||||
(acme_volume_new): add GStreamer mixer support
|
||||
|
||||
2004-02-24 Mariano Suárez-Alvarez <mariano@gnome.org>
|
||||
|
||||
* gnome-settings-accessibility-keyboard.c
|
||||
|
|
|
@ -16,15 +16,21 @@ FB_CFLAGS = -DHAVE_FB
|
|||
FB_files = acme-fb-level.c acme-fb-level.h
|
||||
endif
|
||||
|
||||
INCLUDES = $(GNOME_CFLAGS) -I$(top_srcdir) $(ALSA_CFLAGS) $(OSS_CFLAGS) $(FB_CFLAGS)
|
||||
if HAVE_GSTREAMER
|
||||
HAVE_GST_CFLAGS = -DHAVE_GSTREAMER
|
||||
GST_files = acme-volume-gstreamer.c acme-volume-gstreamer.h
|
||||
endif
|
||||
|
||||
INCLUDES = $(GNOME_CFLAGS) -I$(top_srcdir) $(ALSA_CFLAGS) $(OSS_CFLAGS) $(FB_CFLAGS) $(HAVE_GST_CFLAGS) $(GST_CFLAGS)
|
||||
|
||||
libacme_la_SOURCES = \
|
||||
$(FB_files) $(OSS_files) $(ALSA_files) \
|
||||
$(GST_files) \
|
||||
acme-volume.c acme-volume.h \
|
||||
acme-volume-dummy.c acme-volume-dummy.h
|
||||
|
||||
libacme_la_LIBADD = \
|
||||
$(ALSA_LIBS)
|
||||
$(ALSA_LIBS) $(GST_LIBS)
|
||||
|
||||
Datadir = $(datadir)/control-center-2.0/interfaces/
|
||||
Data_DATA = acme.glade
|
||||
|
|
279
gnome-settings-daemon/actions/acme-volume-gstreamer.c
Normal file
279
gnome-settings-daemon/actions/acme-volume-gstreamer.c
Normal file
|
@ -0,0 +1,279 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
|
||||
/* acme-volume-gstreamer.c
|
||||
|
||||
Copyright (C) 2002, 2003 Bastien Nocera
|
||||
Copyright (C) 2004 Novell, Inc.
|
||||
|
||||
The Gnome Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The Gnome Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the Gnome Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
Author: Bastien Nocera <hadess@hadess.net>
|
||||
Jon Trowbridge <trow@ximian.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "acme-volume-gstreamer.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/mixer/mixer.h>
|
||||
#include <gst/propertyprobe/propertyprobe.h>
|
||||
|
||||
struct AcmeVolumeGStreamerPrivate
|
||||
{
|
||||
GstMixer *mixer;
|
||||
GstMixerTrack *track;
|
||||
};
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
static int acme_volume_gstreamer_get_volume (AcmeVolume *self);
|
||||
static void acme_volume_gstreamer_set_volume (AcmeVolume *self, int val);
|
||||
|
||||
static void
|
||||
acme_volume_gstreamer_finalize (GObject *object)
|
||||
{
|
||||
AcmeVolumeGStreamer *self;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (ACME_IS_VOLUME_GSTREAMER (object));
|
||||
|
||||
self = ACME_VOLUME_GSTREAMER (object);
|
||||
|
||||
g_return_if_fail (self->_priv != NULL);
|
||||
|
||||
if (self->_priv->mixer != NULL) {
|
||||
g_object_unref (self->_priv->mixer);
|
||||
g_object_unref (self->_priv->track);
|
||||
}
|
||||
|
||||
g_free (self->_priv);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
acme_volume_gstreamer_set_mute (AcmeVolume *vol, gboolean val)
|
||||
{
|
||||
AcmeVolumeGStreamer *self = (AcmeVolumeGStreamer *) vol;
|
||||
|
||||
if (self->_priv->mixer == NULL)
|
||||
return;
|
||||
|
||||
gst_mixer_set_mute (self->_priv->mixer,
|
||||
self->_priv->track,
|
||||
val);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
acme_volume_gstreamer_get_mute (AcmeVolume *vol)
|
||||
{
|
||||
AcmeVolumeGStreamer *self = (AcmeVolumeGStreamer *) vol;
|
||||
|
||||
if (self->_priv->mixer == NULL)
|
||||
return FALSE;
|
||||
|
||||
return GST_MIXER_TRACK_HAS_FLAG (self->_priv->track,
|
||||
GST_MIXER_TRACK_MUTE);
|
||||
}
|
||||
|
||||
static int
|
||||
acme_volume_gstreamer_get_volume (AcmeVolume *vol)
|
||||
{
|
||||
gint i, vol_total = 0, *volumes;
|
||||
double volume;
|
||||
AcmeVolumeGStreamer *self = (AcmeVolumeGStreamer *) vol;
|
||||
GstMixerTrack *track;
|
||||
|
||||
if (self->_priv->mixer == NULL)
|
||||
return 0;
|
||||
|
||||
track = self->_priv->track;
|
||||
|
||||
volumes = g_new0 (gint, track->num_channels);
|
||||
gst_mixer_get_volume (self->_priv->mixer, track, volumes);
|
||||
for (i = 0; i < track->num_channels; ++i)
|
||||
vol_total += volumes[i];
|
||||
g_free (volumes);
|
||||
|
||||
volume = vol_total / (double)track->num_channels;
|
||||
|
||||
/* Normalize the volume to the [0, 100] scale that acme expects. */
|
||||
volume = 100 * (volume - track->min_volume) / (track->max_volume - track->min_volume);
|
||||
|
||||
return (gint) volume;
|
||||
}
|
||||
|
||||
static void
|
||||
acme_volume_gstreamer_set_volume (AcmeVolume *vol, int val)
|
||||
{
|
||||
gint i, *volumes;
|
||||
double volume;
|
||||
AcmeVolumeGStreamer *self = (AcmeVolumeGStreamer *) vol;
|
||||
GstMixerTrack *track = self->_priv->track;
|
||||
|
||||
if (self->_priv->mixer == NULL)
|
||||
return;
|
||||
|
||||
val = CLAMP (val, 0, 100);
|
||||
|
||||
/* Rescale the volume from [0, 100] to [track min, track max]. */
|
||||
volume = (val / 100.0) * (track->max_volume - track->min_volume) + track->min_volume;
|
||||
|
||||
volumes = g_new (gint, track->num_channels);
|
||||
for (i = 0; i < track->num_channels; ++i)
|
||||
volumes[i] = (gint) volume;
|
||||
gst_mixer_set_volume (self->_priv->mixer, track, volumes);
|
||||
g_free (volumes);
|
||||
}
|
||||
|
||||
/* This is a modified version of code from gnome-media's gst-mixer */
|
||||
static void
|
||||
acme_volume_gstreamer_init (AcmeVolume *vol)
|
||||
{
|
||||
AcmeVolumeGStreamer *self = (AcmeVolumeGStreamer *) vol;
|
||||
const GList *elements;
|
||||
gint num = 0, channel_count = 0;
|
||||
|
||||
self->_priv = g_new0 (AcmeVolumeGStreamerPrivate, 1);
|
||||
|
||||
/* Go through all elements of a certain class and check whether
|
||||
* they implement a mixer. If so, walk through the tracks and look
|
||||
* for first one named "volume".
|
||||
*
|
||||
* We should probably do something intelligent if we don't find an
|
||||
* appropriate mixer/track. But now we do something stupid... everything
|
||||
* just becomes a no-op.
|
||||
*/
|
||||
elements = gst_registry_pool_feature_list (GST_TYPE_ELEMENT_FACTORY);
|
||||
for ( ; elements != NULL && self->_priv->mixer == NULL; elements = elements->next) {
|
||||
GstElementFactory *factory = GST_ELEMENT_FACTORY (elements->data);
|
||||
gchar *title = NULL;
|
||||
const gchar *klass;
|
||||
GstElement *element = NULL;
|
||||
const GParamSpec *devspec;
|
||||
GstPropertyProbe *probe;
|
||||
GValueArray *array = NULL;
|
||||
gint n;
|
||||
const GList *tracks;
|
||||
|
||||
/* check category */
|
||||
klass = gst_element_factory_get_klass (factory);
|
||||
if (strcmp (klass, "Generic/Audio"))
|
||||
goto next;
|
||||
|
||||
/* create element */
|
||||
title = g_strdup_printf ("gst-mixer-%d", num);
|
||||
element = gst_element_factory_create (factory, title);
|
||||
if (!element)
|
||||
goto next;
|
||||
|
||||
if (!GST_IS_PROPERTY_PROBE (element))
|
||||
goto next;
|
||||
|
||||
probe = GST_PROPERTY_PROBE (element);
|
||||
devspec = gst_property_probe_get_property (probe, "device");
|
||||
if (devspec == NULL)
|
||||
goto next;
|
||||
array = gst_property_probe_probe_and_get_values (probe, devspec);
|
||||
if (array == NULL)
|
||||
goto next;
|
||||
|
||||
/* set all devices and test for mixer */
|
||||
for (n = 0; n < array->n_values; n++) {
|
||||
GValue *device = g_value_array_get_nth (array, n);
|
||||
|
||||
/* set this device */
|
||||
g_object_set_property (G_OBJECT (element), "device", device);
|
||||
if (gst_element_set_state (element,
|
||||
GST_STATE_READY) == GST_STATE_FAILURE)
|
||||
continue;
|
||||
|
||||
/* Is this device a mixer? If so, add it to the list. */
|
||||
if (!GST_IS_MIXER (element)) {
|
||||
gst_element_set_state (element, GST_STATE_NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
tracks = gst_mixer_list_tracks (GST_MIXER (element));
|
||||
for (; tracks != NULL; tracks = tracks->next) {
|
||||
GstMixerTrack *track = tracks->data;
|
||||
|
||||
if (! g_strcasecmp (track->label, "volume")) {
|
||||
self->_priv->mixer = GST_MIXER (element);
|
||||
self->_priv->track = track;
|
||||
|
||||
g_object_ref (self->_priv->mixer);
|
||||
g_object_ref (self->_priv->track);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
num++;
|
||||
|
||||
/* and recreate this object, since we give it to the mixer */
|
||||
title = g_strdup_printf ("gst-mixer-%d", num);
|
||||
element = gst_element_factory_create (factory, title);
|
||||
}
|
||||
|
||||
next:
|
||||
if (element)
|
||||
gst_object_unref (GST_OBJECT (element));
|
||||
if (array)
|
||||
g_value_array_free (array);
|
||||
g_free (title);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
acme_volume_gstreamer_class_init (AcmeVolumeGStreamerClass *klass)
|
||||
{
|
||||
AcmeVolumeClass *volume_class = ACME_VOLUME_CLASS (klass);
|
||||
G_OBJECT_CLASS (klass)->finalize = acme_volume_gstreamer_finalize;
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
volume_class->set_volume = acme_volume_gstreamer_set_volume;
|
||||
volume_class->get_volume = acme_volume_gstreamer_get_volume;
|
||||
volume_class->set_mute = acme_volume_gstreamer_set_mute;
|
||||
volume_class->get_mute = acme_volume_gstreamer_get_mute;
|
||||
}
|
||||
|
||||
GType acme_volume_gstreamer_get_type (void)
|
||||
{
|
||||
static GType object_type = 0;
|
||||
|
||||
if (!object_type)
|
||||
{
|
||||
static const GTypeInfo object_info =
|
||||
{
|
||||
sizeof (AcmeVolumeGStreamerClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) acme_volume_gstreamer_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (AcmeVolumeGStreamer),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) acme_volume_gstreamer_init
|
||||
};
|
||||
|
||||
object_type = g_type_register_static (ACME_TYPE_VOLUME,
|
||||
"AcmeVolumeGStreamer", &object_info, 0);
|
||||
}
|
||||
|
||||
return object_type;
|
||||
}
|
49
gnome-settings-daemon/actions/acme-volume-gstreamer.h
Normal file
49
gnome-settings-daemon/actions/acme-volume-gstreamer.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* acme-volume-gstreamer.h
|
||||
|
||||
Copyright (C) 2002, 2003 Bastien Nocera
|
||||
Copyright (C) 2004 Novell, Inc.
|
||||
|
||||
The Gnome Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The Gnome Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the Gnome Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
Author: Bastien Nocera <hadess@hadess.net>
|
||||
Jon Trowbridge <trow@ximian.com>
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include "acme-volume.h"
|
||||
|
||||
#define ACME_TYPE_VOLUME_GSTREAMER (acme_volume_get_type ())
|
||||
#define ACME_VOLUME_GSTREAMER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ACME_TYPE_VOLUME_GSTREAMER, AcmeVolumeGStreamer))
|
||||
#define ACME_VOLUME_GSTREAMER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ACME_TYPE_VOLUME_GSTREAMER, AcmeVolumeGStreamerClass))
|
||||
#define ACME_IS_VOLUME_GSTREAMER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ACME_TYPE_VOLUME_GSTREAMER))
|
||||
#define ACME_VOLUME_GSTREAMER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ACME_TYPE_VOLUME_GSTREAMER, AcmeVolumeGStreamerClass))
|
||||
|
||||
typedef struct AcmeVolumeGStreamer AcmeVolumeGStreamer;
|
||||
typedef struct AcmeVolumeGStreamerClass AcmeVolumeGStreamerClass;
|
||||
typedef struct AcmeVolumeGStreamerPrivate AcmeVolumeGStreamerPrivate;
|
||||
|
||||
struct AcmeVolumeGStreamer {
|
||||
AcmeVolume parent;
|
||||
AcmeVolumeGStreamerPrivate *_priv;
|
||||
};
|
||||
|
||||
struct AcmeVolumeGStreamerClass {
|
||||
AcmeVolumeClass parent;
|
||||
};
|
||||
|
||||
GType acme_volume_gstreamer_get_type (void);
|
||||
|
|
@ -28,6 +28,9 @@
|
|||
#ifdef HAVE_ALSA
|
||||
#include "acme-volume-alsa.h"
|
||||
#endif
|
||||
#ifdef HAVE_GSTREAMER
|
||||
#include "acme-volume-gstreamer.h"
|
||||
#endif
|
||||
#include "acme-volume-dummy.h"
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
@ -35,6 +38,8 @@ static GObjectClass *parent_class = NULL;
|
|||
static void
|
||||
acme_volume_class_init (AcmeVolumeClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
};
|
||||
|
||||
|
@ -117,6 +122,10 @@ AcmeVolume *acme_volume_new (void)
|
|||
{
|
||||
AcmeVolume *vol;
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
vol = ACME_VOLUME (g_object_new (acme_volume_gstreamer_get_type (), NULL));
|
||||
return vol;
|
||||
#endif
|
||||
#ifdef HAVE_ALSA
|
||||
vol = ACME_VOLUME (g_object_new (acme_volume_alsa_get_type (), NULL));
|
||||
if (vol != NULL && ACME_VOLUME_ALSA (vol)->_priv != NULL)
|
||||
|
|
Loading…
Add table
Reference in a new issue