Mercurial > pidgin.yaz
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 |