diff options
author | Alexander Kojevnikov <alexander@kojevnikov.com> | 2010-09-15 12:32:41 +1000 |
---|---|---|
committer | Alexander Kojevnikov <alexander@kojevnikov.com> | 2010-09-15 12:32:41 +1000 |
commit | c6b2f2c14406e378f42c47ce4294b228021d2ad2 (patch) | |
tree | 94f925f653d3a3ec475906d7bdb54468389bedad | |
parent | 863fd6e52fb0cf091106c5763e688392aecc3bff (diff) |
libbanshee: Insert `volume` element into the pipeline (bgo#6000072)
Changing the volume on the entire pipeline results in a noticeable
latency on certain audio sinks. This commit adds a dedicated volume
element, changing the volume on it drastically reduces the latency.
Original patch by Christian Taedcke, adapted by Christopher Halse Rogers
and myself.
-rw-r--r-- | libbanshee/banshee-player-pipeline.c | 18 | ||||
-rw-r--r-- | libbanshee/banshee-player-private.h | 1 | ||||
-rw-r--r-- | libbanshee/banshee-player-replaygain.c | 6 | ||||
-rw-r--r-- | libbanshee/banshee-player.c | 39 |
4 files changed, 27 insertions, 37 deletions
diff --git a/libbanshee/banshee-player-pipeline.c b/libbanshee/banshee-player-pipeline.c index 773f568fd..ce16a48f7 100644 --- a/libbanshee/banshee-player-pipeline.c +++ b/libbanshee/banshee-player-pipeline.c @@ -358,7 +358,11 @@ _bp_pipeline_construct (BansheePlayer *player) // Our audio sink is a tee, so plugins can attach their own pipelines player->audiotee = gst_element_factory_make ("tee", "audiotee"); g_return_val_if_fail (player->audiotee != NULL, FALSE); - + + // Create a volume control with low latency + player->volume = gst_element_factory_make ("volume", NULL); + g_return_val_if_fail (player->volume != NULL, FALSE); + audiosinkqueue = gst_element_factory_make ("queue", "audiosinkqueue"); g_return_val_if_fail (audiosinkqueue != NULL, FALSE); @@ -371,7 +375,7 @@ _bp_pipeline_construct (BansheePlayer *player) } // Add elements to custom audio sink - gst_bin_add_many (GST_BIN (player->audiobin), player->audiotee, audiosinkqueue, audiosink, NULL); + gst_bin_add_many (GST_BIN (player->audiobin), player->audiotee, player->volume, audiosinkqueue, audiosink, NULL); if (player->equalizer != NULL) { gst_bin_add_many (GST_BIN (player->audiobin), eq_audioconvert, eq_audioconvert2, player->equalizer, player->preamp, NULL); @@ -386,15 +390,13 @@ _bp_pipeline_construct (BansheePlayer *player) if (player->equalizer != NULL) { // link in equalizer, preamp and audioconvert. gst_element_link_many (audiosinkqueue, eq_audioconvert, player->preamp, - player->equalizer, eq_audioconvert2, audiosink, NULL); - player->before_rgvolume = eq_audioconvert; - player->after_rgvolume = player->preamp; + player->equalizer, eq_audioconvert2, player->volume, audiosink, NULL); } else { // link the queue with the real audio sink - gst_element_link (audiosinkqueue, audiosink); - player->before_rgvolume = audiosinkqueue; - player->after_rgvolume = audiosink; + gst_element_link_many (audiosinkqueue, player->volume, audiosink, NULL); } + player->before_rgvolume = player->volume; + player->after_rgvolume = audiosink; player->rgvolume_in_pipeline = FALSE; _bp_replaygain_pipeline_rebuild (player); diff --git a/libbanshee/banshee-player-private.h b/libbanshee/banshee-player-private.h index 5286daf75..f3e28a77f 100644 --- a/libbanshee/banshee-player-private.h +++ b/libbanshee/banshee-player-private.h @@ -141,6 +141,7 @@ struct BansheePlayer { gboolean rgvolume_in_pipeline; gint equalizer_status; + gdouble current_volume; // Pipeline/Playback State GMutex *video_mutex; diff --git a/libbanshee/banshee-player-replaygain.c b/libbanshee/banshee-player-replaygain.c index 43caa6b6b..a479d4a00 100644 --- a/libbanshee/banshee-player-replaygain.c +++ b/libbanshee/banshee-player-replaygain.c @@ -169,14 +169,12 @@ void _bp_rgvolume_print_volume(BansheePlayer *player) g_return_if_fail (IS_BANSHEE_PLAYER (player)); if (player->replaygain_enabled && (player->rgvolume != NULL)) { gdouble scale; - gdouble volume; g_object_get (G_OBJECT (player->rgvolume), "result-gain", &scale, NULL); - g_object_get (G_OBJECT (player->playbin), "volume", &volume, NULL); bp_debug4 ("scaled volume: %.2f (ReplayGain) * %.2f (User) = %.2f", - bp_replaygain_db_to_linear (scale), volume, - bp_replaygain_db_to_linear (scale) * volume); + bp_replaygain_db_to_linear (scale), player->current_volume, + bp_replaygain_db_to_linear (scale) * player->current_volume); } } diff --git a/libbanshee/banshee-player.c b/libbanshee/banshee-player.c index 0c1c1ac76..ef15efd30 100644 --- a/libbanshee/banshee-player.c +++ b/libbanshee/banshee-player.c @@ -275,39 +275,28 @@ bp_audiosink_has_volume (BansheePlayer *player) P_INVOKE void bp_set_volume (BansheePlayer *player, gdouble volume) { + GParamSpec *volume_spec; + GValue value = { 0, }; + g_return_if_fail (IS_BANSHEE_PLAYER (player)); - g_return_if_fail (GST_IS_ELEMENT (player->playbin)); - - if (bp_supports_stream_volume (player)) { - #if BANSHEE_CHECK_GST_VERSION(0,10,25) - gst_stream_volume_set_volume (GST_STREAM_VOLUME (player->playbin), - GST_STREAM_VOLUME_FORMAT_CUBIC, volume); - #endif - } else { - g_object_set (player->playbin, "volume", CLAMP (volume, 0.0, 1.0), NULL); - } + g_return_if_fail (GST_IS_ELEMENT(player->volume)); + + player->current_volume = CLAMP (volume, 0.0, 1.0); + volume_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (player->volume), "volume"); + g_value_init (&value, G_TYPE_DOUBLE); + g_value_set_double (&value, player->current_volume); + g_param_value_validate (volume_spec, &value); - _bp_rgvolume_print_volume (player); + g_object_set_property (G_OBJECT (player->volume), "volume", &value); + g_value_unset (&value); + _bp_rgvolume_print_volume(player); } P_INVOKE gdouble bp_get_volume (BansheePlayer *player) { - gdouble volume; - g_return_val_if_fail (IS_BANSHEE_PLAYER (player), 0.0); - g_return_val_if_fail (GST_IS_ELEMENT (player->playbin), 0.0); - - if (bp_supports_stream_volume (player)) { - #if BANSHEE_CHECK_GST_VERSION(0,10,25) - volume = gst_stream_volume_get_volume (GST_STREAM_VOLUME (player->playbin), - GST_STREAM_VOLUME_FORMAT_CUBIC); - #endif - } else { - g_object_get (player->playbin, "volume", &volume, NULL); - } - - return volume; + return player->current_volume; } P_INVOKE void |