static void
empathy_mic_menu_constructed (GObject *obj)
{
  EmpathyMicMenu *self = EMPATHY_MIC_MENU (obj);
  EmpathyMicMenuPrivate *priv = self->priv;
  GtkUIManager *ui_manager;
  EmpathyGstAudioSrc *audio;

  g_assert (EMPATHY_IS_CALL_WINDOW (priv->window));

  ui_manager = empathy_call_window_get_ui_manager (priv->window);
  audio = empathy_call_window_get_audio_src (priv->window);

  g_assert (GTK_IS_UI_MANAGER (ui_manager));
  g_assert (EMPATHY_IS_GST_AUDIO_SRC (audio));

  /* Okay let's go go go. */

  priv->mic_monitor = empathy_mic_monitor_new ();

  priv->action_group = gtk_action_group_new ("EmpathyMicMenu");
  gtk_ui_manager_insert_action_group (ui_manager, priv->action_group, -1);
  /* the UI manager now owns this */
  g_object_unref (priv->action_group);

  priv->anchor_action = g_object_new (GTK_TYPE_RADIO_ACTION,
      "name", "EmpathyMicMenuAnchorAction",
      NULL);
  gtk_action_group_add_action (priv->action_group, priv->anchor_action);
  g_object_unref (priv->anchor_action);

  priv->microphones = g_queue_new ();

  /* Don't bother with any of this if we don't support changing
   * microphone, so don't listen for microphone changes or enumerate
   * the available microphones. */
  if (!empathy_audio_src_supports_changing_mic (audio))
    return;

  tp_g_signal_connect_object (audio, "notify::microphone",
      G_CALLBACK (empathy_mic_menu_notify_microphone_cb), self, 0);
  tp_g_signal_connect_object (priv->mic_monitor, "microphone-added",
      G_CALLBACK (empathy_mic_menu_microphone_added_cb), self, 0);
  tp_g_signal_connect_object (priv->mic_monitor, "microphone-removed",
      G_CALLBACK (empathy_mic_menu_microphone_removed_cb), self, 0);

  empathy_mic_monitor_list_microphones_async (priv->mic_monitor,
      empathy_mic_menu_list_microphones_cb, self);
}
Example #2
0
static void
empathy_audio_src_init (EmpathyGstAudioSrc *obj)
{
  EmpathyGstAudioSrcPrivate *priv = EMPATHY_GST_AUDIO_SRC_GET_PRIVATE (obj);
  GstPad *ghost, *src;

  obj->priv = priv;
  g_mutex_init (&priv->lock);

  priv->volume = 1.0;

  priv->src = create_src ();
  if (priv->src == NULL)
    return;

  if (GST_IS_STREAM_VOLUME (priv->src))
    {
      gdouble volume;
      gboolean mute;

      priv->have_stream_volume = TRUE;
      /* We can't do a bidirection bind as the ::notify comes from another
       * thread, for other bits of empathy it's most simpler if it comes from
       * the main thread */
      g_object_bind_property (obj, "volume", priv->src, "volume",
        G_BINDING_DEFAULT);
      g_object_bind_property (obj, "mute", priv->src, "mute",
        G_BINDING_DEFAULT);

      /* sync and callback for bouncing */
      g_object_get (priv->src, "volume", &volume, NULL);
      g_object_set (obj, "volume", volume, NULL);

      g_object_get (priv->src, "mute", &mute, NULL);
      g_object_set (obj, "mute", mute, NULL);

      g_signal_connect (priv->src, "notify::volume",
        G_CALLBACK (empathy_audio_src_volume_changed), obj);
      g_signal_connect (priv->src, "notify::mute",
        G_CALLBACK (empathy_audio_src_volume_changed), obj);
    }
  else
    {
      g_message ("No stream volume available :(, mute will work though");
      priv->have_stream_volume = FALSE;
    }

  gst_bin_add (GST_BIN (obj), priv->src);

  priv->volume_element = gst_element_factory_make ("volume", NULL);
  gst_bin_add (GST_BIN (obj), priv->volume_element);

  {
    GstElement *capsfilter;
    GstCaps *caps;

    /* Explicitly state what format we want from pulsesrc. This pushes resampling
     * and format conversion as early as possible, lowering the amount of data
     * transferred and thus improving performance. When moving to GStreamer
     * 0.11/1.0, this should change so that we actually request what the encoder
     * wants downstream. */
    caps = gst_caps_new_simple ("audio/x-raw-int",
        "channels", G_TYPE_INT, 1,
        "width", G_TYPE_INT, 16,
        "depth", G_TYPE_INT, 16,
        "rate", G_TYPE_INT, 32000,
        NULL);
    capsfilter = gst_element_factory_make ("capsfilter", NULL);
    g_object_set (G_OBJECT (capsfilter), "caps", caps, NULL);
    gst_bin_add (GST_BIN (obj), capsfilter);
    gst_element_link (priv->src, capsfilter);
    gst_element_link (capsfilter, priv->volume_element);
  }

  src = gst_element_get_static_pad (priv->volume_element, "src");

  ghost = gst_ghost_pad_new ("src", src);
  gst_element_add_pad (GST_ELEMENT (obj), ghost);

  gst_object_unref (G_OBJECT (src));

  /* Listen to changes to GstPulseSrc:source-output-index so we know when
   * it's no longer PA_INVALID_INDEX (starting for the first time) or if it
   * changes (READY->NULL->READY...) */
  g_signal_connect (priv->src, "notify::source-output-index",
      G_CALLBACK (empathy_audio_src_source_output_index_notify),
      obj);

  priv->mic_monitor = empathy_mic_monitor_new ();
  g_signal_connect (priv->mic_monitor, "microphone-changed",
      G_CALLBACK (empathy_audio_src_microphone_changed_cb), obj);

  priv->source_idx = PA_INVALID_INDEX;
}