changeset 25727:f10e0ac24595

* Added input/output volume preferences for voice conversations. * Properly freed media sessions regarding the media manager. * Made purple_media_session_get_sink actually return the sink.
author Mike Ruprecht <maiku@soc.pidgin.im>
date Sun, 17 Aug 2008 07:55:38 +0000
parents eb289e9086bf
children c48f5c9600c3
files libpurple/media.c libpurple/mediamanager.c libpurple/mediamanager.h pidgin/gtkprefs.c
diffstat 4 files changed, 151 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/media.c	Sun Aug 17 01:06:27 2008 +0000
+++ b/libpurple/media.c	Sun Aug 17 07:55:38 2008 +0000
@@ -31,6 +31,7 @@
 #include "connection.h"
 #include "media.h"
 #include "marshallers.h"
+#include "mediamanager.h"
 
 #include "debug.h"
 
@@ -223,6 +224,9 @@
 	GList *sessions = g_hash_table_get_values(priv->sessions);
 	purple_debug_info("media","purple_media_finalize\n");
 
+	purple_media_manager_remove_media(purple_media_manager_get(),
+			PURPLE_MEDIA(media));
+
 	g_free(priv->name);
 
 	for (; sessions; sessions = g_list_delete_link(sessions, sessions)) {
@@ -524,7 +528,7 @@
 GstElement *
 purple_media_get_sink(PurpleMedia *media, const gchar *sess_id)
 {
-	return purple_media_get_session(media, sess_id)->src;
+	return purple_media_get_session(media, sess_id)->sink;
 }
 
 static gboolean
@@ -767,12 +771,14 @@
 	GstPad *pad;
 	GstPad *ghost;
 	const gchar *audio_device = purple_prefs_get_string("/purple/media/audio/device");
+	double input_volume = purple_prefs_get_int("/purple/media/audio/volume/input")/10.0;
 
 	purple_debug_info("media", "purple_media_audio_init_src\n");
 
 	*sendbin = gst_bin_new("purplesendaudiobin");
 	src = gst_element_factory_make("alsasrc", "asrc");
-	volume = gst_element_factory_make("volume", "purpleaudiovolume");
+	volume = gst_element_factory_make("volume", "purpleaudioinputvolume");
+	g_object_set(volume, "volume", input_volume, NULL);
 	*sendlevel = gst_element_factory_make("level", "sendlevel");
 	gst_bin_add_many(GST_BIN(*sendbin), src, volume, *sendlevel, NULL);
 	gst_element_link(src, volume);
@@ -805,8 +811,10 @@
 	GstElement *src, *tee, *queue, *local_sink;
 	GstPad *pad;
 	GstPad *ghost;
-	const gchar *video_plugin = purple_prefs_get_string("/purple/media/video/plugin");
-	const gchar *video_device = purple_prefs_get_string("/purple/media/video/device");
+	const gchar *video_plugin = purple_prefs_get_string(
+			"/purple/media/video/plugin");
+	const gchar *video_device = purple_prefs_get_string(
+			"/purple/media/video/device");
 
 	purple_debug_info("media", "purple_media_video_init_src\n");
 
@@ -859,18 +867,23 @@
 void
 purple_media_audio_init_recv(GstElement **recvbin, GstElement **recvlevel)
 {
-	GstElement *sink;
+	GstElement *sink, *volume;
 	GstPad *pad, *ghost;
+	double output_volume = purple_prefs_get_int(
+			"/purple/media/audio/volume/output")/10.0;
 
 	purple_debug_info("media", "purple_media_audio_init_recv\n");
 
 	*recvbin = gst_bin_new("pidginrecvaudiobin");
 	sink = gst_element_factory_make("alsasink", "asink");
 	g_object_set(G_OBJECT(sink), "sync", FALSE, NULL);
+	volume = gst_element_factory_make("volume", "purpleaudiooutputvolume");
+	g_object_set(volume, "volume", output_volume, NULL);
 	*recvlevel = gst_element_factory_make("level", "recvlevel");
-	gst_bin_add_many(GST_BIN(*recvbin), sink, *recvlevel, NULL);
+	gst_bin_add_many(GST_BIN(*recvbin), sink, volume, *recvlevel, NULL);
 	gst_element_link(*recvlevel, sink);
-	pad = gst_element_get_pad(*recvlevel, "sink");
+	gst_element_link(volume, *recvlevel);
+	pad = gst_element_get_pad(volume, "sink");
 	ghost = gst_ghost_pad_new("ghostsink", pad);
 	gst_element_add_pad(*recvbin, ghost);
 	g_object_set(G_OBJECT(*recvlevel), "message", TRUE, NULL);
@@ -1272,7 +1285,7 @@
 		if (session->type & PURPLE_MEDIA_SEND_AUDIO) {
 			GstElement *volume = gst_bin_get_by_name(
 					GST_BIN(session->src),
-					"purpleaudiovolume");
+					"purpleaudioinputvolume");
 			g_object_set(volume, "mute", active, NULL);
 		}
 	}
--- a/libpurple/mediamanager.c	Sun Aug 17 01:06:27 2008 +0000
+++ b/libpurple/mediamanager.c	Sun Aug 17 07:55:38 2008 +0000
@@ -116,6 +116,11 @@
 static void
 purple_media_manager_finalize (GObject *media)
 {
+	PurpleMediaManagerPrivate *priv = PURPLE_MEDIA_MANAGER_GET_PRIVATE(media);
+	for (; priv->medias; priv->medias =
+			g_list_delete_link(priv->medias, priv->medias)) {
+		g_object_unref(priv->medias->data);
+	}
 	parent_class->finalize(media);
 }
 
@@ -168,4 +173,20 @@
 	return media;
 }
 
+GList *
+purple_media_manager_get_media(PurpleMediaManager *manager)
+{
+	return manager->priv->medias;
+}
+
+void
+purple_media_manager_remove_media(PurpleMediaManager *manager,
+				  PurpleMedia *media)
+{
+	GList *list = g_list_find(manager->priv->medias, media);
+	if (list)
+		manager->priv->medias =
+			g_list_delete_link(manager->priv->medias, list);
+}
+
 #endif  /* USE_VV */
--- a/libpurple/mediamanager.h	Sun Aug 17 01:06:27 2008 +0000
+++ b/libpurple/mediamanager.h	Sun Aug 17 07:55:38 2008 +0000
@@ -102,6 +102,25 @@
 						const char *conference_type,
 						const char *remote_user);
 
+/**
+ * Gets all of the media sessions.
+ *
+ * @param manager The media manager to get all of the sessions from.
+ *
+ * @return A list of all the media sessions.
+ */
+GList *purple_media_manager_get_media(PurpleMediaManager *manager);
+
+/**
+ * Removes a media session from the media manager.
+ *
+ * @param manager The media manager to remove the media session from.
+ * @param media The media session to remove.
+ */
+void
+purple_media_manager_remove_media(PurpleMediaManager *manager,
+				  PurpleMedia *media);
+
 /*}@*/
 
 #ifdef __cplusplus
--- a/pidgin/gtkprefs.c	Sun Aug 17 01:06:27 2008 +0000
+++ b/pidgin/gtkprefs.c	Sun Aug 17 07:55:38 2008 +0000
@@ -28,6 +28,9 @@
 #include "pidgin.h"
 
 #include "debug.h"
+#ifdef USE_VV
+#include "mediamanager.h"
+#endif
 #include "notify.h"
 #include "prefs.h"
 #include "proxy.h"
@@ -2154,6 +2157,54 @@
 	gtk_widget_show_all(hbox);
 }
 
+static void
+prefs_media_input_volume_changed(GtkRange *range)
+{
+	double val = (double)gtk_range_get_value(GTK_RANGE(range));
+	GList *medias = purple_media_manager_get_media(purple_media_manager_get());
+	purple_prefs_set_int("/purple/media/audio/volume/input", val);
+
+	val /= 10.0;
+	for (; medias; medias = g_list_next(medias)) {
+		PurpleMedia *media = PURPLE_MEDIA(medias->data);
+		GList *sessions = purple_media_get_session_names(media);
+		for (; sessions; sessions = g_list_delete_link(sessions, sessions)) {
+			const gchar *session = sessions->data;
+			if (purple_media_get_session_type(media, session)
+					& PURPLE_MEDIA_SEND_AUDIO) {
+				GstElement *volume = gst_bin_get_by_name(
+						GST_BIN(purple_media_get_src(media, session)),
+						"purpleaudioinputvolume");
+				g_object_set(volume, "volume", val, NULL);
+			}
+		}
+	}
+}
+
+static void
+prefs_media_output_volume_changed(GtkRange *range)
+{
+	double val = (double)gtk_range_get_value(GTK_RANGE(range));
+	GList *medias = purple_media_manager_get_media(purple_media_manager_get());
+	purple_prefs_set_int("/purple/media/audio/volume/output", val);
+
+	val /= 10.0;
+	for (; medias; medias = g_list_next(medias)) {
+		PurpleMedia *media = PURPLE_MEDIA(medias->data);
+		GList *sessions = purple_media_get_session_names(media);
+		for (; sessions; sessions = g_list_delete_link(sessions, sessions)) {
+			const gchar *session = sessions->data;
+			if (purple_media_get_session_type(media, session)
+					& PURPLE_MEDIA_RECV_AUDIO) {
+				GstElement *volume = gst_bin_get_by_name(
+						GST_BIN(purple_media_get_sink(media, session)),
+						"purpleaudiooutputvolume");
+				g_object_set(volume, "volume", val, NULL);
+			}
+		}
+	}
+}
+
 static GtkWidget *
 media_page()
 {
@@ -2162,7 +2213,8 @@
 	GtkWidget *hbox;
 	GtkWidget *dd;
 	GtkWidget *preview_button;
-	GtkSizeGroup *sg;
+	GtkWidget *sw;
+	GtkSizeGroup *sg, *sg2;
 	const char *plugin = purple_prefs_get_string("/purple/media/video/plugin");
 	const char *device = purple_prefs_get_string("/purple/media/video/device");
 
@@ -2199,8 +2251,10 @@
 	gtk_container_set_border_width (GTK_CONTAINER (ret), PIDGIN_HIG_BORDER);
 
 	sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+	sg2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 
 	vbox = pidgin_make_frame (ret, _("Video Input"));
+	gtk_size_group_add_widget(sg2, vbox);
 
 	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
 	dd = pidgin_prefs_dropdown(vbox, _("_Plugin:"), PURPLE_PREF_STRING,
@@ -2215,7 +2269,7 @@
 	gtk_misc_set_alignment(GTK_MISC(dd), 0, 0.5);
 
 	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-	dd = pidgin_prefs_dropdown_from_list(hbox, _("_Device:"), PURPLE_PREF_STRING,
+	dd = pidgin_prefs_dropdown_from_list(hbox, _("Device:"), PURPLE_PREF_STRING,
 			"/purple/media/video/device",
 			video_items);
 
@@ -2236,7 +2290,8 @@
 	gtk_container_add(GTK_CONTAINER(vbox), hbox);
 
 	vbox = pidgin_make_frame (ret, _("Audio Input"));
-	dd = pidgin_prefs_dropdown_from_list(vbox, _("_Device:"), PURPLE_PREF_STRING,
+	gtk_size_group_add_widget(sg2, vbox);
+	dd = pidgin_prefs_dropdown_from_list(vbox, _("Device:"), PURPLE_PREF_STRING,
 			"/purple/media/audio/device",
 			audio_items);
 
@@ -2246,6 +2301,35 @@
 	hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
 	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 
+	/* Input Volume */
+	sw = gtk_hscale_new_with_range(0.0, 100.0, 5.0);
+	gtk_range_set_increments(GTK_RANGE(sw), 5.0, 25.0);
+	gtk_range_set_value(GTK_RANGE(sw),
+			purple_prefs_get_int("/purple/media/audio/volume/input"));
+	g_signal_connect (G_OBJECT (sw), "format-value",
+			  G_CALLBACK (prefs_sound_volume_format),
+			  NULL);
+	g_signal_connect (G_OBJECT (sw), "value-changed",
+			  G_CALLBACK (prefs_media_input_volume_changed),
+			  NULL);
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Volume:"), sg, sw, TRUE, NULL);
+
+	vbox = pidgin_make_frame (ret, _("Audio Output"));
+	gtk_size_group_add_widget(sg2, vbox);
+
+	/* Output Volume */
+	sw = gtk_hscale_new_with_range(0.0, 100.0, 5.0);
+	gtk_range_set_increments(GTK_RANGE(sw), 5.0, 25.0);
+	gtk_range_set_value(GTK_RANGE(sw),
+			purple_prefs_get_int("/purple/media/audio/volume/output"));
+	g_signal_connect (G_OBJECT (sw), "format-value",
+			  G_CALLBACK (prefs_sound_volume_format),
+			  NULL);
+	g_signal_connect (G_OBJECT (sw), "value-changed",
+			  G_CALLBACK (prefs_media_output_volume_changed),
+			  NULL);
+	pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Volume:"), sg, sw, TRUE, NULL);
+
 	gtk_widget_show_all(ret);
 
 	return ret;
@@ -2513,6 +2597,9 @@
 	purple_prefs_add_string("/purple/media/video/device", "");
 	purple_prefs_add_none("/purple/media/audio");
 	purple_prefs_add_string("/purple/media/audio/device", "");
+	purple_prefs_add_none("/purple/media/audio/volume");
+	purple_prefs_add_int("/purple/media/audio/volume/input", 10);
+	purple_prefs_add_int("/purple/media/audio/volume/output", 10);
 #endif /* USE_VV */
 
 	pidgin_prefs_update_old();