1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* Copyright (C) 2008 William Jon McCann
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28
#include <glib/gi18n-lib.h>
30
#include <pulse/pulseaudio.h>
32
#include "gvc-channel-map.h"
33
#include "gvc-channel-map-private.h"
35
#define GVC_CHANNEL_MAP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_CHANNEL_MAP, GvcChannelMapPrivate))
37
struct GvcChannelMapPrivate
39
pa_channel_map pa_map;
40
gboolean pa_volume_is_set;
42
gdouble extern_volume[NUM_TYPES]; /* volume, balance, fade, lfe */
52
static guint signals [LAST_SIGNAL] = { 0, };
54
static void gvc_channel_map_class_init (GvcChannelMapClass *klass);
55
static void gvc_channel_map_init (GvcChannelMap *channel_map);
56
static void gvc_channel_map_finalize (GObject *object);
58
G_DEFINE_TYPE (GvcChannelMap, gvc_channel_map, G_TYPE_OBJECT)
61
gvc_channel_map_get_num_channels (const GvcChannelMap *map)
63
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), 0);
65
if (!pa_channel_map_valid(&map->priv->pa_map))
68
return map->priv->pa_map.channels;
72
gvc_channel_map_get_volume (GvcChannelMap *map)
74
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), NULL);
76
if (!pa_channel_map_valid(&map->priv->pa_map))
79
map->priv->extern_volume[VOLUME] = (gdouble) pa_cvolume_max (&map->priv->pa_volume);
80
if (gvc_channel_map_can_balance (map))
81
map->priv->extern_volume[BALANCE] = (gdouble) pa_cvolume_get_balance (&map->priv->pa_volume, &map->priv->pa_map);
83
map->priv->extern_volume[BALANCE] = 0;
84
if (gvc_channel_map_can_fade (map))
85
map->priv->extern_volume[FADE] = (gdouble) pa_cvolume_get_fade (&map->priv->pa_volume, &map->priv->pa_map);
87
map->priv->extern_volume[FADE] = 0;
88
if (gvc_channel_map_has_lfe (map))
89
map->priv->extern_volume[LFE] = (gdouble) pa_cvolume_get_position (&map->priv->pa_volume, &map->priv->pa_map, PA_CHANNEL_POSITION_LFE);
91
map->priv->extern_volume[LFE] = 0;
93
return map->priv->extern_volume;
97
gvc_channel_map_can_balance (const GvcChannelMap *map)
99
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), FALSE);
101
return map->priv->can_balance;
105
gvc_channel_map_can_fade (const GvcChannelMap *map)
107
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), FALSE);
109
return map->priv->can_fade;
113
gvc_channel_map_get_mapping (const GvcChannelMap *map)
115
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), NULL);
117
if (!pa_channel_map_valid(&map->priv->pa_map))
120
return pa_channel_map_to_pretty_name (&map->priv->pa_map);
124
* gvc_channel_map_has_position: (skip)
132
gvc_channel_map_has_position (const GvcChannelMap *map,
133
pa_channel_position_t position)
135
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), FALSE);
137
return pa_channel_map_has_position (&(map->priv->pa_map), position);
140
const pa_channel_map *
141
gvc_channel_map_get_pa_channel_map (const GvcChannelMap *map)
143
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), NULL);
145
if (!pa_channel_map_valid(&map->priv->pa_map))
148
return &map->priv->pa_map;
152
gvc_channel_map_get_cvolume (const GvcChannelMap *map)
154
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), NULL);
156
if (!pa_channel_map_valid(&map->priv->pa_map))
159
return &map->priv->pa_volume;
163
gvc_channel_map_class_init (GvcChannelMapClass *klass)
165
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
167
gobject_class->finalize = gvc_channel_map_finalize;
169
signals [VOLUME_CHANGED] =
170
g_signal_new ("volume-changed",
171
G_TYPE_FROM_CLASS (klass),
173
G_STRUCT_OFFSET (GvcChannelMapClass, volume_changed),
175
g_cclosure_marshal_VOID__BOOLEAN,
176
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
178
g_type_class_add_private (klass, sizeof (GvcChannelMapPrivate));
182
gvc_channel_map_volume_changed (GvcChannelMap *map,
183
const pa_cvolume *cv,
186
g_return_if_fail (GVC_IS_CHANNEL_MAP (map));
187
g_return_if_fail (cv != NULL);
188
g_return_if_fail (pa_cvolume_compatible_with_channel_map(cv, &map->priv->pa_map));
190
if (pa_cvolume_equal(cv, &map->priv->pa_volume))
193
map->priv->pa_volume = *cv;
195
if (map->priv->pa_volume_is_set == FALSE) {
196
map->priv->pa_volume_is_set = TRUE;
199
g_signal_emit (map, signals[VOLUME_CHANGED], 0, set);
203
gvc_channel_map_init (GvcChannelMap *map)
205
map->priv = GVC_CHANNEL_MAP_GET_PRIVATE (map);
206
map->priv->pa_volume_is_set = FALSE;
210
gvc_channel_map_finalize (GObject *object)
212
GvcChannelMap *channel_map;
214
g_return_if_fail (object != NULL);
215
g_return_if_fail (GVC_IS_CHANNEL_MAP (object));
217
channel_map = GVC_CHANNEL_MAP (object);
219
g_return_if_fail (channel_map->priv != NULL);
221
G_OBJECT_CLASS (gvc_channel_map_parent_class)->finalize (object);
225
gvc_channel_map_new (void)
228
map = g_object_new (GVC_TYPE_CHANNEL_MAP, NULL);
229
return GVC_CHANNEL_MAP (map);
233
set_from_pa_map (GvcChannelMap *map,
234
const pa_channel_map *pa_map)
236
g_assert (pa_channel_map_valid(pa_map));
238
map->priv->can_balance = pa_channel_map_can_balance (pa_map);
239
map->priv->can_fade = pa_channel_map_can_fade (pa_map);
241
map->priv->pa_map = *pa_map;
242
pa_cvolume_set(&map->priv->pa_volume, pa_map->channels, PA_VOLUME_NORM);
246
gvc_channel_map_new_from_pa_channel_map (const pa_channel_map *pa_map)
249
map = g_object_new (GVC_TYPE_CHANNEL_MAP, NULL);
251
set_from_pa_map (GVC_CHANNEL_MAP (map), pa_map);
253
return GVC_CHANNEL_MAP (map);