comparison pidgin/gtkmedia.c @ 28191: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 584fa66dfb31
children 47a356df8b5a
comparison
equal deleted inserted replaced
28190:9824572dbb49 28191:c8ff0a9cf8cc
82 { 82 {
83 PurpleMedia *media; 83 PurpleMedia *media;
84 gchar *screenname; 84 gchar *screenname;
85 GstElement *send_level; 85 GstElement *send_level;
86 GstElement *recv_level; 86 GstElement *recv_level;
87 gulong level_handler_id;
87 88
88 GtkItemFactory *item_factory; 89 GtkItemFactory *item_factory;
89 GtkWidget *menubar; 90 GtkWidget *menubar;
90 GtkWidget *statusbar; 91 GtkWidget *statusbar;
91 92
336 337
337 g_signal_connect(G_OBJECT(media), "delete-event", 338 g_signal_connect(G_OBJECT(media), "delete-event",
338 G_CALLBACK(pidgin_media_delete_event_cb), media); 339 G_CALLBACK(pidgin_media_delete_event_cb), media);
339 } 340 }
340 341
341 static gboolean 342 static void
342 level_message_cb(GstBus *bus, GstMessage *message, PidginMedia *gtkmedia) 343 level_message_cb(PurpleMedia *media, gchar *session_id, gchar *participant,
343 { 344 double level, PidginMedia *gtkmedia)
344 gdouble rms_db; 345 {
345 gdouble percent;
346 const GValue *list;
347 const GValue *value;
348
349 GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(message));
350 GtkWidget *progress; 346 GtkWidget *progress;
351 347 if (participant == NULL)
352 if (message->type != GST_MESSAGE_ELEMENT)
353 return TRUE;
354
355 if (!gst_structure_has_name(
356 gst_message_get_structure(message), "level"))
357 return TRUE;
358
359 if (src == gtkmedia->priv->send_level)
360 progress = gtkmedia->priv->send_progress; 348 progress = gtkmedia->priv->send_progress;
361 else if (src == gtkmedia->priv->recv_level) 349 else
362 progress = gtkmedia->priv->recv_progress; 350 progress = gtkmedia->priv->recv_progress;
363 else 351 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), level);
364 return TRUE;
365
366 list = gst_structure_get_value(
367 gst_message_get_structure(message), "rms");
368
369 /* Only bother with the first channel. */
370 value = gst_value_list_get_value(list, 0);
371 rms_db = g_value_get_double(value);
372
373 percent = pow(10, rms_db / 20) * 5;
374
375 if(percent > 1.0)
376 percent = 1.0;
377
378 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), percent);
379 return TRUE;
380 } 352 }
381 353
382 354
383 static void 355 static void
384 pidgin_media_disconnect_levels(PurpleMedia *media, PidginMedia *gtkmedia) 356 pidgin_media_disconnect_levels(PurpleMedia *media, PidginMedia *gtkmedia)
563 #else 535 #else
564 pidgin_media_input_volume_changed(GtkRange *range, PurpleMedia *media) 536 pidgin_media_input_volume_changed(GtkRange *range, PurpleMedia *media)
565 { 537 {
566 double val = (double)gtk_range_get_value(GTK_RANGE(range)); 538 double val = (double)gtk_range_get_value(GTK_RANGE(range));
567 #endif 539 #endif
568 purple_prefs_set_int("/pidgin/media/audio/volume/input", val); 540 purple_media_set_input_volume(media, NULL, val);
569 purple_media_set_input_volume(media, NULL, val / 10.0);
570 } 541 }
571 542
572 static void 543 static void
573 #if GTK_CHECK_VERSION(2,12,0) 544 #if GTK_CHECK_VERSION(2,12,0)
574 pidgin_media_output_volume_changed(GtkScaleButton *range, double value, 545 pidgin_media_output_volume_changed(GtkScaleButton *range, double value,
578 #else 549 #else
579 pidgin_media_output_volume_changed(GtkRange *range, PurpleMedia *media) 550 pidgin_media_output_volume_changed(GtkRange *range, PurpleMedia *media)
580 { 551 {
581 double val = (double)gtk_range_get_value(GTK_RANGE(range)); 552 double val = (double)gtk_range_get_value(GTK_RANGE(range));
582 #endif 553 #endif
583 purple_prefs_set_int("/pidgin/media/audio/volume/output", val); 554 purple_media_set_output_volume(media, NULL, NULL, val);
584 purple_media_set_output_volume(media, NULL, NULL, val / 10.0);
585 } 555 }
586 556
587 static GtkWidget * 557 static GtkWidget *
588 pidgin_media_add_audio_widget(PidginMedia *gtkmedia, 558 pidgin_media_add_audio_widget(PidginMedia *gtkmedia,
589 PurpleMediaSessionType type) 559 PurpleMediaSessionType type)
591 GtkWidget *volume_widget, *progress_parent, *volume, *progress; 561 GtkWidget *volume_widget, *progress_parent, *volume, *progress;
592 double value; 562 double value;
593 563
594 if (type & PURPLE_MEDIA_SEND_AUDIO) { 564 if (type & PURPLE_MEDIA_SEND_AUDIO) {
595 value = purple_prefs_get_int( 565 value = purple_prefs_get_int(
596 "/pidgin/media/audio/volume/input"); 566 "/purple/media/audio/volume/input");
597 } else if (type & PURPLE_MEDIA_RECV_AUDIO) { 567 } else if (type & PURPLE_MEDIA_RECV_AUDIO) {
598 value = purple_prefs_get_int( 568 value = purple_prefs_get_int(
599 "/pidgin/media/audio/volume/output"); 569 "/purple/media/audio/volume/output");
600 } else 570 } else
601 g_return_val_if_reached(NULL); 571 g_return_val_if_reached(NULL);
602 572
603 #if GTK_CHECK_VERSION(2,12,0) 573 #if GTK_CHECK_VERSION(2,12,0)
604 /* Setup widget structure */ 574 /* Setup widget structure */
649 } 619 }
650 620
651 static void 621 static void
652 pidgin_media_ready_cb(PurpleMedia *media, PidginMedia *gtkmedia, const gchar *sid) 622 pidgin_media_ready_cb(PurpleMedia *media, PidginMedia *gtkmedia, const gchar *sid)
653 { 623 {
654 PurpleMediaManager *manager = purple_media_get_manager(media);
655 GstElement *pipeline = purple_media_manager_get_pipeline(manager);
656 GtkWidget *send_widget = NULL, *recv_widget = NULL; 624 GtkWidget *send_widget = NULL, *recv_widget = NULL;
657 PurpleMediaSessionType type = 625 PurpleMediaSessionType type =
658 purple_media_get_session_type(media, sid); 626 purple_media_get_session_type(media, sid);
659 627
660 if (gtkmedia->priv->recv_widget == NULL 628 if (gtkmedia->priv->recv_widget == NULL
734 gtk_box_pack_end(GTK_BOX(recv_widget), 702 gtk_box_pack_end(GTK_BOX(recv_widget),
735 pidgin_media_add_audio_widget(gtkmedia, 703 pidgin_media_add_audio_widget(gtkmedia,
736 PURPLE_MEDIA_RECV_AUDIO), FALSE, FALSE, 0); 704 PURPLE_MEDIA_RECV_AUDIO), FALSE, FALSE, 0);
737 } 705 }
738 if (type & PURPLE_MEDIA_SEND_AUDIO) { 706 if (type & PURPLE_MEDIA_SEND_AUDIO) {
739 GstElement *media_src;
740 GtkWidget *hbox; 707 GtkWidget *hbox;
741 708
742 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); 709 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
743 gtk_box_pack_end(GTK_BOX(send_widget), hbox, FALSE, FALSE, 0); 710 gtk_box_pack_end(GTK_BOX(send_widget), hbox, FALSE, FALSE, 0);
744 gtkmedia->priv->mute = 711 gtkmedia->priv->mute =
749 gtk_box_pack_end(GTK_BOX(hbox), gtkmedia->priv->mute, 716 gtk_box_pack_end(GTK_BOX(hbox), gtkmedia->priv->mute,
750 FALSE, FALSE, 0); 717 FALSE, FALSE, 0);
751 gtk_widget_show(gtkmedia->priv->mute); 718 gtk_widget_show(gtkmedia->priv->mute);
752 gtk_widget_show(GTK_WIDGET(hbox)); 719 gtk_widget_show(GTK_WIDGET(hbox));
753 720
754 media_src = purple_media_get_src(media, sid);
755 gtkmedia->priv->send_level = gst_bin_get_by_name(
756 GST_BIN(media_src), "sendlevel");
757
758 gtk_box_pack_end(GTK_BOX(send_widget), 721 gtk_box_pack_end(GTK_BOX(send_widget),
759 pidgin_media_add_audio_widget(gtkmedia, 722 pidgin_media_add_audio_widget(gtkmedia,
760 PURPLE_MEDIA_SEND_AUDIO), FALSE, FALSE, 0); 723 PURPLE_MEDIA_SEND_AUDIO), FALSE, FALSE, 0);
761 724
762 gtk_widget_show(gtkmedia->priv->mute); 725 gtk_widget_show(gtkmedia->priv->mute);
763 } 726 }
764 727
765 728
766 if (type & PURPLE_MEDIA_AUDIO) { 729 if (type & PURPLE_MEDIA_AUDIO &&
767 GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); 730 gtkmedia->priv->level_handler_id == 0) {
768 g_signal_connect(G_OBJECT(bus), "message::element", 731 gtkmedia->priv->level_handler_id = g_signal_connect(
769 G_CALLBACK(level_message_cb), gtkmedia); 732 media, "level", G_CALLBACK(level_message_cb),
770 gst_object_unref(bus); 733 gtkmedia);
771 } 734 }
772 735
773 if (send_widget != NULL) 736 if (send_widget != NULL)
774 gtkmedia->priv->send_widget = send_widget; 737 gtkmedia->priv->send_widget = send_widget;
775 if (recv_widget != NULL) 738 if (recv_widget != NULL)
800 gtk_widget_destroy(GTK_WIDGET(gtkmedia)); 763 gtk_widget_destroy(GTK_WIDGET(gtkmedia));
801 } 764 }
802 } else if (state == PURPLE_MEDIA_STATE_NEW && 765 } else if (state == PURPLE_MEDIA_STATE_NEW &&
803 sid != NULL && name != NULL) { 766 sid != NULL && name != NULL) {
804 pidgin_media_ready_cb(media, gtkmedia, sid); 767 pidgin_media_ready_cb(media, gtkmedia, sid);
805 } else if (state == PURPLE_MEDIA_STATE_CONNECTED &&
806 purple_media_get_session_type(media, sid) &
807 PURPLE_MEDIA_RECV_AUDIO) {
808 GstElement *tee = purple_media_get_tee(media, sid, name);
809 GstIterator *iter = gst_element_iterate_src_pads(tee);
810 GstPad *sinkpad;
811 if (gst_iterator_next(iter, (gpointer)&sinkpad)
812 == GST_ITERATOR_OK) {
813 GstPad *peer = gst_pad_get_peer(sinkpad);
814 if (peer != NULL) {
815 gtkmedia->priv->recv_level =
816 gst_bin_get_by_name(
817 GST_BIN(GST_OBJECT_PARENT(
818 peer)), "recvlevel");
819 gst_object_unref(peer);
820 }
821 gst_object_unref(sinkpad);
822 }
823 gst_iterator_free(iter);
824 } 768 }
825 } 769 }
826 770
827 static void 771 static void
828 pidgin_media_stream_info_cb(PurpleMedia *media, PurpleMediaInfoType type, 772 pidgin_media_stream_info_cb(PurpleMedia *media, PurpleMediaInfoType type,
1014 958
1015 static GstElement * 959 static GstElement *
1016 create_default_audio_src(PurpleMedia *media, 960 create_default_audio_src(PurpleMedia *media,
1017 const gchar *session_id, const gchar *participant) 961 const gchar *session_id, const gchar *participant)
1018 { 962 {
1019 GstElement *bin, *src, *volume, *level; 963 GstElement *src;
1020 GstPad *pad, *ghost;
1021 double input_volume = purple_prefs_get_int(
1022 "/pidgin/media/audio/volume/input")/10.0;
1023
1024 src = gst_element_factory_make("gconfaudiosrc", NULL); 964 src = gst_element_factory_make("gconfaudiosrc", NULL);
1025 if (src == NULL) 965 if (src == NULL)
1026 src = gst_element_factory_make("autoaudiosrc", NULL); 966 src = gst_element_factory_make("autoaudiosrc", NULL);
1027 if (src == NULL) 967 if (src == NULL)
1028 src = gst_element_factory_make("alsasrc", NULL); 968 src = gst_element_factory_make("alsasrc", NULL);
1033 if (src == NULL) { 973 if (src == NULL) {
1034 purple_debug_error("gtkmedia", "Unable to find a suitable " 974 purple_debug_error("gtkmedia", "Unable to find a suitable "
1035 "element for the default audio source.\n"); 975 "element for the default audio source.\n");
1036 return NULL; 976 return NULL;
1037 } 977 }
1038 978 gst_element_set_name(src, "pidgindefaultaudiosrc");
1039 bin = gst_bin_new("pidgindefaultaudiosrc"); 979 return src;
1040 volume = gst_element_factory_make("volume", "purpleaudioinputvolume");
1041 g_object_set(volume, "volume", input_volume, NULL);
1042 level = gst_element_factory_make("level", "sendlevel");
1043 gst_bin_add_many(GST_BIN(bin), src, volume, level, NULL);
1044 gst_element_link(src, volume);
1045 gst_element_link(volume, level);
1046 pad = gst_element_get_pad(level, "src");
1047 ghost = gst_ghost_pad_new("ghostsrc", pad);
1048 gst_element_add_pad(bin, ghost);
1049 g_object_set(G_OBJECT(level), "message", TRUE, NULL);
1050
1051 return bin;
1052 } 980 }
1053 981
1054 static GstElement * 982 static GstElement *
1055 create_default_audio_sink(PurpleMedia *media, 983 create_default_audio_sink(PurpleMedia *media,
1056 const gchar *session_id, const gchar *participant) 984 const gchar *session_id, const gchar *participant)
1057 { 985 {
1058 GstElement *bin, *sink, *volume, *level, *queue; 986 GstElement *sink;
1059 GstPad *pad, *ghost;
1060 double output_volume = purple_prefs_get_int(
1061 "/pidgin/media/audio/volume/output")/10.0;
1062
1063 sink = gst_element_factory_make("gconfaudiosink", NULL); 987 sink = gst_element_factory_make("gconfaudiosink", NULL);
1064 if (sink == NULL) 988 if (sink == NULL)
1065 sink = gst_element_factory_make("autoaudiosink",NULL); 989 sink = gst_element_factory_make("autoaudiosink",NULL);
1066 if (sink == NULL) { 990 if (sink == NULL) {
1067 purple_debug_error("gtkmedia", "Unable to find a suitable " 991 purple_debug_error("gtkmedia", "Unable to find a suitable "
1068 "element for the default audio sink.\n"); 992 "element for the default audio sink.\n");
1069 return NULL; 993 return NULL;
1070 } 994 }
1071 995 return sink;
1072 bin = gst_bin_new("pidginrecvaudiobin");
1073 volume = gst_element_factory_make("volume", "purpleaudiooutputvolume");
1074 g_object_set(volume, "volume", output_volume, NULL);
1075 level = gst_element_factory_make("level", "recvlevel");
1076 queue = gst_element_factory_make("queue", NULL);
1077 gst_bin_add_many(GST_BIN(bin), sink, volume, level, queue, NULL);
1078 gst_element_link(level, sink);
1079 gst_element_link(volume, level);
1080 gst_element_link(queue, volume);
1081 pad = gst_element_get_pad(queue, "sink");
1082 ghost = gst_ghost_pad_new("ghostsink", pad);
1083 gst_element_add_pad(bin, ghost);
1084 g_object_set(G_OBJECT(level), "message", TRUE, NULL);
1085
1086 return bin;
1087 } 996 }
1088 #endif /* USE_VV */ 997 #endif /* USE_VV */
1089 998
1090 void 999 void
1091 pidgin_medias_init(void) 1000 pidgin_medias_init(void)
1140 purple_debug_info("gtkmedia", "Registering media element types\n"); 1049 purple_debug_info("gtkmedia", "Registering media element types\n");
1141 purple_media_manager_set_active_element(manager, default_video_src); 1050 purple_media_manager_set_active_element(manager, default_video_src);
1142 purple_media_manager_set_active_element(manager, default_video_sink); 1051 purple_media_manager_set_active_element(manager, default_video_sink);
1143 purple_media_manager_set_active_element(manager, default_audio_src); 1052 purple_media_manager_set_active_element(manager, default_audio_src);
1144 purple_media_manager_set_active_element(manager, default_audio_sink); 1053 purple_media_manager_set_active_element(manager, default_audio_sink);
1145
1146 purple_prefs_add_none("/pidgin/media");
1147 purple_prefs_add_none("/pidgin/media/audio");
1148 purple_prefs_add_none("/pidgin/media/audio/volume");
1149 purple_prefs_add_int("/pidgin/media/audio/volume/input", 10);
1150 purple_prefs_add_int("/pidgin/media/audio/volume/output", 10);
1151 #endif 1054 #endif
1152 } 1055 }
1153 1056