From 6ce4e37a4f68412d9de2e014fd1ae4ef73e3b579 Mon Sep 17 00:00:00 2001 From: Ronald Bultje Date: Sun, 5 Jun 2005 13:04:26 +0000 Subject: [PATCH] Fix mute handling, particularly for devices without hardware mute support * actions/Makefile.am: * actions/acme-volume-gstreamer.c: (acme_volume_gstreamer_set_mute), (update_state), (acme_volume_gstreamer_get_mute), (acme_volume_gstreamer_get_volume), (acme_volume_gstreamer_set_volume): Fix mute handling, particularly for devices without hardware mute support or with applications that use volume=0 for mute. Also fix the fact that we linked against all of ALSA, OSS and GStreamer if they were all available; default to GStreamer. Fixes #306036. --- gnome-settings-daemon/ChangeLog | 14 ++++ gnome-settings-daemon/actions/Makefile.am | 27 ++++--- .../actions/acme-volume-gstreamer.c | 75 +++++++++++++------ 3 files changed, 83 insertions(+), 33 deletions(-) diff --git a/gnome-settings-daemon/ChangeLog b/gnome-settings-daemon/ChangeLog index ef845574a..39b05a39d 100644 --- a/gnome-settings-daemon/ChangeLog +++ b/gnome-settings-daemon/ChangeLog @@ -1,3 +1,17 @@ +2005-06-05 Ronald S. Bultje + + * actions/Makefile.am: + * actions/acme-volume-gstreamer.c: + (acme_volume_gstreamer_set_mute), (update_state), + (acme_volume_gstreamer_get_mute), + (acme_volume_gstreamer_get_volume), + (acme_volume_gstreamer_set_volume): + Fix mute handling, particularly for devices without hardware + mute support or with applications that use volume=0 for mute. + Also fix the fact that we linked against all of ALSA, OSS and + GStreamer if they were all available; default to GStreamer. + Fixes #306036. + 2005-06-03 Anders Carlsson * Makefile.am: diff --git a/gnome-settings-daemon/actions/Makefile.am b/gnome-settings-daemon/actions/Makefile.am index 51892f52f..c882b7bb8 100644 --- a/gnome-settings-daemon/actions/Makefile.am +++ b/gnome-settings-daemon/actions/Makefile.am @@ -1,25 +1,30 @@ - INCLUDES = $(GNOME_CFLAGS) -I$(top_srcdir) $(GST_CFLAGS) noinst_LTLIBRARIES = libacme.la libacme_la_SOURCES = \ - acme-volume.c acme-volume.h \ - acme-volume-dummy.c acme-volume-dummy.h - -libacme_la_LIBADD = \ - $(GST_LIBS) $(ALSA_LIBS) + acme-volume.c acme-volume.h +libacme_la_LIBADD = +if HAVE_GSTREAMER +INCLUDES += -DHAVE_GSTREAMER +libacme_la_SOURCES += acme-volume-gstreamer.c acme-volume-gstreamer.h +libacme_la_LIBADD += $(GST_LIBS) +else # HAVE_GSTREAMER if HAVE_ALSA INCLUDES += -DHAVE_ALSA libacme_la_SOURCES += acme-volume-alsa.c acme-volume-alsa.h -endif - +libacme_la_LIBADD += $(ALSA_LIBS) +else # HAVE_ALSA if HAVE_OSS INCLUDES += -DHAVE_OSS libacme_la_SOURCES += acme-volume-oss.c acme-volume-oss.h -endif +else # HAVE_OSS +libacme_la_SOURCES += acme-volume-dummy.c acme-volume-dummy.h +endif # HAVE_OSS +endif # HAVE_ALSA +endif # HAVE_GSTREAMER if HAVE_FB INCLUDES += -DHAVE_FB @@ -29,9 +34,9 @@ endif if HAVE_GSTREAMER INCLUDES += -DHAVE_GSTREAMER libacme_la_SOURCES += acme-volume-gstreamer.c acme-volume-gstreamer.h +libacme_la_LIBADD += $(GST_LIBS) endif - Datadir = $(datadir)/control-center-2.0/interfaces/ Data_DATA = acme.glade @@ -42,8 +47,8 @@ EXTRA_DIST = \ acme-volume-alsa.c acme-volume-alsa.h \ acme-volume-gstreamer.c acme-volume-gstreamer.h \ acme-volume-oss.c acme-volume-oss.h \ + acme-volume-dummy.c acme-volume-dummy.h \ acme-fb-level.c acme-fb-level.h \ acme.h \ acme.glade \ $(pixmaps_DATA) - diff --git a/gnome-settings-daemon/actions/acme-volume-gstreamer.c b/gnome-settings-daemon/actions/acme-volume-gstreamer.c index bf7546c8b..dbe652234 100644 --- a/gnome-settings-daemon/actions/acme-volume-gstreamer.c +++ b/gnome-settings-daemon/actions/acme-volume-gstreamer.c @@ -40,6 +40,7 @@ struct AcmeVolumeGStreamerPrivate GstMixer *mixer; GstMixerTrack *track; guint timer_id; + gint state; }; static GObjectClass *parent_class = NULL; @@ -87,52 +88,78 @@ acme_volume_gstreamer_set_mute (AcmeVolume *vol, gboolean val) gst_mixer_set_mute (self->_priv->mixer, self->_priv->track, val); - + + if (val) + self->_priv->state |= 1; + else { + GstMixerTrack *track = self->_priv->track; + gint *volumes, n; + + self->_priv->state &= ~1; + volumes = g_new0 (gint, track->num_channels); + for (n = 0; n < track->num_channels; n++) + volumes[n] = (self->_priv->state >> 1) / + track->num_channels; + gst_mixer_set_volume (self->_priv->mixer, track, volumes); + g_free (volumes); + } + acme_volume_gstreamer_close (self); } +static void +update_state (AcmeVolumeGStreamer * self) +{ + gint *volumes, vol = 0, n; + GstMixerTrack *track = self->_priv->track; + + /* update mixer by getting volume */ + volumes = g_new0 (gint, track->num_channels); + gst_mixer_get_volume (self->_priv->mixer, track, volumes); + for (n = 0; n < track->num_channels; n++) + vol += volumes[n]; + g_free (volumes); + + /* update mute flag, and volume if not muted */ + if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_MUTE) || + (vol == 0 && (self->_priv->state >> 1) != 0)) + self->_priv->state |= 1; + else + self->_priv->state = vol << 1; +} + static gboolean acme_volume_gstreamer_get_mute (AcmeVolume *vol) { AcmeVolumeGStreamer *self = (AcmeVolumeGStreamer *) vol; - gboolean mute; if (acme_volume_gstreamer_open (self) == FALSE) return FALSE; - mute = GST_MIXER_TRACK_HAS_FLAG (self->_priv->track, - GST_MIXER_TRACK_MUTE); - + update_state (self); acme_volume_gstreamer_close (self); - return mute; + return (self->_priv->state & 1); } static int acme_volume_gstreamer_get_volume (AcmeVolume *vol) { - gint i, vol_total = 0, *volumes; double volume; AcmeVolumeGStreamer *self = (AcmeVolumeGStreamer *) vol; - GstMixerTrack *track; + GstMixerTrack *track = self->_priv->track; if (acme_volume_gstreamer_open (self) == FALSE) return 0; - track = self->_priv->track; + update_state (self); - 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); + /* normalize to [0,100] scale that acme wants */ + volume = (self->_priv->state >> 1) / (double) track->num_channels; + volume = 100 * (volume - track->min_volume) / + (track->max_volume - track->min_volume); acme_volume_gstreamer_close (self); - - 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; } @@ -140,8 +167,7 @@ acme_volume_gstreamer_get_volume (AcmeVolume *vol) static void acme_volume_gstreamer_set_volume (AcmeVolume *vol, int val) { - gint i, *volumes; - double volume; + gint i, *volumes, volume; AcmeVolumeGStreamer *self = (AcmeVolumeGStreamer *) vol; GstMixerTrack *track; @@ -152,7 +178,8 @@ acme_volume_gstreamer_set_volume (AcmeVolume *vol, int val) 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; + 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) @@ -160,6 +187,10 @@ acme_volume_gstreamer_set_volume (AcmeVolume *vol, int val) gst_mixer_set_volume (self->_priv->mixer, track, volumes); g_free (volumes); + /* update state */ + self->_priv->state = (self->_priv->state & 1) | + ((volume * track->num_channels) << 1); + acme_volume_gstreamer_close (self); }