Skip to content

Commit 249f587

Browse files
committed
libcvc: Re-add stream monitor, balance, fade, lfe to channel map,
other small things.
1 parent 2d4f356 commit 249f587

7 files changed

Lines changed: 306 additions & 5 deletions

File tree

debian/libcvc0.symbols

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ libcvc.so.0 libcvc0 #MINVER#
1919
gvc_channel_map_set_lfe@Base 4.2.0
2020
gvc_channel_map_volume_changed@Base 4.2.0
2121
gvc_headset_port_choice_get_type@Base 5.3.0
22+
gvc_mixer_card_add_port@Base 6.6.2
2223
gvc_mixer_card_change_profile@Base 4.2.0
2324
gvc_mixer_card_get_gicon@Base 4.2.0
2425
gvc_mixer_card_get_icon_name@Base 4.2.0
@@ -32,6 +33,7 @@ libcvc.so.0 libcvc0 #MINVER#
3233
gvc_mixer_card_get_type@Base 4.2.0
3334
gvc_mixer_card_new@Base 4.2.0
3435
gvc_mixer_card_profile_compare@Base 4.2.0
36+
gvc_mixer_card_remove_port@Base 6.6.2
3537
gvc_mixer_card_set_icon_name@Base 4.2.0
3638
gvc_mixer_card_set_name@Base 4.2.0
3739
gvc_mixer_card_set_ports@Base 4.2.0

libcvc/gvc-channel-map.c

Lines changed: 107 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,38 @@ gvc_channel_map_get_volume (GvcChannelMap *map)
8989
return map->priv->extern_volume;
9090
}
9191

92+
gfloat
93+
gvc_channel_map_get_balance (GvcChannelMap *map)
94+
{
95+
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), 0);
96+
97+
if (!pa_channel_map_valid (&map->priv->pa_map))
98+
return 0;
99+
100+
if (gvc_channel_map_can_balance (map))
101+
return (gfloat) pa_cvolume_get_balance (&map->priv->pa_volume, &map->priv->pa_map);
102+
else
103+
return 0;
104+
}
105+
106+
void
107+
gvc_channel_map_set_balance (GvcChannelMap *map,
108+
gfloat value)
109+
{
110+
pa_cvolume cv;
111+
112+
g_return_if_fail (GVC_IS_CHANNEL_MAP (map));
113+
114+
if (!gvc_channel_map_can_balance (map))
115+
return;
116+
117+
cv = *gvc_channel_map_get_cvolume (map);
118+
pa_cvolume_set_balance (&cv, &map->priv->pa_map, value);
119+
120+
if (!pa_cvolume_equal (&cv, &map->priv->pa_volume))
121+
gvc_channel_map_volume_changed (map, &cv, TRUE);
122+
}
123+
92124
gboolean
93125
gvc_channel_map_can_balance (const GvcChannelMap *map)
94126
{
@@ -97,6 +129,38 @@ gvc_channel_map_can_balance (const GvcChannelMap *map)
97129
return map->priv->can_balance;
98130
}
99131

132+
gfloat
133+
gvc_channel_map_get_fade (GvcChannelMap *map)
134+
{
135+
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), 0);
136+
137+
if (!pa_channel_map_valid (&map->priv->pa_map))
138+
return 0;
139+
140+
if (gvc_channel_map_can_fade (map))
141+
return (gfloat) pa_cvolume_get_fade (&map->priv->pa_volume, &map->priv->pa_map);
142+
else
143+
return 0;
144+
}
145+
146+
void
147+
gvc_channel_map_set_fade (GvcChannelMap *map,
148+
gfloat value)
149+
{
150+
pa_cvolume cv;
151+
152+
g_return_if_fail (GVC_IS_CHANNEL_MAP (map));
153+
154+
if (!gvc_channel_map_can_fade (map))
155+
return;
156+
157+
cv = *gvc_channel_map_get_cvolume(map);
158+
pa_cvolume_set_fade (&cv, &map->priv->pa_map, value);
159+
160+
if (!pa_cvolume_equal (&cv, &map->priv->pa_volume))
161+
gvc_channel_map_volume_changed(map, &cv, TRUE);
162+
}
163+
100164
gboolean
101165
gvc_channel_map_can_fade (const GvcChannelMap *map)
102166
{
@@ -105,6 +169,47 @@ gvc_channel_map_can_fade (const GvcChannelMap *map)
105169
return map->priv->can_fade;
106170
}
107171

172+
gfloat
173+
gvc_channel_map_get_lfe (GvcChannelMap *map)
174+
{
175+
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), 0);
176+
177+
if (!pa_channel_map_valid (&map->priv->pa_map))
178+
return 0;
179+
180+
if (gvc_channel_map_has_lfe (map))
181+
return (gfloat) pa_cvolume_get_position (&map->priv->pa_volume, &map->priv->pa_map, PA_CHANNEL_POSITION_LFE);
182+
else
183+
return 0;
184+
}
185+
186+
void
187+
gvc_channel_map_set_lfe (GvcChannelMap *map,
188+
gfloat value)
189+
{
190+
pa_cvolume cv;
191+
192+
g_return_if_fail (GVC_IS_CHANNEL_MAP (map));
193+
194+
if (!gvc_channel_map_has_lfe (map))
195+
return;
196+
197+
cv = *gvc_channel_map_get_cvolume (map);
198+
199+
pa_cvolume_set_position (&cv, &map->priv->pa_map, PA_CHANNEL_POSITION_LFE, value);
200+
201+
if (!pa_cvolume_equal (&cv, &map->priv->pa_volume))
202+
gvc_channel_map_volume_changed (map, &cv, TRUE);
203+
}
204+
205+
gboolean
206+
gvc_channel_map_can_lfe (const GvcChannelMap *map)
207+
{
208+
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), FALSE);
209+
210+
return gvc_channel_map_has_lfe(map);
211+
}
212+
108213
const char *
109214
gvc_channel_map_get_mapping (const GvcChannelMap *map)
110215
{
@@ -117,9 +222,9 @@ gvc_channel_map_get_mapping (const GvcChannelMap *map)
117222
}
118223

119224
/**
120-
* gvc_channel_map_has_position: (skip)
225+
* gvc_channel_map_has_position:
121226
* @map:
122-
* @position:
227+
* @position: (type int)
123228
*
124229
* Returns:
125230
*/

libcvc/gvc-channel-map.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,19 @@ GType gvc_channel_map_get_type (void);
6060
GvcChannelMap * gvc_channel_map_new (void);
6161
guint gvc_channel_map_get_num_channels (const GvcChannelMap *map);
6262
const gdouble * gvc_channel_map_get_volume (GvcChannelMap *map);
63+
gfloat gvc_channel_map_get_balance (GvcChannelMap *map);
6364
gboolean gvc_channel_map_can_balance (const GvcChannelMap *map);
65+
void gvc_channel_map_set_balance (GvcChannelMap *map,
66+
gfloat value);
67+
gfloat gvc_channel_map_get_fade (GvcChannelMap *map);
68+
void gvc_channel_map_set_fade (GvcChannelMap *map,
69+
gfloat value);
6470
gboolean gvc_channel_map_can_fade (const GvcChannelMap *map);
65-
gboolean gvc_channel_map_has_position (const GvcChannelMap *map,
71+
gfloat gvc_channel_map_get_lfe (GvcChannelMap *map);
72+
void gvc_channel_map_set_lfe (GvcChannelMap *map,
73+
gfloat value);
74+
gboolean gvc_channel_map_can_lfe (const GvcChannelMap *map);
75+
gboolean gvc_channel_map_has_position (const GvcChannelMap *map,
6676
pa_channel_position_t position);
6777
#define gvc_channel_map_has_lfe(x) gvc_channel_map_has_position (x, PA_CHANNEL_POSITION_LFE)
6878

libcvc/gvc-mixer-control.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,11 @@ gvc_mixer_control_change_profile_on_selected_device (GvcMixerControl *control,
542542
g_object_get (G_OBJECT (device), "card", &card, NULL);
543543
current_profile = gvc_mixer_card_get_profile (card);
544544

545+
if (!current_profile) {
546+
g_warning ("gvc_mixer_card_get_profile() returned NULL for card %p", card);
547+
return FALSE;
548+
}
549+
545550
if (current_profile)
546551
best_profile = gvc_mixer_ui_device_get_best_profile (device, profile, current_profile->profile);
547552
else
@@ -1816,7 +1821,7 @@ update_sink_input (GvcMixerControl *control,
18161821

18171822
set_application_id_from_proplist (stream, info->proplist);
18181823
set_is_event_stream_from_proplist (stream, info->proplist);
1819-
set_icon_name_from_proplist (stream, info->proplist, "application-x-executable");
1824+
set_icon_name_from_proplist (stream, info->proplist, "applications-multimedia");
18201825
gvc_mixer_stream_set_volume (stream, (guint)max_volume);
18211826
gvc_mixer_stream_set_is_muted (stream, info->mute);
18221827
gvc_mixer_stream_set_is_virtual (stream, info->client == PA_INVALID_INDEX);
@@ -2916,7 +2921,7 @@ update_event_role_stream (GvcMixerControl *control,
29162921
max_volume = pa_cvolume_max (&info->volume);
29172922

29182923
gvc_mixer_stream_set_name (stream, _("System Sounds"));
2919-
gvc_mixer_stream_set_icon_name (stream, "audio-x-generic");
2924+
gvc_mixer_stream_set_icon_name (stream, "xsi-emblem-system-symbolic");
29202925
gvc_mixer_stream_set_volume (stream, (guint)max_volume);
29212926
gvc_mixer_stream_set_is_muted (stream, info->mute);
29222927

libcvc/gvc-mixer-stream.c

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,14 @@ enum
8787
};
8888
static GParamSpec *obj_props[N_PROPS] = { NULL, };
8989

90+
enum {
91+
MONITOR_UPDATE,
92+
MONITOR_SUSPEND,
93+
LAST_SIGNAL
94+
};
95+
96+
static guint signals [LAST_SIGNAL] = { 0, };
97+
9098
static void gvc_mixer_stream_finalize (GObject *object);
9199

92100
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GvcMixerStream, gvc_mixer_stream, G_TYPE_OBJECT)
@@ -887,6 +895,152 @@ gvc_mixer_stream_is_running (GvcMixerStream *stream)
887895
return FALSE;
888896
}
889897

898+
static void
899+
on_monitor_suspended_callback (pa_stream *s,
900+
void *userdata)
901+
{
902+
GvcMixerStream *stream;
903+
904+
stream = userdata;
905+
906+
if (pa_stream_is_suspended (s)) {
907+
g_debug ("Stream suspended");
908+
g_signal_emit (stream, signals[MONITOR_SUSPEND], 0);
909+
}
910+
}
911+
912+
static void
913+
on_monitor_read_callback (pa_stream *s,
914+
size_t length,
915+
void *userdata)
916+
{
917+
GvcMixerStream *stream;
918+
const void *data;
919+
double v;
920+
921+
stream = userdata;
922+
923+
if (pa_stream_peek (s, &data, &length) < 0) {
924+
g_warning ("Failed to read data from stream");
925+
return;
926+
}
927+
928+
g_assert (length > 0);
929+
g_assert (length % sizeof (float) == 0);
930+
931+
v = ((const float *) data)[length / sizeof (float) -1];
932+
933+
pa_stream_drop (s);
934+
935+
if (v < 0) {
936+
v = 0;
937+
}
938+
if (v > 1) {
939+
v = 1;
940+
}
941+
g_signal_emit (stream, signals[MONITOR_UPDATE], 0, v);
942+
}
943+
944+
/**
945+
* gvc_mixer_stream_create_monitor:
946+
* @stream:
947+
*/
948+
void
949+
gvc_mixer_stream_create_monitor (GvcMixerStream *stream)
950+
{
951+
pa_stream *s;
952+
char t[16];
953+
pa_buffer_attr attr;
954+
pa_sample_spec ss;
955+
pa_context *context;
956+
int res;
957+
pa_proplist *proplist;
958+
gboolean has_monitor;
959+
960+
if (stream == NULL) {
961+
return;
962+
}
963+
has_monitor = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (stream), "has-monitor"));
964+
if (has_monitor != FALSE) {
965+
return;
966+
}
967+
968+
g_debug ("Create monitor for %u",
969+
gvc_mixer_stream_get_index (stream));
970+
971+
context = gvc_mixer_stream_get_pa_context (stream);
972+
973+
if (pa_context_get_server_protocol_version (context) < 13) {
974+
return;
975+
}
976+
977+
ss.channels = 1;
978+
ss.format = PA_SAMPLE_FLOAT32;
979+
ss.rate = 25;
980+
981+
memset (&attr, 0, sizeof (attr));
982+
attr.fragsize = sizeof (float);
983+
attr.maxlength = (uint32_t) -1;
984+
985+
snprintf (t, sizeof (t), "%u", gvc_mixer_stream_get_index (stream));
986+
987+
proplist = pa_proplist_new ();
988+
pa_proplist_sets (proplist, PA_PROP_APPLICATION_ID, "org.gnome.VolumeControl");
989+
s = pa_stream_new_with_proplist (context, "Peak detect", &ss, NULL, proplist);
990+
pa_proplist_free (proplist);
991+
if (s == NULL) {
992+
g_warning ("Failed to create monitoring stream");
993+
return;
994+
}
995+
996+
pa_stream_set_read_callback (s, on_monitor_read_callback, stream);
997+
pa_stream_set_suspended_callback (s, on_monitor_suspended_callback, stream);
998+
999+
res = pa_stream_connect_record (s,
1000+
t,
1001+
&attr,
1002+
(pa_stream_flags_t) (PA_STREAM_DONT_MOVE
1003+
|PA_STREAM_PEAK_DETECT
1004+
|PA_STREAM_ADJUST_LATENCY));
1005+
if (res < 0) {
1006+
g_warning ("Failed to connect monitoring stream");
1007+
pa_stream_unref (s);
1008+
} else {
1009+
g_object_set_data (G_OBJECT (stream), "has-monitor", GINT_TO_POINTER (TRUE));
1010+
g_object_set_data (G_OBJECT (stream), "pa_stream", s);
1011+
}
1012+
}
1013+
1014+
/**
1015+
* gvc_mixer_stream_remove_monitor:
1016+
* @stream:
1017+
*/
1018+
void
1019+
gvc_mixer_stream_remove_monitor (GvcMixerStream *stream)
1020+
{
1021+
pa_stream *s;
1022+
pa_context *context;
1023+
int res;
1024+
1025+
s = g_object_get_data (G_OBJECT (stream), "pa_stream");
1026+
if (s == NULL)
1027+
return;
1028+
g_assert (stream != NULL);
1029+
1030+
g_debug ("Stopping monitor for %u", pa_stream_get_index (s));
1031+
1032+
context = gvc_mixer_stream_get_pa_context (stream);
1033+
1034+
if (pa_context_get_server_protocol_version (context) < 13) {
1035+
return;
1036+
}
1037+
1038+
res = pa_stream_disconnect (s);
1039+
if (res == 0)
1040+
g_object_set_data (G_OBJECT (stream), "has-monitor", GINT_TO_POINTER (FALSE));
1041+
g_object_set_data (G_OBJECT (stream), "pa_stream", NULL);
1042+
}
1043+
8901044
static void
8911045
gvc_mixer_stream_class_init (GvcMixerStreamClass *klass)
8921046
{
@@ -998,6 +1152,21 @@ gvc_mixer_stream_class_init (GvcMixerStreamClass *klass)
9981152
G_PARAM_READWRITE|G_PARAM_CONSTRUCT|G_PARAM_STATIC_STRINGS);
9991153

10001154
g_object_class_install_properties (gobject_class, N_PROPS, obj_props);
1155+
1156+
signals [MONITOR_UPDATE] =
1157+
g_signal_new ("monitor-update",
1158+
G_TYPE_FROM_CLASS (klass),
1159+
G_SIGNAL_RUN_LAST,
1160+
G_STRUCT_OFFSET (GvcMixerStreamClass, monitor_update),
1161+
NULL, NULL, NULL,
1162+
G_TYPE_NONE, 1, G_TYPE_DOUBLE);
1163+
signals [MONITOR_SUSPEND] =
1164+
g_signal_new ("monitor-suspend",
1165+
G_TYPE_FROM_CLASS (klass),
1166+
G_SIGNAL_RUN_LAST,
1167+
G_STRUCT_OFFSET (GvcMixerStreamClass, monitor_suspend),
1168+
NULL, NULL, NULL,
1169+
G_TYPE_NONE, 0, G_TYPE_NONE);
10011170
}
10021171

10031172
static void

0 commit comments

Comments
 (0)