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



Author: mccann
Date: Sat Dec 13 21:07:50 2008
New Revision: 4095
URL: http://svn.gnome.org/viewvc/gnome-media?rev=4095&view=rev

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

	* src/Makefile.am:
	* src/gvc-channel-map.c (gvc_channel_map_get_num_channels),
	(gvc_channel_map_get_gains), (gvc_channel_map_get_positions),
	(gvc_channel_map_class_init), (gvc_channel_map_init),
	(gvc_channel_map_finalize), (gvc_channel_map_new),
	(set_from_pa_map), (gvc_channel_map_new_from_pa_channel_map):
	* src/gvc-channel-map.h:
	* src/gvc-mixer-control.c (update_sink), (update_source),
	(update_sink_input), (update_source_output):
	* src/gvc-mixer-event-role.c (update_settings),
	(gvc_mixer_event_role_new):
	* src/gvc-mixer-sink-input.c (gvc_mixer_sink_input_change_volume),
	(gvc_mixer_sink_input_new):
	* src/gvc-mixer-sink-input.h:
	* src/gvc-mixer-sink.c (gvc_mixer_sink_change_volume),
	(gvc_mixer_sink_new):
	* src/gvc-mixer-sink.h:
	* src/gvc-mixer-source-output.c (gvc_mixer_source_output_new):
	* src/gvc-mixer-source-output.h:
	* src/gvc-mixer-source.c (gvc_mixer_source_change_volume),
	(gvc_mixer_source_new):
	* src/gvc-mixer-source.h:
	* src/gvc-mixer-stream.c (gvc_mixer_stream_get_channel_map),
	(gvc_mixer_stream_set_channel_map),
	(gvc_mixer_stream_set_property), (gvc_mixer_stream_get_property),
	(gvc_mixer_stream_class_init):
	* src/gvc-mixer-stream.h:
	Add a ChannelMap class that we can use to manipulate channel
	volume levels.



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

Modified: trunk/gnome-volume-control/src/Makefile.am
==============================================================================
--- trunk/gnome-volume-control/src/Makefile.am	(original)
+++ trunk/gnome-volume-control/src/Makefile.am	Sat Dec 13 21:07:50 2008
@@ -24,6 +24,8 @@
 gnome_volume_control_applet_SOURCES =		\
 	gvc-mixer-stream.h			\
 	gvc-mixer-stream.c			\
+	gvc-channel-map.h			\
+	gvc-channel-map.c			\
 	gvc-mixer-sink.h			\
 	gvc-mixer-sink.c			\
 	gvc-mixer-source.h			\
@@ -53,6 +55,8 @@
 gnome_volume_control_SOURCES =			\
 	gvc-mixer-stream.h			\
 	gvc-mixer-stream.c			\
+	gvc-channel-map.h			\
+	gvc-channel-map.c			\
 	gvc-mixer-sink.h			\
 	gvc-mixer-sink.c			\
 	gvc-mixer-source.h			\

Added: trunk/gnome-volume-control/src/gvc-channel-map.c
==============================================================================
--- (empty file)
+++ trunk/gnome-volume-control/src/gvc-channel-map.c	Sat Dec 13 21:07:50 2008
@@ -0,0 +1,130 @@
+/* -*- 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 <pulse/pulseaudio.h>
+
+#include "gvc-channel-map.h"
+
+#define GVC_CHANNEL_MAP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_CHANNEL_MAP, GvcChannelMapPrivate))
+
+struct GvcChannelMapPrivate
+{
+        guint                 num_channels;
+        pa_channel_position_t positions[PA_CHANNELS_MAX];
+        gdouble               gains[PA_CHANNELS_MAX];
+};
+
+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);
+
+G_DEFINE_TYPE (GvcChannelMap, gvc_channel_map, G_TYPE_OBJECT)
+
+guint
+gvc_channel_map_get_num_channels (GvcChannelMap *map)
+{
+        g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), 0);
+        return map->priv->num_channels;
+}
+
+gdouble *
+gvc_channel_map_get_gains (GvcChannelMap *map)
+{
+        g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), NULL);
+        return map->priv->gains;
+}
+
+pa_channel_position_t *
+gvc_channel_map_get_positions (GvcChannelMap *map)
+{
+        g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), NULL);
+        return map->priv->positions;
+}
+
+static void
+gvc_channel_map_class_init (GvcChannelMapClass *klass)
+{
+        GObjectClass   *gobject_class = G_OBJECT_CLASS (klass);
+
+        gobject_class->finalize = gvc_channel_map_finalize;
+
+        g_type_class_add_private (klass, sizeof (GvcChannelMapPrivate));
+}
+
+static void
+gvc_channel_map_init (GvcChannelMap *map)
+{
+        map->priv = GVC_CHANNEL_MAP_GET_PRIVATE (map);
+}
+
+static void
+gvc_channel_map_finalize (GObject *object)
+{
+        GvcChannelMap *channel_map;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GVC_IS_CHANNEL_MAP (object));
+
+        channel_map = GVC_CHANNEL_MAP (object);
+
+        g_return_if_fail (channel_map->priv != NULL);
+
+        G_OBJECT_CLASS (gvc_channel_map_parent_class)->finalize (object);
+}
+
+GvcChannelMap *
+gvc_channel_map_new (void)
+{
+        GObject *map;
+        map = g_object_new (GVC_TYPE_CHANNEL_MAP, NULL);
+        return GVC_CHANNEL_MAP (map);
+}
+
+static void
+set_from_pa_map (GvcChannelMap        *map,
+                 const pa_channel_map *pa_map)
+{
+        guint i;
+
+        for (i = 0; i < pa_map->channels; i++) {
+                map->priv->positions[i] = pa_map->map[i];
+                map->priv->gains[i] = 1.0;
+        }
+}
+
+GvcChannelMap *
+gvc_channel_map_new_from_pa_channel_map (const pa_channel_map *pa_map)
+{
+        GObject *map;
+        map = g_object_new (GVC_TYPE_CHANNEL_MAP, NULL);
+
+        set_from_pa_map (GVC_CHANNEL_MAP (map), pa_map);
+
+        return GVC_CHANNEL_MAP (map);
+}

Added: trunk/gnome-volume-control/src/gvc-channel-map.h
==============================================================================
--- (empty file)
+++ trunk/gnome-volume-control/src/gvc-channel-map.h	Sat Dec 13 21:07:50 2008
@@ -0,0 +1,59 @@
+/* -*- 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_CHANNEL_MAP_H
+#define __GVC_CHANNEL_MAP_H
+
+#include <glib-object.h>
+#include <pulse/pulseaudio.h>
+
+G_BEGIN_DECLS
+
+#define GVC_TYPE_CHANNEL_MAP         (gvc_channel_map_get_type ())
+#define GVC_CHANNEL_MAP(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_CHANNEL_MAP, GvcChannelMap))
+#define GVC_CHANNEL_MAP_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_CHANNEL_MAP, GvcChannelMapClass))
+#define GVC_IS_CHANNEL_MAP(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_CHANNEL_MAP))
+#define GVC_IS_CHANNEL_MAP_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_CHANNEL_MAP))
+#define GVC_CHANNEL_MAP_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_CHANNEL_MAP, GvcChannelMapClass))
+
+typedef struct GvcChannelMapPrivate GvcChannelMapPrivate;
+
+typedef struct
+{
+        GObject               parent;
+        GvcChannelMapPrivate *priv;
+} GvcChannelMap;
+
+typedef struct
+{
+        GObjectClass           parent_class;
+} GvcChannelMapClass;
+
+GType                   gvc_channel_map_get_type                (void);
+
+GvcChannelMap *         gvc_channel_map_new                     (void);
+GvcChannelMap *         gvc_channel_map_new_from_pa_channel_map (const pa_channel_map *map);
+guint                   gvc_channel_map_get_num_channels        (GvcChannelMap  *map);
+pa_channel_position_t * gvc_channel_map_get_positions           (GvcChannelMap  *map);
+gdouble *               gvc_channel_map_get_gains               (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	Sat Dec 13 21:07:50 2008
@@ -503,12 +503,15 @@
         GvcMixerStream *stream;
         gboolean        is_new;
         pa_volume_t     avg_volume;
+        char            map_buff[PA_CHANNEL_MAP_SNPRINT_MAX];
 
-#if 0
-        g_debug ("Updating sink: index=%u name='%s' description='%s'",
+        pa_channel_map_snprint (map_buff, PA_CHANNEL_MAP_SNPRINT_MAX, &info->channel_map);
+#if 1
+        g_debug ("Updating sink: index=%u name='%s' description='%s' map='%s'",
                  info->index,
                  info->name,
-                 info->description);
+                 info->description,
+                 map_buff);
 #endif
 
         /* for now completely ignore virtual streams */
@@ -520,9 +523,12 @@
         stream = g_hash_table_lookup (control->priv->sinks,
                                       GUINT_TO_POINTER (info->index));
         if (stream == NULL) {
+                GvcChannelMap *map;
+                map = gvc_channel_map_new_from_pa_channel_map (&info->channel_map);
                 stream = gvc_mixer_sink_new (control->priv->pa_context,
                                              info->index,
-                                             info->channel_map.channels);
+                                             map);
+                g_object_unref (map);
                 is_new = TRUE;
         }
 
@@ -579,9 +585,12 @@
         stream = g_hash_table_lookup (control->priv->sources,
                                       GUINT_TO_POINTER (info->index));
         if (stream == NULL) {
+                GvcChannelMap *map;
+                map = gvc_channel_map_new_from_pa_channel_map (&info->channel_map);
                 stream = gvc_mixer_source_new (control->priv->pa_context,
                                                info->index,
-                                               info->channel_map.channels);
+                                               map);
+                g_object_unref (map);
                 is_new = TRUE;
         }
 
@@ -683,9 +692,12 @@
         stream = g_hash_table_lookup (control->priv->sink_inputs,
                                       GUINT_TO_POINTER (info->index));
         if (stream == NULL) {
+                GvcChannelMap *map;
+                map = gvc_channel_map_new_from_pa_channel_map (&info->channel_map);
                 stream = gvc_mixer_sink_input_new (control->priv->pa_context,
                                                    info->index,
-                                                   info->channel_map.channels);
+                                                   map);
+                g_object_unref (map);
                 is_new = TRUE;
         }
 
@@ -728,9 +740,12 @@
         stream = g_hash_table_lookup (control->priv->source_outputs,
                                       GUINT_TO_POINTER (info->index));
         if (stream == NULL) {
+                GvcChannelMap *map;
+                map = gvc_channel_map_new_from_pa_channel_map (&info->channel_map);
                 stream = gvc_mixer_source_output_new (control->priv->pa_context,
                                                       info->index,
-                                                      info->channel_map.channels);
+                                                      map);
+                g_object_unref (map);
                 is_new = TRUE;
         }
 

Modified: trunk/gnome-volume-control/src/gvc-mixer-event-role.c
==============================================================================
--- trunk/gnome-volume-control/src/gvc-mixer-event-role.c	(original)
+++ trunk/gnome-volume-control/src/gvc-mixer-event-role.c	Sat Dec 13 21:07:50 2008
@@ -58,14 +58,12 @@
 {
         pa_operation              *o;
         guint                      index;
-        guint                      num_channels;
         pa_context                *context;
         pa_ext_stream_restore_info info;
 
         index = gvc_mixer_stream_get_index (GVC_MIXER_STREAM (role));
-        num_channels = gvc_mixer_stream_get_num_channels (GVC_MIXER_STREAM (role));
 
-        pa_cvolume_set (&info.volume, num_channels, (pa_volume_t)volume);
+        pa_cvolume_set (&info.volume, 1, (pa_volume_t)volume);
 
         info.name = "sink-input-by-media-role:event";
         info.channel_map.channels = 1;
@@ -233,7 +231,6 @@
         object = g_object_new (GVC_TYPE_MIXER_EVENT_ROLE,
                                "pa-context", context,
                                "index", 0,
-                               "num-channels", 1,
                                "device", device,
                                NULL);
 

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	Sat Dec 13 21:07:50 2008
@@ -50,15 +50,29 @@
 {
         pa_operation      *o;
         guint              index;
-        guint              num_channels;
+        GvcChannelMap     *map;
         pa_context        *context;
         pa_cvolume         cv;
+        guint              i;
+        guint              num_channels;
+        gdouble           *gains;
 
         index = gvc_mixer_stream_get_index (stream);
-        num_channels = gvc_mixer_stream_get_num_channels (stream);
 
+        map = gvc_mixer_stream_get_channel_map (stream);
+        num_channels = gvc_channel_map_get_num_channels (map);
+        gains = gvc_channel_map_get_gains (map);
+
+        /* 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];
+                cv.values[i] = v;
+        }
+
         context = gvc_mixer_stream_get_pa_context (stream);
 
         o = pa_context_set_sink_input_volume (context,
@@ -156,16 +170,16 @@
 }
 
 GvcMixerStream *
-gvc_mixer_sink_input_new (pa_context *context,
-                          guint       index,
-                          guint       num_channels)
+gvc_mixer_sink_input_new (pa_context    *context,
+                          guint          index,
+                          GvcChannelMap *channel_map)
 {
         GObject *object;
 
         object = g_object_new (GVC_TYPE_MIXER_SINK_INPUT,
                                "pa-context", context,
                                "index", index,
-                               "num-channels", num_channels,
+                               "channel-map", channel_map,
                                NULL);
 
         return GVC_MIXER_STREAM (object);

Modified: trunk/gnome-volume-control/src/gvc-mixer-sink-input.h
==============================================================================
--- trunk/gnome-volume-control/src/gvc-mixer-sink-input.h	(original)
+++ trunk/gnome-volume-control/src/gvc-mixer-sink-input.h	Sat Dec 13 21:07:50 2008
@@ -48,9 +48,9 @@
 
 GType               gvc_mixer_sink_input_get_type      (void);
 
-GvcMixerStream *    gvc_mixer_sink_input_new           (pa_context *context,
-                                                        guint       index,
-                                                        guint       num_channels);
+GvcMixerStream *    gvc_mixer_sink_input_new           (pa_context    *context,
+                                                        guint          index,
+                                                        GvcChannelMap *map);
 
 G_END_DECLS
 

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	Sat Dec 13 21:07:50 2008
@@ -48,17 +48,32 @@
 gvc_mixer_sink_change_volume (GvcMixerStream *stream,
                               guint           volume)
 {
-        pa_operation *o;
-        guint         index;
-        guint         num_channels;
-        pa_context   *context;
-        pa_cvolume    cv;
+        pa_operation      *o;
+        guint              index;
+        GvcChannelMap     *map;
+        pa_context        *context;
+        pa_cvolume         cv;
+        guint              i;
+        guint              num_channels;
+        gdouble           *gains;
 
         index = gvc_mixer_stream_get_index (stream);
-        num_channels = gvc_mixer_stream_get_num_channels (stream);
 
+
+        map = gvc_mixer_stream_get_channel_map (stream);
+        num_channels = gvc_channel_map_get_num_channels (map);
+        gains = gvc_channel_map_get_gains (map);
+
+        /* 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];
+                cv.values[i] = v;
+        }
+
         context = gvc_mixer_stream_get_pa_context (stream);
 
         o = pa_context_set_sink_volume_by_index (context,
@@ -156,16 +171,17 @@
 }
 
 GvcMixerStream *
-gvc_mixer_sink_new (pa_context *context,
-                    guint       index,
-                    guint       num_channels)
+gvc_mixer_sink_new (pa_context    *context,
+                    guint          index,
+                    GvcChannelMap *channel_map)
+
 {
         GObject *object;
 
         object = g_object_new (GVC_TYPE_MIXER_SINK,
                                "pa-context", context,
                                "index", index,
-                               "num-channels", num_channels,
+                               "channel-map", channel_map,
                                NULL);
 
         return GVC_MIXER_STREAM (object);

Modified: trunk/gnome-volume-control/src/gvc-mixer-sink.h
==============================================================================
--- trunk/gnome-volume-control/src/gvc-mixer-sink.h	(original)
+++ trunk/gnome-volume-control/src/gvc-mixer-sink.h	Sat Dec 13 21:07:50 2008
@@ -48,9 +48,9 @@
 
 GType               gvc_mixer_sink_get_type            (void);
 
-GvcMixerStream *    gvc_mixer_sink_new                 (pa_context *context,
-                                                        guint       index,
-                                                        guint       num_channels);
+GvcMixerStream *    gvc_mixer_sink_new                 (pa_context    *context,
+                                                        guint          index,
+                                                        GvcChannelMap *map);
 
 G_END_DECLS
 

Modified: trunk/gnome-volume-control/src/gvc-mixer-source-output.c
==============================================================================
--- trunk/gnome-volume-control/src/gvc-mixer-source-output.c	(original)
+++ trunk/gnome-volume-control/src/gvc-mixer-source-output.c	Sat Dec 13 21:07:50 2008
@@ -112,16 +112,16 @@
 }
 
 GvcMixerStream *
-gvc_mixer_source_output_new (pa_context *context,
-                             guint       index,
-                             guint       num_channels)
+gvc_mixer_source_output_new (pa_context    *context,
+                             guint          index,
+                             GvcChannelMap *channel_map)
 {
         GObject *object;
 
         object = g_object_new (GVC_TYPE_MIXER_SOURCE_OUTPUT,
                                "pa-context", context,
                                "index", index,
-                               "num-channels", num_channels,
+                               "channel-map", channel_map,
                                NULL);
 
         return GVC_MIXER_STREAM (object);

Modified: trunk/gnome-volume-control/src/gvc-mixer-source-output.h
==============================================================================
--- trunk/gnome-volume-control/src/gvc-mixer-source-output.h	(original)
+++ trunk/gnome-volume-control/src/gvc-mixer-source-output.h	Sat Dec 13 21:07:50 2008
@@ -48,9 +48,9 @@
 
 GType               gvc_mixer_source_output_get_type      (void);
 
-GvcMixerStream *    gvc_mixer_source_output_new           (pa_context *context,
-                                                           guint       index,
-                                                           guint       num_channels);
+GvcMixerStream *    gvc_mixer_source_output_new           (pa_context    *context,
+                                                           guint          index,
+                                                           GvcChannelMap *map);
 
 G_END_DECLS
 

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	Sat Dec 13 21:07:50 2008
@@ -48,17 +48,32 @@
 gvc_mixer_source_change_volume (GvcMixerStream *stream,
                               guint           volume)
 {
-        pa_operation *o;
-        guint         index;
-        guint         num_channels;
-        pa_context   *context;
-        pa_cvolume    cv;
+        pa_operation      *o;
+        guint              index;
+        GvcChannelMap     *map;
+        pa_context        *context;
+        pa_cvolume         cv;
+        guint              num_channels;
+        guint              i;
+        gdouble           *gains;
 
         index = gvc_mixer_stream_get_index (stream);
-        num_channels = gvc_mixer_stream_get_num_channels (stream);
 
+        map = gvc_mixer_stream_get_channel_map (stream);
+        num_channels = gvc_channel_map_get_num_channels (map);
+        gains = gvc_channel_map_get_gains (map);
+
+        /* 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];
+                cv.values[i] = v;
+        }
+
         context = gvc_mixer_stream_get_pa_context (stream);
 
         o = pa_context_set_source_volume_by_index (context,
@@ -156,16 +171,17 @@
 }
 
 GvcMixerStream *
-gvc_mixer_source_new (pa_context *context,
-                    guint       index,
-                    guint       num_channels)
+gvc_mixer_source_new (pa_context    *context,
+                      guint          index,
+                      GvcChannelMap *channel_map)
+
 {
         GObject *object;
 
         object = g_object_new (GVC_TYPE_MIXER_SOURCE,
                                "pa-context", context,
                                "index", index,
-                               "num-channels", num_channels,
+                               "channel-map", channel_map,
                                NULL);
 
         return GVC_MIXER_STREAM (object);

Modified: trunk/gnome-volume-control/src/gvc-mixer-source.h
==============================================================================
--- trunk/gnome-volume-control/src/gvc-mixer-source.h	(original)
+++ trunk/gnome-volume-control/src/gvc-mixer-source.h	Sat Dec 13 21:07:50 2008
@@ -48,9 +48,9 @@
 
 GType               gvc_mixer_source_get_type            (void);
 
-GvcMixerStream *    gvc_mixer_source_new               (pa_context *context,
-                                                        guint       index,
-                                                        guint       num_channels);
+GvcMixerStream *    gvc_mixer_source_new               (pa_context    *context,
+                                                        guint          index,
+                                                        GvcChannelMap *map);
 
 G_END_DECLS
 

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	Sat Dec 13 21:07:50 2008
@@ -40,7 +40,7 @@
         pa_context    *pa_context;
         guint          id;
         guint          index;
-        guint          num_channels;
+        GvcChannelMap *channel_map;
         guint          volume;
         gdouble        decibel;
         char          *name;
@@ -55,7 +55,7 @@
         PROP_0,
         PROP_ID,
         PROP_PA_CONTEXT,
-        PROP_NUM_CHANNELS,
+        PROP_CHANNEL_MAP,
         PROP_INDEX,
         PROP_NAME,
         PROP_DESCRIPTION,
@@ -107,11 +107,11 @@
         return stream->priv->id;
 }
 
-guint
-gvc_mixer_stream_get_num_channels (GvcMixerStream *stream)
+GvcChannelMap *
+gvc_mixer_stream_get_channel_map (GvcMixerStream *stream)
 {
-        g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), 0);
-        return stream->priv->num_channels;
+        g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), NULL);
+        return stream->priv->channel_map;
 }
 
 guint
@@ -238,6 +238,27 @@
         return TRUE;
 }
 
+static gboolean
+gvc_mixer_stream_set_channel_map (GvcMixerStream *stream,
+                                  GvcChannelMap  *channel_map)
+{
+        g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
+
+        if (channel_map != NULL) {
+                g_object_ref (channel_map);
+        }
+
+        if (stream->priv->channel_map != NULL) {
+                g_object_unref (stream->priv->channel_map);
+        }
+
+        stream->priv->channel_map = channel_map;
+
+        g_object_notify (G_OBJECT (stream), "channel-map");
+
+        return TRUE;
+}
+
 const char *
 gvc_mixer_stream_get_icon_name (GvcMixerStream *stream)
 {
@@ -276,8 +297,8 @@
         case PROP_ID:
                 self->priv->id = g_value_get_ulong (value);
                 break;
-        case PROP_NUM_CHANNELS:
-                self->priv->num_channels = g_value_get_ulong (value);
+        case PROP_CHANNEL_MAP:
+                gvc_mixer_stream_set_channel_map (self, g_value_get_object (value));
                 break;
         case PROP_NAME:
                 gvc_mixer_stream_set_name (self, g_value_get_string (value));
@@ -324,8 +345,8 @@
         case PROP_ID:
                 g_value_set_ulong (value, self->priv->id);
                 break;
-        case PROP_NUM_CHANNELS:
-                g_value_set_ulong (value, self->priv->num_channels);
+        case PROP_CHANNEL_MAP:
+                g_value_set_object (value, self->priv->channel_map);
                 break;
         case PROP_NAME:
                 g_value_set_string (value, self->priv->name);
@@ -433,12 +454,12 @@
                                                              0, G_MAXULONG, 0,
                                                              G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
         g_object_class_install_property (gobject_class,
-                                         PROP_NUM_CHANNELS,
-                                         g_param_spec_ulong ("num-channels",
-                                                             "num channels",
-                                                             "The number of channels for this stream",
-                                                             0, G_MAXULONG, 0,
-                                                             G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+                                         PROP_CHANNEL_MAP,
+                                         g_param_spec_object ("channel-map",
+                                                              "channel map",
+                                                              "The channel map for this stream",
+                                                              GVC_TYPE_CHANNEL_MAP,
+                                                              G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
         g_object_class_install_property (gobject_class,
                                          PROP_PA_CONTEXT,
                                          g_param_spec_pointer ("pa-context",

Modified: trunk/gnome-volume-control/src/gvc-mixer-stream.h
==============================================================================
--- trunk/gnome-volume-control/src/gvc-mixer-stream.h	(original)
+++ trunk/gnome-volume-control/src/gvc-mixer-stream.h	Sat Dec 13 21:07:50 2008
@@ -24,6 +24,8 @@
 #include <glib-object.h>
 #include <pulse/pulseaudio.h>
 
+#include "gvc-channel-map.h"
+
 G_BEGIN_DECLS
 
 #define GVC_TYPE_MIXER_STREAM         (gvc_mixer_stream_get_type ())
@@ -57,7 +59,7 @@
 pa_context *        gvc_mixer_stream_get_pa_context  (GvcMixerStream *stream);
 guint               gvc_mixer_stream_get_index       (GvcMixerStream *stream);
 guint               gvc_mixer_stream_get_id          (GvcMixerStream *stream);
-guint               gvc_mixer_stream_get_num_channels (GvcMixerStream *stream);
+GvcChannelMap *     gvc_mixer_stream_get_channel_map (GvcMixerStream *stream);
 
 guint               gvc_mixer_stream_get_volume      (GvcMixerStream *stream);
 gdouble             gvc_mixer_stream_get_decibel     (GvcMixerStream *stream);



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