gnome-media r4097 - in trunk/gnome-volume-control: . src



Author: mccann
Date: Sun Dec 14 00:11:42 2008
New Revision: 4097
URL: http://svn.gnome.org/viewvc/gnome-media?rev=4097&view=rev

Log:
2008-12-13  William Jon McCann  <jmccann redhat com>

	* src/Makefile.am:
	* src/gvc-balance-bar.c (_scale_box_new),
	(gvc_balance_bar_set_size_group),
	(gvc_balance_bar_set_channel_map), (gvc_balance_bar_set_property),
	(gvc_balance_bar_get_property), (gvc_balance_bar_constructor),
	(gvc_balance_bar_class_init), (on_left), (on_right),
	(on_adjustment_value_changed), (gvc_balance_bar_init),
	(gvc_balance_bar_finalize), (gvc_balance_bar_new):
	* src/gvc-balance-bar.h:
	* src/gvc-channel-map.c (gvc_channel_map_class_init),
	(gvc_channel_map_gains_changed), (set_from_pa_map):
	* src/gvc-channel-map.h:
	* src/gvc-mixer-control.c (gvc_mixer_control_set_default_sink),
	(gvc_mixer_control_set_default_source),
	(update_default_source_from_name), (update_default_sink_from_name),
	(update_sink), (update_source), (update_sink_input),
	(update_event_role_stream):
	* src/gvc-mixer-dialog.c (update_output_settings),
	(on_mixer_control_default_sink_changed), (add_stream),
	(on_output_radio_toggled), (gvc_mixer_dialog_constructor):
	* src/gvc-mixer-sink-input.c (gvc_mixer_sink_input_change_volume):
	* src/gvc-mixer-sink.c (gvc_mixer_sink_change_volume):
	* src/gvc-mixer-source.c (gvc_mixer_source_change_volume):
	* src/gvc-mixer-stream.c (on_channel_map_gains_changed),
	(gvc_mixer_stream_set_channel_map):
	Add output balance control.



Added:
   trunk/gnome-volume-control/src/gvc-balance-bar.c
   trunk/gnome-volume-control/src/gvc-balance-bar.h
Modified:
   trunk/gnome-volume-control/ChangeLog
   trunk/gnome-volume-control/src/Makefile.am
   trunk/gnome-volume-control/src/gvc-channel-map.c
   trunk/gnome-volume-control/src/gvc-channel-map.h
   trunk/gnome-volume-control/src/gvc-mixer-control.c
   trunk/gnome-volume-control/src/gvc-mixer-dialog.c
   trunk/gnome-volume-control/src/gvc-mixer-sink-input.c
   trunk/gnome-volume-control/src/gvc-mixer-sink.c
   trunk/gnome-volume-control/src/gvc-mixer-source.c
   trunk/gnome-volume-control/src/gvc-mixer-stream.c

Modified: trunk/gnome-volume-control/src/Makefile.am
==============================================================================
--- trunk/gnome-volume-control/src/Makefile.am	(original)
+++ trunk/gnome-volume-control/src/Makefile.am	Sun Dec 14 00:11:42 2008
@@ -69,6 +69,8 @@
 	gvc-mixer-event-role.c			\
 	gvc-mixer-control.h			\
 	gvc-mixer-control.c			\
+	gvc-balance-bar.h			\
+	gvc-balance-bar.c			\
 	gvc-channel-bar.h			\
 	gvc-channel-bar.c			\
 	gvc-sound-theme-chooser.h		\

Added: trunk/gnome-volume-control/src/gvc-balance-bar.c
==============================================================================
--- (empty file)
+++ trunk/gnome-volume-control/src/gvc-balance-bar.c	Sun Dec 14 00:11:42 2008
@@ -0,0 +1,340 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 William Jon McCann
+ *
+ * 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 of the License, 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "gvc-balance-bar.h"
+
+#define SCALE_SIZE 128
+
+#define GVC_BALANCE_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_BALANCE_BAR, GvcBalanceBarPrivate))
+
+struct GvcBalanceBarPrivate
+{
+        GvcChannelMap *channel_map;
+        GtkWidget     *scale_box;
+        GtkWidget     *start_box;
+        GtkWidget     *end_box;
+        GtkWidget     *label;
+        GtkWidget     *scale;
+        GtkAdjustment *adjustment;
+        GtkSizeGroup  *size_group;
+        gboolean       symmetric;
+};
+
+enum
+{
+        PROP_0,
+        PROP_CHANNEL_MAP
+};
+
+static void     gvc_balance_bar_class_init (GvcBalanceBarClass *klass);
+static void     gvc_balance_bar_init       (GvcBalanceBar      *balance_bar);
+static void     gvc_balance_bar_finalize   (GObject            *object);
+
+G_DEFINE_TYPE (GvcBalanceBar, gvc_balance_bar, GTK_TYPE_HBOX)
+
+static GtkWidget *
+_scale_box_new (GvcBalanceBar *bar)
+{
+        GvcBalanceBarPrivate *priv = bar->priv;
+        GtkWidget            *box;
+        GtkWidget            *sbox;
+        GtkWidget            *ebox;
+
+        bar->priv->scale_box = box = gtk_hbox_new (FALSE, 6);
+        priv->scale = gtk_hscale_new (priv->adjustment);
+        gtk_widget_set_size_request (priv->scale, SCALE_SIZE, -1);
+
+        bar->priv->start_box = sbox = gtk_hbox_new (FALSE, 6);
+        gtk_box_pack_start (GTK_BOX (box), sbox, FALSE, FALSE, 0);
+
+        gtk_box_pack_start (GTK_BOX (sbox), priv->label, FALSE, FALSE, 0);
+
+        gtk_box_pack_start (GTK_BOX (box), priv->scale, TRUE, TRUE, 0);
+
+        bar->priv->end_box = ebox = gtk_hbox_new (FALSE, 6);
+        gtk_box_pack_start (GTK_BOX (box), ebox, FALSE, FALSE, 0);
+
+        gtk_range_set_update_policy (GTK_RANGE (priv->scale), GTK_UPDATE_DISCONTINUOUS);
+
+        if (bar->priv->size_group != NULL) {
+                gtk_size_group_add_widget (bar->priv->size_group, sbox);
+
+                if (bar->priv->symmetric) {
+                        gtk_size_group_add_widget (bar->priv->size_group, ebox);
+                }
+        }
+
+        gtk_scale_set_draw_value (GTK_SCALE (priv->scale), FALSE);
+
+        return box;
+}
+
+void
+gvc_balance_bar_set_size_group (GvcBalanceBar *bar,
+                                GtkSizeGroup  *group,
+                                gboolean       symmetric)
+{
+        g_return_if_fail (GVC_IS_BALANCE_BAR (bar));
+
+        bar->priv->size_group = group;
+        bar->priv->symmetric = symmetric;
+
+        if (bar->priv->size_group != NULL) {
+                gtk_size_group_add_widget (bar->priv->size_group,
+                                           bar->priv->start_box);
+
+                if (bar->priv->symmetric) {
+                        gtk_size_group_add_widget (bar->priv->size_group,
+                                                   bar->priv->end_box);
+                }
+        }
+        gtk_widget_queue_draw (GTK_WIDGET (bar));
+}
+
+static void
+gvc_balance_bar_set_channel_map (GvcBalanceBar *bar,
+                                 GvcChannelMap *map)
+{
+        g_return_if_fail (GVC_BALANCE_BAR (bar));
+
+        if (bar->priv->channel_map != NULL) {
+                g_object_unref (bar->priv->channel_map);
+        }
+        bar->priv->channel_map = g_object_ref (map);
+
+        g_object_notify (G_OBJECT (bar), "channel-map");
+}
+
+static void
+gvc_balance_bar_set_property (GObject       *object,
+                              guint          prop_id,
+                              const GValue  *value,
+                              GParamSpec    *pspec)
+{
+        GvcBalanceBar *self = GVC_BALANCE_BAR (object);
+
+        switch (prop_id) {
+        case PROP_CHANNEL_MAP:
+                gvc_balance_bar_set_channel_map (self, g_value_get_object (value));
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gvc_balance_bar_get_property (GObject     *object,
+                              guint        prop_id,
+                              GValue      *value,
+                              GParamSpec  *pspec)
+{
+        GvcBalanceBar *self = GVC_BALANCE_BAR (object);
+
+        switch (prop_id) {
+        case PROP_CHANNEL_MAP:
+                g_value_set_object (value, self->priv->channel_map);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static GObject *
+gvc_balance_bar_constructor (GType                  type,
+                             guint                  n_construct_properties,
+                             GObjectConstructParam *construct_params)
+{
+        GObject       *object;
+        GvcBalanceBar *self;
+
+        object = G_OBJECT_CLASS (gvc_balance_bar_parent_class)->constructor (type, n_construct_properties, construct_params);
+
+        self = GVC_BALANCE_BAR (object);
+
+        return object;
+}
+
+static void
+gvc_balance_bar_class_init (GvcBalanceBarClass *klass)
+{
+        GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+
+        object_class->constructor = gvc_balance_bar_constructor;
+        object_class->finalize = gvc_balance_bar_finalize;
+        object_class->set_property = gvc_balance_bar_set_property;
+        object_class->get_property = gvc_balance_bar_get_property;
+
+        g_object_class_install_property (object_class,
+                                         PROP_CHANNEL_MAP,
+                                         g_param_spec_object ("channel-map",
+                                                              "channel map",
+                                                              "The channel map",
+                                                              GVC_TYPE_CHANNEL_MAP,
+                                                              G_PARAM_READWRITE));
+
+        g_type_class_add_private (klass, sizeof (GvcBalanceBarPrivate));
+}
+
+
+static gboolean
+on_left (pa_channel_position_t p)
+{
+    return
+        p == PA_CHANNEL_POSITION_FRONT_LEFT ||
+        p == PA_CHANNEL_POSITION_REAR_LEFT ||
+        p == PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER ||
+        p == PA_CHANNEL_POSITION_SIDE_LEFT ||
+        p == PA_CHANNEL_POSITION_TOP_FRONT_LEFT ||
+        p == PA_CHANNEL_POSITION_TOP_REAR_LEFT;
+}
+
+static gboolean
+on_right (pa_channel_position_t p)
+{
+    return
+        p == PA_CHANNEL_POSITION_FRONT_RIGHT ||
+        p == PA_CHANNEL_POSITION_REAR_RIGHT ||
+        p == PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER ||
+        p == PA_CHANNEL_POSITION_SIDE_RIGHT ||
+        p == PA_CHANNEL_POSITION_TOP_FRONT_RIGHT ||
+        p == PA_CHANNEL_POSITION_TOP_REAR_RIGHT;
+}
+
+static void
+on_adjustment_value_changed (GtkAdjustment *adjustment,
+                             GvcBalanceBar *bar)
+{
+        gdouble                val;
+        gdouble               *gains;
+        pa_channel_position_t *positions;
+        guint                  num_channels;
+        guint                  i;
+        gdouble                left_v;
+        gdouble                center_v;
+        gdouble                right_v;
+
+        val = gtk_adjustment_get_value (adjustment);
+
+        if (bar->priv->channel_map == NULL) {
+                return;
+        }
+
+        left_v = 1.0;
+        right_v = 1.0;
+
+        /* FIXME: handle RTOL locales */
+        if (val > 0) {
+                left_v = 1.0 - val;
+        } else if (val < 0) {
+                right_v = 1.0 - ABS(val);
+        }
+        center_v = (left_v + right_v) / 2.0;
+
+        num_channels = gvc_channel_map_get_num_channels (bar->priv->channel_map);
+        positions = gvc_channel_map_get_positions (bar->priv->channel_map);
+        gains = gvc_channel_map_get_gains (bar->priv->channel_map);
+
+        for (i = 0; i < num_channels; i++) {
+                if (on_left (positions[i])) {
+                        gains[i] = left_v;
+                } else if (on_right (positions[i])) {
+                        gains[i] = right_v;
+                } else {
+                        gains[i] = center_v;
+                }
+        }
+
+        gvc_channel_map_gains_changed (bar->priv->channel_map);
+}
+
+static void
+gvc_balance_bar_init (GvcBalanceBar *bar)
+{
+        GtkWidget *frame;
+
+        bar->priv = GVC_BALANCE_BAR_GET_PRIVATE (bar);
+
+        bar->priv->adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0,
+                                                                    -1.0,
+                                                                    1.0,
+                                                                    0.05,
+                                                                    0.1,
+                                                                    0.1));
+        g_object_ref_sink (bar->priv->adjustment);
+        g_signal_connect (bar->priv->adjustment,
+                          "value-changed",
+                          G_CALLBACK (on_adjustment_value_changed),
+                          bar);
+
+        bar->priv->label = gtk_label_new (_("Balance:"));
+        gtk_misc_set_alignment (GTK_MISC (bar->priv->label),
+                                0.0,
+                                0.5);
+        /* frame */
+        frame = gtk_frame_new (NULL);
+        gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
+        gtk_container_add (GTK_CONTAINER (bar), frame);
+
+        /* box with scale */
+        bar->priv->scale_box = _scale_box_new (bar);
+        gtk_container_add (GTK_CONTAINER (frame), bar->priv->scale_box);
+        gtk_widget_show_all (frame);
+}
+
+static void
+gvc_balance_bar_finalize (GObject *object)
+{
+        GvcBalanceBar *balance_bar;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GVC_IS_BALANCE_BAR (object));
+
+        balance_bar = GVC_BALANCE_BAR (object);
+
+        g_return_if_fail (balance_bar->priv != NULL);
+
+        if (balance_bar->priv->channel_map != NULL) {
+                g_object_unref (balance_bar->priv->channel_map);
+        }
+
+        G_OBJECT_CLASS (gvc_balance_bar_parent_class)->finalize (object);
+}
+
+GtkWidget *
+gvc_balance_bar_new (GvcChannelMap *channel_map)
+{
+        GObject *bar;
+        bar = g_object_new (GVC_TYPE_BALANCE_BAR,
+                            "channel-map", channel_map,
+                            NULL);
+        return GTK_WIDGET (bar);
+}

Added: trunk/gnome-volume-control/src/gvc-balance-bar.h
==============================================================================
--- (empty file)
+++ trunk/gnome-volume-control/src/gvc-balance-bar.h	Sun Dec 14 00:11:42 2008
@@ -0,0 +1,60 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * 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 of the License, 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __GVC_BALANCE_BAR_H
+#define __GVC_BALANCE_BAR_H
+
+#include <glib-object.h>
+
+#include "gvc-channel-map.h"
+
+G_BEGIN_DECLS
+
+#define GVC_TYPE_BALANCE_BAR         (gvc_balance_bar_get_type ())
+#define GVC_BALANCE_BAR(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_BALANCE_BAR, GvcBalanceBar))
+#define GVC_BALANCE_BAR_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_BALANCE_BAR, GvcBalanceBarClass))
+#define GVC_IS_BALANCE_BAR(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_BALANCE_BAR))
+#define GVC_IS_BALANCE_BAR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_BALANCE_BAR))
+#define GVC_BALANCE_BAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_BALANCE_BAR, GvcBalanceBarClass))
+
+typedef struct GvcBalanceBarPrivate GvcBalanceBarPrivate;
+
+typedef struct
+{
+        GtkHBox               parent;
+        GvcBalanceBarPrivate *priv;
+} GvcBalanceBar;
+
+typedef struct
+{
+        GtkHBoxClass          parent_class;
+} GvcBalanceBarClass;
+
+GType               gvc_balance_bar_get_type            (void);
+
+GtkWidget *         gvc_balance_bar_new                 (GvcChannelMap *map);
+
+void                gvc_balance_bar_set_size_group      (GvcBalanceBar *bar,
+                                                         GtkSizeGroup  *group,
+                                                         gboolean       symmetric);
+
+G_END_DECLS
+
+#endif /* __GVC_BALANCE_BAR_H */

Modified: trunk/gnome-volume-control/src/gvc-channel-map.c
==============================================================================
--- trunk/gnome-volume-control/src/gvc-channel-map.c	(original)
+++ trunk/gnome-volume-control/src/gvc-channel-map.c	Sun Dec 14 00:11:42 2008
@@ -40,6 +40,13 @@
         gdouble               gains[PA_CHANNELS_MAX];
 };
 
+enum {
+        GAINS_CHANGED,
+        LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0, };
+
 static void     gvc_channel_map_class_init (GvcChannelMapClass *klass);
 static void     gvc_channel_map_init       (GvcChannelMap      *channel_map);
 static void     gvc_channel_map_finalize   (GObject            *object);
@@ -74,9 +81,25 @@
 
         gobject_class->finalize = gvc_channel_map_finalize;
 
+        signals [GAINS_CHANGED] =
+                g_signal_new ("gains-changed",
+                              G_TYPE_FROM_CLASS (klass),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (GvcChannelMapClass, gains_changed),
+                              NULL, NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE, 0);
+
         g_type_class_add_private (klass, sizeof (GvcChannelMapPrivate));
 }
 
+void
+gvc_channel_map_gains_changed (GvcChannelMap *map)
+{
+        g_return_if_fail (GVC_IS_CHANNEL_MAP (map));
+        g_signal_emit (map, signals[GAINS_CHANGED], 0);
+}
+
 static void
 gvc_channel_map_init (GvcChannelMap *map)
 {
@@ -112,6 +135,7 @@
 {
         guint i;
 
+        map->priv->num_channels = pa_map->channels;
         for (i = 0; i < pa_map->channels; i++) {
                 map->priv->positions[i] = pa_map->map[i];
                 map->priv->gains[i] = 1.0;

Modified: trunk/gnome-volume-control/src/gvc-channel-map.h
==============================================================================
--- trunk/gnome-volume-control/src/gvc-channel-map.h	(original)
+++ trunk/gnome-volume-control/src/gvc-channel-map.h	Sun Dec 14 00:11:42 2008
@@ -44,6 +44,7 @@
 typedef struct
 {
         GObjectClass           parent_class;
+        void (*gains_changed) (GvcChannelMap *channel_map);
 } GvcChannelMapClass;
 
 GType                   gvc_channel_map_get_type                (void);
@@ -54,6 +55,8 @@
 pa_channel_position_t * gvc_channel_map_get_positions           (GvcChannelMap  *map);
 gdouble *               gvc_channel_map_get_gains               (GvcChannelMap  *map);
 
+void                    gvc_channel_map_gains_changed           (GvcChannelMap  *map);
+
 G_END_DECLS
 
 #endif /* __GVC_CHANNEL_MAP_H */

Modified: trunk/gnome-volume-control/src/gvc-mixer-control.c
==============================================================================
--- trunk/gnome-volume-control/src/gvc-mixer-control.c	(original)
+++ trunk/gnome-volume-control/src/gvc-mixer-control.c	Sun Dec 14 00:11:42 2008
@@ -113,9 +113,6 @@
         g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), FALSE);
         g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
 
-        g_debug ("Setting default sink to '%s'",
-                 gvc_mixer_stream_get_name (stream));
-
         o = pa_context_set_default_sink (control->priv->pa_context,
                                          gvc_mixer_stream_get_name (stream),
                                          NULL,
@@ -139,9 +136,6 @@
         g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), FALSE);
         g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
 
-        g_debug ("Setting default source to '%s'",
-                 gvc_mixer_stream_get_name (stream));
-
         o = pa_context_set_default_source (control->priv->pa_context,
                                            gvc_mixer_stream_get_name (stream),
                                            NULL,
@@ -401,7 +395,6 @@
 {
         gboolean changed;
 
-        g_debug ("Default source: %s", name);
         if ((control->priv->default_source_name == NULL
              && name != NULL)
             || (control->priv->default_source_name != NULL
@@ -427,7 +420,6 @@
 {
         gboolean changed;
 
-        g_debug ("Default sink: %s", name);
         if ((control->priv->default_sink_name == NULL
              && name != NULL)
             || (control->priv->default_sink_name != NULL
@@ -502,7 +494,7 @@
 {
         GvcMixerStream *stream;
         gboolean        is_new;
-        pa_volume_t     avg_volume;
+        pa_volume_t     max_volume;
         char            map_buff[PA_CHANNEL_MAP_SNPRINT_MAX];
 
         pa_channel_map_snprint (map_buff, PA_CHANNEL_MAP_SNPRINT_MAX, &info->channel_map);
@@ -532,17 +524,16 @@
                 is_new = TRUE;
         }
 
-        avg_volume = pa_cvolume_avg (&info->volume);
-
+        max_volume = pa_cvolume_max (&info->volume);
         gvc_mixer_stream_set_name (stream, info->name);
         gvc_mixer_stream_set_description (stream, info->description);
         gvc_mixer_stream_set_icon_name (stream, "audio-card");
-        gvc_mixer_stream_set_volume (stream, (guint)avg_volume);
+        gvc_mixer_stream_set_volume (stream, (guint)max_volume);
         gvc_mixer_stream_set_is_muted (stream, info->mute);
         gvc_mixer_stream_set_can_decibel (stream, !!(info->flags & PA_SINK_DECIBEL_VOLUME));
         if (!!(info->flags & PA_SINK_DECIBEL_VOLUME)) {
                 gdouble db;
-                db = pa_sw_volume_to_dB (avg_volume);
+                db = pa_sw_volume_to_dB (max_volume);
                 gvc_mixer_stream_set_decibel (stream, db);
         }
 
@@ -566,7 +557,7 @@
 {
         GvcMixerStream *stream;
         gboolean        is_new;
-        pa_volume_t     avg_volume;
+        pa_volume_t     max_volume;
 
 #if 1
         g_debug ("Updating source: index=%u name='%s' description='%s'",
@@ -594,17 +585,17 @@
                 is_new = TRUE;
         }
 
-        avg_volume = pa_cvolume_avg (&info->volume);
+        max_volume = pa_cvolume_max (&info->volume);
 
         gvc_mixer_stream_set_name (stream, info->name);
         gvc_mixer_stream_set_description (stream, info->description);
         gvc_mixer_stream_set_icon_name (stream, "audio-input-microphone");
-        gvc_mixer_stream_set_volume (stream, (guint)avg_volume);
+        gvc_mixer_stream_set_volume (stream, (guint)max_volume);
         gvc_mixer_stream_set_is_muted (stream, info->mute);
         gvc_mixer_stream_set_can_decibel (stream, !!(info->flags & PA_SOURCE_DECIBEL_VOLUME));
         if (!!(info->flags & PA_SINK_DECIBEL_VOLUME)) {
                 gdouble db;
-                db = pa_sw_volume_to_dB (avg_volume);
+                db = pa_sw_volume_to_dB (max_volume);
                 gvc_mixer_stream_set_decibel (stream, db);
         }
 
@@ -676,7 +667,7 @@
 {
         GvcMixerStream *stream;
         gboolean        is_new;
-        pa_volume_t     avg_volume;
+        pa_volume_t     max_volume;
         const char     *name;
 
 #if 0
@@ -701,7 +692,7 @@
                 is_new = TRUE;
         }
 
-        avg_volume = pa_cvolume_avg (&info->volume);
+        max_volume = pa_cvolume_max (&info->volume);
 
         name = (const char *)g_hash_table_lookup (control->priv->clients,
                                                   GUINT_TO_POINTER (info->client));
@@ -709,7 +700,7 @@
         gvc_mixer_stream_set_description (stream, info->name);
 
         set_icon_name_from_proplist (stream, info->proplist, "applications-multimedia");
-        gvc_mixer_stream_set_volume (stream, (guint)avg_volume);
+        gvc_mixer_stream_set_volume (stream, (guint)max_volume);
         gvc_mixer_stream_set_is_muted (stream, info->mute);
 
         if (is_new) {
@@ -932,7 +923,7 @@
 {
         GvcMixerStream *stream;
         gboolean        is_new;
-        pa_volume_t     avg_volume;
+        pa_volume_t     max_volume;
 
         if (strcmp (info->name, "sink-input-by-media-role:event") != 0) {
                 return;
@@ -958,11 +949,11 @@
                                               GUINT_TO_POINTER (control->priv->event_sink_input_id));
         }
 
-        avg_volume = pa_cvolume_avg (&info->volume);
+        max_volume = pa_cvolume_max (&info->volume);
 
         gvc_mixer_stream_set_name (stream, _("System Sounds"));
         gvc_mixer_stream_set_icon_name (stream, "multimedia-volume-control");
-        gvc_mixer_stream_set_volume (stream, (guint)avg_volume);
+        gvc_mixer_stream_set_volume (stream, (guint)max_volume);
         gvc_mixer_stream_set_is_muted (stream, info->mute);
 
         if (is_new) {

Modified: trunk/gnome-volume-control/src/gvc-mixer-dialog.c
==============================================================================
--- trunk/gnome-volume-control/src/gvc-mixer-dialog.c	(original)
+++ trunk/gnome-volume-control/src/gvc-mixer-dialog.c	Sun Dec 14 00:11:42 2008
@@ -31,6 +31,7 @@
 #include <gconf/gconf-client.h>
 
 #include "gvc-channel-bar.h"
+#include "gvc-balance-bar.h"
 #include "gvc-mixer-control.h"
 #include "gvc-mixer-sink.h"
 #include "gvc-mixer-source.h"
@@ -59,6 +60,8 @@
         GtkWidget       *applications_box;
         GtkWidget       *no_apps_label;
         GtkWidget       *output_treeview;
+        GtkWidget       *output_settings_box;
+        GtkWidget       *output_balance_bar;
         GtkWidget       *input_treeview;
         GtkWidget       *sound_theme_chooser;
         GtkWidget       *click_feedback_button;
@@ -132,6 +135,43 @@
 }
 
 static void
+update_output_settings (GvcMixerDialog *dialog)
+{
+        GvcMixerStream *stream;
+        GvcChannelMap  *map;
+
+        g_debug ("Updating output settings");
+        if (dialog->priv->output_balance_bar != NULL) {
+                gtk_container_remove (GTK_CONTAINER (dialog->priv->output_settings_box),
+                                      dialog->priv->output_balance_bar);
+                dialog->priv->output_balance_bar = NULL;
+        }
+
+        stream = gvc_mixer_control_get_default_sink (dialog->priv->mixer_control);
+        if (stream == NULL) {
+                g_warning ("Default sink stream not found");
+                return;
+        }
+
+        map = gvc_mixer_stream_get_channel_map (stream);
+        if (map == NULL) {
+                g_warning ("Default sink stream has no channel map");
+                return;
+        }
+
+        dialog->priv->output_balance_bar = gvc_balance_bar_new (map);
+        if (dialog->priv->size_group != NULL) {
+                gvc_balance_bar_set_size_group (GVC_BALANCE_BAR (dialog->priv->output_balance_bar),
+                                                dialog->priv->size_group,
+                                                TRUE);
+        }
+        gtk_box_pack_start (GTK_BOX (dialog->priv->output_settings_box),
+                            dialog->priv->output_balance_bar,
+                            FALSE, FALSE, 12);
+        gtk_widget_show (dialog->priv->output_balance_bar);
+}
+
+static void
 update_default_output (GvcMixerDialog *dialog)
 {
         GtkTreeModel *model;
@@ -181,6 +221,8 @@
                                                      id);
         bar_set_stream (dialog, dialog->priv->output_bar, stream);
 
+        update_output_settings (dialog);
+
         update_default_output (dialog);
 }
 
@@ -612,6 +654,8 @@
                 is_default = TRUE;
                 gtk_widget_set_sensitive (dialog->priv->applications_box,
                                           !is_muted);
+
+                update_output_settings (dialog);
         } else if (stream == gvc_mixer_control_get_default_source (dialog->priv->mixer_control)) {
                 bar = dialog->priv->input_bar;
                 is_default = TRUE;
@@ -860,7 +904,7 @@
         if (toggled) {
                 GvcMixerStream *stream;
 
-                g_debug ("Default input selected: %u", id);
+                g_debug ("Default output selected: %u", id);
                 stream = gvc_mixer_control_lookup_stream_id (dialog->priv->mixer_control, id);
                 if (stream == NULL) {
                         g_warning ("Unable to find stream for id: %u", id);
@@ -1101,6 +1145,14 @@
         selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->output_treeview));
         gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
 
+        box = gtk_frame_new (_("Settings for the selected device:"));
+        label = gtk_frame_get_label_widget (GTK_FRAME (box));
+        _gtk_label_make_bold (GTK_LABEL (label));
+        gtk_frame_set_shadow_type (GTK_FRAME (box), GTK_SHADOW_NONE);
+        gtk_box_pack_start (GTK_BOX (self->priv->output_box), box, TRUE, TRUE, 12);
+        self->priv->output_settings_box = gtk_vbox_new (FALSE, 12);
+        gtk_container_add (GTK_CONTAINER (box), self->priv->output_settings_box);
+
         /* Applications */
         self->priv->applications_box = gtk_vbox_new (FALSE, 12);
         gtk_container_set_border_width (GTK_CONTAINER (self->priv->applications_box), 12);

Modified: trunk/gnome-volume-control/src/gvc-mixer-sink-input.c
==============================================================================
--- trunk/gnome-volume-control/src/gvc-mixer-sink-input.c	(original)
+++ trunk/gnome-volume-control/src/gvc-mixer-sink-input.c	Sun Dec 14 00:11:42 2008
@@ -69,7 +69,7 @@
         /* apply channel gain mapping */
         for (i = 0; i < num_channels; i++) {
                 pa_volume_t v;
-                v = (double) v * gains[i];
+                v = (double) volume * gains[i];
                 cv.values[i] = v;
         }
 

Modified: trunk/gnome-volume-control/src/gvc-mixer-sink.c
==============================================================================
--- trunk/gnome-volume-control/src/gvc-mixer-sink.c	(original)
+++ trunk/gnome-volume-control/src/gvc-mixer-sink.c	Sun Dec 14 00:11:42 2008
@@ -64,13 +64,16 @@
         num_channels = gvc_channel_map_get_num_channels (map);
         gains = gvc_channel_map_get_gains (map);
 
+        g_debug ("Changing volume for sink: n=%d vol=%u", num_channels, (guint)volume);
+
         /* set all values to nominal level */
         pa_cvolume_set (&cv, num_channels, (pa_volume_t)volume);
 
         /* apply channel gain mapping */
         for (i = 0; i < num_channels; i++) {
                 pa_volume_t v;
-                v = (double) v * gains[i];
+                v = (double) volume * gains[i];
+                g_debug ("Channel %d v=%u", i, v);
                 cv.values[i] = v;
         }
 

Modified: trunk/gnome-volume-control/src/gvc-mixer-source.c
==============================================================================
--- trunk/gnome-volume-control/src/gvc-mixer-source.c	(original)
+++ trunk/gnome-volume-control/src/gvc-mixer-source.c	Sun Dec 14 00:11:42 2008
@@ -70,7 +70,7 @@
         /* apply channel gain mapping */
         for (i = 0; i < num_channels; i++) {
                 pa_volume_t v;
-                v = (double) v * gains[i];
+                v = (double) volume * gains[i];
                 cv.values[i] = v;
         }
 

Modified: trunk/gnome-volume-control/src/gvc-mixer-stream.c
==============================================================================
--- trunk/gnome-volume-control/src/gvc-mixer-stream.c	(original)
+++ trunk/gnome-volume-control/src/gvc-mixer-stream.c	Sun Dec 14 00:11:42 2008
@@ -238,6 +238,14 @@
         return TRUE;
 }
 
+static void
+on_channel_map_gains_changed (GvcChannelMap  *channel_map,
+                              GvcMixerStream *stream)
+{
+        g_debug ("Gains changed");
+        gvc_mixer_stream_change_volume (stream, stream->priv->volume);
+}
+
 static gboolean
 gvc_mixer_stream_set_channel_map (GvcMixerStream *stream,
                                   GvcChannelMap  *channel_map)
@@ -249,12 +257,22 @@
         }
 
         if (stream->priv->channel_map != NULL) {
+                g_signal_handlers_disconnect_by_func (stream->priv->channel_map,
+                                                      on_channel_map_gains_changed,
+                                                      stream);
                 g_object_unref (stream->priv->channel_map);
         }
 
         stream->priv->channel_map = channel_map;
 
-        g_object_notify (G_OBJECT (stream), "channel-map");
+        if (stream->priv->channel_map != NULL) {
+                g_signal_connect (stream->priv->channel_map,
+                                  "gains-changed",
+                                  G_CALLBACK (on_channel_map_gains_changed),
+                                  stream);
+
+                g_object_notify (G_OBJECT (stream), "channel-map");
+        }
 
         return TRUE;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]