From 62eada2ee0785a4f0182e13d40dd3273302024d7 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Fri, 05 Jan 2007 02:21:55 +0000 Subject: Implement audio controls --- (limited to 'lib') diff --git a/lib/src/Makefile.am b/lib/src/Makefile.am index ce4ec78..50ee2e2 100644 --- a/lib/src/Makefile.am +++ b/lib/src/Makefile.am @@ -9,7 +9,9 @@ libsugarprivate_la_CPPFLAGS = \ noinst_LTLIBRARIES = libsugarprivate.la -libsugarprivate_la_LIBADD = $(GECKO_LIBS) +libsugarprivate_la_LIBADD = $(LIB_LIBS) \ + -lgstinterfaces-0.10 \ + -lgstaudio-0.10 libsugarprivate_la_SOURCES = \ $(BUILT_SOURCES) \ diff --git a/lib/src/sugar-audio-manager.c b/lib/src/sugar-audio-manager.c index 6444f11..6f73cbc 100644 --- a/lib/src/sugar-audio-manager.c +++ b/lib/src/sugar-audio-manager.c @@ -16,23 +16,153 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ +#include +#include +#include +#include + #include "sugar-audio-manager.h" +struct _SugarAudioManagerPrivate +{ + GstMixer *mixer; + GstMixerTrack *track; + guint timer_id; +}; + G_DEFINE_TYPE(SugarAudioManager, sugar_audio_manager, G_TYPE_OBJECT) -static void -sugar_audio_manager_class_init(SugarAudioManagerClass *grabber_class) +#define SUGAR_AUDIO_MANAGER_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), SUGAR_TYPE_AUDIO_MANAGER, SugarAudioManagerPrivate)) + +/* This is a modified version of code from gnome-control-center */ + +static gboolean +mixer_close_real(SugarAudioManager *manager) +{ + if (manager->priv->mixer != NULL) + { + gst_element_set_state(GST_ELEMENT(manager->priv->mixer), GST_STATE_NULL); + gst_object_unref(GST_OBJECT(manager->priv->mixer)); + g_object_unref(G_OBJECT(manager->priv->track)); + manager->priv->mixer = NULL; + manager->priv->track = NULL; + } + + manager->priv->timer_id = 0; + + return FALSE; +} + +static gboolean +set_mixer_helper(GstMixer *mixer, gpointer user_data) +{ + const GList *tracks; + + tracks = gst_mixer_list_tracks(mixer); + + while (tracks != NULL) { + GstMixerTrack *track = GST_MIXER_TRACK(tracks->data); + + if (GST_MIXER_TRACK_HAS_FLAG(track, GST_MIXER_TRACK_MASTER)) { + SugarAudioManager *manager; + + manager = SUGAR_AUDIO_MANAGER(user_data); + + manager->priv->mixer = mixer; + manager->priv->track = track; + + /* no need to ref the mixer element */ + g_object_ref(manager->priv->track); + return TRUE; + } + + tracks = tracks->next; + } + + return FALSE; +} + +static gboolean +mixer_open(SugarAudioManager *manager) { - GObjectClass *g_object_class = G_OBJECT_CLASS (grabber_class); + GList *mixer_list; + + if (manager->priv->timer_id != 0) { + g_source_remove (manager->priv->timer_id); + manager->priv->timer_id = 0; + return TRUE; + } + + mixer_list = gst_audio_default_registry_mixer_filter + (set_mixer_helper, TRUE, manager); + + if (mixer_list == NULL) + return FALSE; + + /* do not unref the mixer as we keep the ref for manager->priv->mixer */ + g_list_free (mixer_list); + + return TRUE; } static void -sugar_audio_manager_init(SugarAudioManager *grabber) +mixer_close(SugarAudioManager *manager) { + manager->priv->timer_id = g_timeout_add (4000, (GSourceFunc)mixer_close_real, manager); } void sugar_audio_manager_set_volume (SugarAudioManager *manager, int level) { + gint i, *volumes, volume; + GstMixerTrack *track; + + if (mixer_open(manager) == FALSE) + return; + + track = manager->priv->track; + volume = CLAMP(level, 0, 100); + + /* Rescale the volume from [0, 100] to [track min, track max]. */ + volume = (volume / 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(manager->priv->mixer, track, volumes); + g_free (volumes); + + mixer_close(manager); +} + +static void +sugar_audio_manager_finalize (GObject *object) +{ + SugarAudioManager *manager = SUGAR_AUDIO_MANAGER(object); + + mixer_close_real(manager); + + G_OBJECT_CLASS(sugar_audio_manager_parent_class)->finalize(object); +} + +static void +sugar_audio_manager_class_init(SugarAudioManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + gst_init (NULL, NULL); + + object_class->finalize = sugar_audio_manager_finalize; + + g_type_class_add_private(klass, sizeof(SugarAudioManagerPrivate)); +} + +static void +sugar_audio_manager_init(SugarAudioManager *manager) +{ + manager->priv = SUGAR_AUDIO_MANAGER_GET_PRIVATE(manager); } + + diff --git a/lib/src/sugar-audio-manager.h b/lib/src/sugar-audio-manager.h index 3df8cef..ba72fa0 100644 --- a/lib/src/sugar-audio-manager.h +++ b/lib/src/sugar-audio-manager.h @@ -36,6 +36,9 @@ typedef struct _SugarAudioManagerPrivate SugarAudioManagerPrivate; struct _SugarAudioManager { GObject base_instance; + + /*< private >*/ + SugarAudioManagerPrivate *priv; }; struct _SugarAudioManagerClass { -- cgit v0.9.1