/** * gst_stream_volume_set_mute: * @volume: #GstStreamVolume that should be used * @mute: Mute state that should be set */ void gst_stream_volume_set_mute (GstStreamVolume * volume, gboolean mute) { g_return_if_fail (GST_IS_STREAM_VOLUME (volume)); g_object_set (volume, "mute", mute, NULL); }
/** * gst_stream_volume_get_mute: * @volume: #GstStreamVolume that should be used * * Returns: Returns %TRUE if the stream is muted */ gboolean gst_stream_volume_get_mute (GstStreamVolume * volume) { gboolean val; g_return_val_if_fail (GST_IS_STREAM_VOLUME (volume), FALSE); g_object_get (volume, "mute", &val, NULL); return val; }
/** * gst_stream_volume_set_volume: * @volume: #GstStreamVolume that should be used * @format: #GstStreamVolumeFormat of @val * @val: Linear volume factor that should be set */ void gst_stream_volume_set_volume (GstStreamVolume * volume, GstStreamVolumeFormat format, gdouble val) { g_return_if_fail (GST_IS_STREAM_VOLUME (volume)); if (format != GST_STREAM_VOLUME_FORMAT_LINEAR) val = gst_stream_volume_convert_volume (format, GST_STREAM_VOLUME_FORMAT_LINEAR, val); g_object_set (volume, "volume", val, NULL); }
static void set_playbin_volume (RBPlayerGst *player, float volume) { /* ignore the deep-notify we get directly from the sink, as it causes deadlock. * we still get another one anyway. */ g_signal_handlers_block_by_func (player->priv->playbin, volume_notify_cb, player); if (GST_IS_STREAM_VOLUME (player->priv->playbin)) gst_stream_volume_set_volume (GST_STREAM_VOLUME (player->priv->playbin), GST_STREAM_VOLUME_FORMAT_CUBIC, volume); else g_object_set (player->priv->playbin, "volume", volume, NULL); g_signal_handlers_unblock_by_func (player->priv->playbin, volume_notify_cb, player); }
/** * gst_stream_volume_get_volume: * @volume: #GstStreamVolume that should be used * @format: #GstStreamVolumeFormat which should be returned * * Returns: The current stream volume as linear factor */ gdouble gst_stream_volume_get_volume (GstStreamVolume * volume, GstStreamVolumeFormat format) { gdouble val; g_return_val_if_fail (GST_IS_STREAM_VOLUME (volume), 1.0); g_object_get (volume, "volume", &val, NULL); if (format != GST_STREAM_VOLUME_FORMAT_LINEAR) val = gst_stream_volume_convert_volume (GST_STREAM_VOLUME_FORMAT_LINEAR, format, val); return val; }
static gboolean emit_volume_changed_idle (RBPlayerGst *player) { double vol; if (GST_IS_STREAM_VOLUME (player->priv->playbin)) { vol = gst_stream_volume_get_volume (GST_STREAM_VOLUME (player->priv->playbin), GST_STREAM_VOLUME_FORMAT_CUBIC); } else { vol = player->priv->cur_volume; } _rb_player_emit_volume_changed (RB_PLAYER (player), vol); return FALSE; }
static GstPad * empathy_audio_sink_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar* name) { EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (element); GstElement *bin, *resample, *audioconvert0, *audioconvert1; GstPad *pad = NULL; GstPad *subpad, *filterpad; bin = gst_bin_new (NULL); audioconvert0 = gst_element_factory_make ("audioconvert", NULL); if (audioconvert0 == NULL) goto error; gst_bin_add (GST_BIN (bin), audioconvert0); resample = gst_element_factory_make ("audioresample", NULL); if (resample == NULL) goto error; gst_bin_add (GST_BIN (bin), resample); audioconvert1 = gst_element_factory_make ("audioconvert", NULL); if (audioconvert1 == NULL) goto error; gst_bin_add (GST_BIN (bin), audioconvert1); self->priv->sink = create_sink (self); if (self->priv->sink == NULL) goto error; if (GST_IS_STREAM_VOLUME (self->priv->sink)) { g_static_mutex_lock (&self->priv->volume_mutex); if (self->priv->volume_idle_id == 0) self->priv->volume_idle_id = g_idle_add ( empathy_audio_sink_volume_idle_setup, self); g_static_mutex_unlock (&self->priv->volume_mutex); } else { gchar *n = gst_element_get_name (self->priv->sink); DEBUG ("Element %s doesn't support volume", n); g_free (n); } gst_bin_add (GST_BIN (bin), self->priv->sink); if (!gst_element_link_many (audioconvert0, resample, audioconvert1, self->priv->sink, NULL)) goto error; filterpad = gst_element_get_static_pad (audioconvert0, "sink"); if (filterpad == NULL) goto error; subpad = gst_ghost_pad_new ("sink", filterpad); if (!gst_element_add_pad (GST_ELEMENT (bin), subpad)) goto error; gst_bin_add (GST_BIN (self), bin); pad = gst_ghost_pad_new (name, subpad); g_assert (pad != NULL); if (!gst_element_sync_state_with_parent (bin)) goto error; if (!gst_pad_set_active (pad, TRUE)) goto error; if (!gst_element_add_pad (GST_ELEMENT (self), pad)) goto error; return pad; error: if (pad != NULL) { gst_object_unref (pad); } gst_object_unref (bin); g_warning ("Failed to create output subpipeline"); return NULL; }
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; }