Mercurial > pidgin
changeset 27849:c8ff0a9cf8cc
Unlink the local audio volume and mute between sessions.
author | Mike Ruprecht <maiku@soc.pidgin.im> |
---|---|
date | Fri, 07 Aug 2009 08:23:12 +0000 |
parents | 9824572dbb49 |
children | 47a356df8b5a |
files | finch/gntmedia.c libpurple/marshallers.list libpurple/media.c libpurple/mediamanager.c pidgin/gtkmedia.c |
diffstat | 5 files changed, 152 insertions(+), 187 deletions(-) [+] |
line wrap: on
line diff
--- a/finch/gntmedia.c Fri Aug 07 00:08:43 2009 +0000 +++ b/finch/gntmedia.c Fri Aug 07 08:23:12 2009 +0000 @@ -417,11 +417,7 @@ create_default_audio_src(PurpleMedia *media, const gchar *session_id, const gchar *participant) { - GstElement *bin, *src, *volume; - GstPad *pad, *ghost; - double input_volume = purple_prefs_get_int( - "/finch/media/audio/volume/input")/10.0; - + GstElement *src; src = gst_element_factory_make("gconfaudiosrc", NULL); if (src == NULL) src = gst_element_factory_make("autoaudiosrc", NULL); @@ -436,28 +432,15 @@ "element for the default audio source.\n"); return NULL; } - - bin = gst_bin_new("finchdefaultaudiosrc"); - volume = gst_element_factory_make("volume", "purpleaudioinputvolume"); - g_object_set(volume, "volume", input_volume, NULL); - gst_bin_add_many(GST_BIN(bin), src, volume, NULL); - gst_element_link(src, volume); - pad = gst_element_get_pad(volume, "src"); - ghost = gst_ghost_pad_new("ghostsrc", pad); - gst_element_add_pad(bin, ghost); - - return bin; + gst_element_set_name(src, "finchdefaultaudiosrc"); + return src; } static GstElement * create_default_audio_sink(PurpleMedia *media, const gchar *session_id, const gchar *participant) { - GstElement *bin, *sink, *volume, *queue; - GstPad *pad, *ghost; - double output_volume = purple_prefs_get_int( - "/finch/media/audio/volume/output")/10.0; - + GstElement *sink; sink = gst_element_factory_make("gconfaudiosink", NULL); if (sink == NULL) sink = gst_element_factory_make("autoaudiosink",NULL); @@ -466,19 +449,7 @@ "element for the default audio sink.\n"); return NULL; } - - bin = gst_bin_new("finchdefaultaudiosink"); - volume = gst_element_factory_make("volume", "purpleaudiooutputvolume"); - g_object_set(volume, "volume", output_volume, NULL); - queue = gst_element_factory_make("queue", NULL); - gst_bin_add_many(GST_BIN(bin), sink, volume, queue, NULL); - gst_element_link(volume, sink); - gst_element_link(queue, volume); - pad = gst_element_get_pad(queue, "sink"); - ghost = gst_ghost_pad_new("ghostsink", pad); - gst_element_add_pad(bin, ghost); - - return bin; + return sink; } #endif /* USE_VV */ @@ -516,12 +487,6 @@ purple_debug_info("gntmedia", "Registering media element types\n"); purple_media_manager_set_active_element(manager, default_audio_src); purple_media_manager_set_active_element(manager, default_audio_sink); - - purple_prefs_add_none("/finch/media"); - purple_prefs_add_none("/finch/media/audio"); - purple_prefs_add_none("/finch/media/audio/volume"); - purple_prefs_add_int("/finch/media/audio/volume/input", 10); - purple_prefs_add_int("/finch/media/audio/volume/output", 10); #endif }
--- a/libpurple/marshallers.list Fri Aug 07 00:08:43 2009 +0000 +++ b/libpurple/marshallers.list Fri Aug 07 08:23:12 2009 +0000 @@ -1,5 +1,6 @@ VOID:POINTER,POINTER,OBJECT BOOLEAN:OBJECT,POINTER,STRING VOID:STRING,STRING +VOID:STRING,STRING,DOUBLE VOID:ENUM,STRING,STRING VOID:ENUM,STRING,STRING,BOOLEAN
--- a/libpurple/media.c Fri Aug 07 00:08:43 2009 +0000 +++ b/libpurple/media.c Fri Aug 07 08:23:12 2009 +0000 @@ -94,6 +94,8 @@ FsStream *stream; GstElement *src; GstElement *tee; + GstElement *volume; + GstElement *level; GList *local_candidates; GList *remote_candidates; @@ -159,6 +161,7 @@ S_ERROR, CANDIDATES_PREPARED, CODECS_CHANGED, + LEVEL, NEW_CANDIDATE, STATE_CHANGED, STREAM_INFO, @@ -340,6 +343,11 @@ G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); + purple_media_signals[LEVEL] = g_signal_new("level", G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + purple_smarshal_VOID__STRING_STRING_DOUBLE, + G_TYPE_NONE, 3, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_DOUBLE); purple_media_signals[NEW_CANDIDATE] = g_signal_new("new-candidate", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, purple_smarshal_VOID__POINTER_POINTER_OBJECT, @@ -1898,7 +1906,27 @@ gst_element_set_state(session->tee, GST_STATE_PLAYING); g_object_get(session->session, "sink-pad", &sinkpad, NULL); - srcpad = gst_element_get_request_pad(session->tee, "src%d"); + if (session->type & PURPLE_MEDIA_SEND_AUDIO) { + gchar *name = g_strdup_printf("volume_%s", session->id); + GstElement *level; + GstElement *volume = gst_element_factory_make("volume", name); + double input_volume = purple_prefs_get_int( + "/purple/media/audio/volume/input")/10.0; + g_free(name); + name = g_strdup_printf("sendlevel_%s", session->id); + level = gst_element_factory_make("level", name); + g_free(name); + gst_bin_add(GST_BIN(session->media->priv->confbin), volume); + gst_bin_add(GST_BIN(session->media->priv->confbin), level); + gst_element_link(session->tee, volume); + gst_element_link(volume, level); + gst_element_set_state(level, GST_STATE_PLAYING); + gst_element_set_state(volume, GST_STATE_PLAYING); + srcpad = gst_element_get_static_pad(level, "src"); + g_object_set(volume, "volume", input_volume, NULL); + } else { + srcpad = gst_element_get_request_pad(session->tee, "src%d"); + } purple_debug_info("media", "connecting pad: %s\n", gst_pad_link(srcpad, sinkpad) == GST_PAD_LINK_OK ? "success" : "failure"); @@ -1955,6 +1983,55 @@ { switch(GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_ELEMENT: { + if (g_signal_has_handler_pending(media, + purple_media_signals[LEVEL], 0, FALSE) + && gst_structure_has_name( + gst_message_get_structure(msg), "level")) { + GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(msg)); + gchar *name; + gchar *participant = NULL; + PurpleMediaSession *session = NULL; + gdouble rms_db; + gdouble percent; + const GValue *list; + const GValue *value; + + if (!PURPLE_IS_MEDIA(media) || + GST_ELEMENT_PARENT(src) != + media->priv->confbin) + break; + + name = gst_element_get_name(src); + if (!strncmp(name, "sendlevel_", 10)) { + session = purple_media_get_session( + media, name+10); + } else { + GList *iter = media->priv->streams; + for (; iter; iter = g_list_next(iter)) { + PurpleMediaStream *stream = iter->data; + if (stream->level == src) { + session = stream->session; + participant = stream->participant; + break; + } + } + } + g_free(name); + if (!session) + break; + + list = gst_structure_get_value( + gst_message_get_structure(msg), "rms"); + value = gst_value_list_get_value(list, 0); + rms_db = g_value_get_double(value); + percent = pow(10, rms_db / 20) * 5; + if(percent > 1.0) + percent = 1.0; + + g_signal_emit(media, purple_media_signals[LEVEL], + 0, session->id, participant, percent); + break; + } if (!FS_IS_CONFERENCE(GST_MESSAGE_SRC(msg)) || !PURPLE_IS_MEDIA(media) || media->priv->conference != @@ -2172,9 +2249,12 @@ sessions, sessions)) { PurpleMediaSession *session = sessions->data; if (session->type & PURPLE_MEDIA_SEND_AUDIO) { + gchar *name = g_strdup_printf("volume_%s", + session->id); GstElement *volume = gst_bin_get_by_name( - GST_BIN(session->src), - "purpleaudioinputvolume"); + GST_BIN(session->media-> + priv->confbin), name); + g_free(name); g_object_set(volume, "mute", active, NULL); } } @@ -2338,11 +2418,21 @@ GstElement *sink = NULL; if (codec->media_type == FS_MEDIA_TYPE_AUDIO) { + GstElement *queue = NULL; + double output_volume = purple_prefs_get_int( + "/purple/media/audio/volume/output")/10.0; /* * Should this instead be: * audioconvert ! audioresample ! liveadder ! * audioresample ! audioconvert ! realsink */ + queue = gst_element_factory_make("queue", NULL); + stream->volume = gst_element_factory_make( + "volume", NULL); + g_object_set(stream->volume, "volume", + output_volume, NULL); + stream->level = gst_element_factory_make( + "level", NULL); stream->src = gst_element_factory_make( "liveadder", NULL); sink = purple_media_manager_get_element(priv->manager, @@ -2350,16 +2440,28 @@ stream->session->media, stream->session->id, stream->participant); + gst_bin_add(GST_BIN(priv->confbin), queue); + gst_bin_add(GST_BIN(priv->confbin), stream->volume); + gst_bin_add(GST_BIN(priv->confbin), stream->level); + gst_bin_add(GST_BIN(priv->confbin), sink); + gst_element_link(stream->level, sink); + gst_element_link(stream->volume, stream->level); + gst_element_link(queue, stream->volume); + gst_element_sync_state_with_parent(sink); + gst_element_sync_state_with_parent(stream->level); + gst_element_sync_state_with_parent(stream->volume); + sink = queue; } else if (codec->media_type == FS_MEDIA_TYPE_VIDEO) { stream->src = gst_element_factory_make( "fsfunnel", NULL); sink = gst_element_factory_make( "fakesink", NULL); g_object_set(G_OBJECT(sink), "async", FALSE, NULL); + gst_bin_add(GST_BIN(priv->confbin), sink); } stream->tee = gst_element_factory_make("tee", NULL); gst_bin_add_many(GST_BIN(priv->confbin), - stream->src, stream->tee, sink, NULL); + stream->src, stream->tee, NULL); gst_element_sync_state_with_parent(sink); gst_element_sync_state_with_parent(stream->tee); gst_element_sync_state_with_parent(stream->src); @@ -2975,6 +3077,8 @@ g_return_if_fail(PURPLE_IS_MEDIA(media)); + purple_prefs_set_int("/purple/media/audio/volume/input", level); + if (session_id == NULL) sessions = g_hash_table_get_values(media->priv->sessions); else @@ -2985,10 +3089,13 @@ PurpleMediaSession *session = sessions->data; if (session->type & PURPLE_MEDIA_SEND_AUDIO) { + gchar *name = g_strdup_printf("volume_%s", + session->id); GstElement *volume = gst_bin_get_by_name( - GST_BIN(session->src), - "purpleaudioinputvolume"); - g_object_set(volume, "volume", level, NULL); + GST_BIN(session->media->priv->confbin), + name); + g_free(name); + g_object_set(volume, "volume", level/10.0, NULL); } } #endif @@ -3003,34 +3110,17 @@ g_return_if_fail(PURPLE_IS_MEDIA(media)); + purple_prefs_set_int("/purple/media/audio/volume/output", level); + streams = purple_media_get_streams(media, session_id, participant); for (; streams; streams = g_list_delete_link(streams, streams)) { PurpleMediaStream *stream = streams->data; - if (stream->session->type & PURPLE_MEDIA_RECV_AUDIO) { - GstElement *tee = stream->tee; - GstIterator *iter = gst_element_iterate_src_pads(tee); - GstPad *sinkpad; - while (gst_iterator_next(iter, (gpointer)&sinkpad) - == GST_ITERATOR_OK) { - GstPad *peer = gst_pad_get_peer(sinkpad); - GstElement *volume; - - if (peer == NULL) { - gst_object_unref(sinkpad); - continue; - } - - volume = gst_bin_get_by_name(GST_BIN( - GST_OBJECT_PARENT(peer)), - "purpleaudiooutputvolume"); - g_object_set(volume, "volume", level, NULL); - gst_object_unref(peer); - gst_object_unref(sinkpad); - } - gst_iterator_free(iter); + if (stream->session->type & PURPLE_MEDIA_RECV_AUDIO + && GST_IS_ELEMENT(stream->volume)) { + g_object_set(stream->volume, "volume", level/10.0, NULL); } } #endif
--- a/libpurple/mediamanager.c Fri Aug 07 00:08:43 2009 +0000 +++ b/libpurple/mediamanager.c Fri Aug 07 08:23:12 2009 +0000 @@ -157,6 +157,12 @@ media->priv = PURPLE_MEDIA_MANAGER_GET_PRIVATE(media); media->priv->medias = NULL; media->priv->next_output_window_id = 1; + + purple_prefs_add_none("/purple/media"); + purple_prefs_add_none("/purple/media/audio"); + 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); } static void
--- a/pidgin/gtkmedia.c Fri Aug 07 00:08:43 2009 +0000 +++ b/pidgin/gtkmedia.c Fri Aug 07 08:23:12 2009 +0000 @@ -84,6 +84,7 @@ gchar *screenname; GstElement *send_level; GstElement *recv_level; + gulong level_handler_id; GtkItemFactory *item_factory; GtkWidget *menubar; @@ -338,45 +339,16 @@ G_CALLBACK(pidgin_media_delete_event_cb), media); } -static gboolean -level_message_cb(GstBus *bus, GstMessage *message, PidginMedia *gtkmedia) +static void +level_message_cb(PurpleMedia *media, gchar *session_id, gchar *participant, + double level, PidginMedia *gtkmedia) { - gdouble rms_db; - gdouble percent; - const GValue *list; - const GValue *value; - - GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(message)); GtkWidget *progress; - - if (message->type != GST_MESSAGE_ELEMENT) - return TRUE; - - if (!gst_structure_has_name( - gst_message_get_structure(message), "level")) - return TRUE; - - if (src == gtkmedia->priv->send_level) + if (participant == NULL) progress = gtkmedia->priv->send_progress; - else if (src == gtkmedia->priv->recv_level) + else progress = gtkmedia->priv->recv_progress; - else - return TRUE; - - list = gst_structure_get_value( - gst_message_get_structure(message), "rms"); - - /* Only bother with the first channel. */ - value = gst_value_list_get_value(list, 0); - rms_db = g_value_get_double(value); - - percent = pow(10, rms_db / 20) * 5; - - if(percent > 1.0) - percent = 1.0; - - gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), percent); - return TRUE; + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), level); } @@ -565,8 +537,7 @@ { double val = (double)gtk_range_get_value(GTK_RANGE(range)); #endif - purple_prefs_set_int("/pidgin/media/audio/volume/input", val); - purple_media_set_input_volume(media, NULL, val / 10.0); + purple_media_set_input_volume(media, NULL, val); } static void @@ -580,8 +551,7 @@ { double val = (double)gtk_range_get_value(GTK_RANGE(range)); #endif - purple_prefs_set_int("/pidgin/media/audio/volume/output", val); - purple_media_set_output_volume(media, NULL, NULL, val / 10.0); + purple_media_set_output_volume(media, NULL, NULL, val); } static GtkWidget * @@ -593,10 +563,10 @@ if (type & PURPLE_MEDIA_SEND_AUDIO) { value = purple_prefs_get_int( - "/pidgin/media/audio/volume/input"); + "/purple/media/audio/volume/input"); } else if (type & PURPLE_MEDIA_RECV_AUDIO) { value = purple_prefs_get_int( - "/pidgin/media/audio/volume/output"); + "/purple/media/audio/volume/output"); } else g_return_val_if_reached(NULL); @@ -651,8 +621,6 @@ static void pidgin_media_ready_cb(PurpleMedia *media, PidginMedia *gtkmedia, const gchar *sid) { - PurpleMediaManager *manager = purple_media_get_manager(media); - GstElement *pipeline = purple_media_manager_get_pipeline(manager); GtkWidget *send_widget = NULL, *recv_widget = NULL; PurpleMediaSessionType type = purple_media_get_session_type(media, sid); @@ -736,7 +704,6 @@ PURPLE_MEDIA_RECV_AUDIO), FALSE, FALSE, 0); } if (type & PURPLE_MEDIA_SEND_AUDIO) { - GstElement *media_src; GtkWidget *hbox; hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); @@ -751,10 +718,6 @@ gtk_widget_show(gtkmedia->priv->mute); gtk_widget_show(GTK_WIDGET(hbox)); - media_src = purple_media_get_src(media, sid); - gtkmedia->priv->send_level = gst_bin_get_by_name( - GST_BIN(media_src), "sendlevel"); - gtk_box_pack_end(GTK_BOX(send_widget), pidgin_media_add_audio_widget(gtkmedia, PURPLE_MEDIA_SEND_AUDIO), FALSE, FALSE, 0); @@ -763,11 +726,11 @@ } - if (type & PURPLE_MEDIA_AUDIO) { - GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); - g_signal_connect(G_OBJECT(bus), "message::element", - G_CALLBACK(level_message_cb), gtkmedia); - gst_object_unref(bus); + if (type & PURPLE_MEDIA_AUDIO && + gtkmedia->priv->level_handler_id == 0) { + gtkmedia->priv->level_handler_id = g_signal_connect( + media, "level", G_CALLBACK(level_message_cb), + gtkmedia); } if (send_widget != NULL) @@ -802,25 +765,6 @@ } else if (state == PURPLE_MEDIA_STATE_NEW && sid != NULL && name != NULL) { pidgin_media_ready_cb(media, gtkmedia, sid); - } else if (state == PURPLE_MEDIA_STATE_CONNECTED && - purple_media_get_session_type(media, sid) & - PURPLE_MEDIA_RECV_AUDIO) { - GstElement *tee = purple_media_get_tee(media, sid, name); - GstIterator *iter = gst_element_iterate_src_pads(tee); - GstPad *sinkpad; - if (gst_iterator_next(iter, (gpointer)&sinkpad) - == GST_ITERATOR_OK) { - GstPad *peer = gst_pad_get_peer(sinkpad); - if (peer != NULL) { - gtkmedia->priv->recv_level = - gst_bin_get_by_name( - GST_BIN(GST_OBJECT_PARENT( - peer)), "recvlevel"); - gst_object_unref(peer); - } - gst_object_unref(sinkpad); - } - gst_iterator_free(iter); } } @@ -1016,11 +960,7 @@ create_default_audio_src(PurpleMedia *media, const gchar *session_id, const gchar *participant) { - GstElement *bin, *src, *volume, *level; - GstPad *pad, *ghost; - double input_volume = purple_prefs_get_int( - "/pidgin/media/audio/volume/input")/10.0; - + GstElement *src; src = gst_element_factory_make("gconfaudiosrc", NULL); if (src == NULL) src = gst_element_factory_make("autoaudiosrc", NULL); @@ -1035,31 +975,15 @@ "element for the default audio source.\n"); return NULL; } - - bin = gst_bin_new("pidgindefaultaudiosrc"); - volume = gst_element_factory_make("volume", "purpleaudioinputvolume"); - g_object_set(volume, "volume", input_volume, NULL); - level = gst_element_factory_make("level", "sendlevel"); - gst_bin_add_many(GST_BIN(bin), src, volume, level, NULL); - gst_element_link(src, volume); - gst_element_link(volume, level); - pad = gst_element_get_pad(level, "src"); - ghost = gst_ghost_pad_new("ghostsrc", pad); - gst_element_add_pad(bin, ghost); - g_object_set(G_OBJECT(level), "message", TRUE, NULL); - - return bin; + gst_element_set_name(src, "pidgindefaultaudiosrc"); + return src; } static GstElement * create_default_audio_sink(PurpleMedia *media, const gchar *session_id, const gchar *participant) { - GstElement *bin, *sink, *volume, *level, *queue; - GstPad *pad, *ghost; - double output_volume = purple_prefs_get_int( - "/pidgin/media/audio/volume/output")/10.0; - + GstElement *sink; sink = gst_element_factory_make("gconfaudiosink", NULL); if (sink == NULL) sink = gst_element_factory_make("autoaudiosink",NULL); @@ -1068,22 +992,7 @@ "element for the default audio sink.\n"); return NULL; } - - bin = gst_bin_new("pidginrecvaudiobin"); - volume = gst_element_factory_make("volume", "purpleaudiooutputvolume"); - g_object_set(volume, "volume", output_volume, NULL); - level = gst_element_factory_make("level", "recvlevel"); - queue = gst_element_factory_make("queue", NULL); - gst_bin_add_many(GST_BIN(bin), sink, volume, level, queue, NULL); - gst_element_link(level, sink); - gst_element_link(volume, level); - gst_element_link(queue, volume); - pad = gst_element_get_pad(queue, "sink"); - ghost = gst_ghost_pad_new("ghostsink", pad); - gst_element_add_pad(bin, ghost); - g_object_set(G_OBJECT(level), "message", TRUE, NULL); - - return bin; + return sink; } #endif /* USE_VV */ @@ -1142,12 +1051,6 @@ purple_media_manager_set_active_element(manager, default_video_sink); purple_media_manager_set_active_element(manager, default_audio_src); purple_media_manager_set_active_element(manager, default_audio_sink); - - purple_prefs_add_none("/pidgin/media"); - purple_prefs_add_none("/pidgin/media/audio"); - purple_prefs_add_none("/pidgin/media/audio/volume"); - purple_prefs_add_int("/pidgin/media/audio/volume/input", 10); - purple_prefs_add_int("/pidgin/media/audio/volume/output", 10); #endif }