summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kojevnikov <alexander@kojevnikov.com>2010-09-15 12:32:41 +1000
committerAlexander Kojevnikov <alexander@kojevnikov.com>2010-09-15 12:32:41 +1000
commitc6b2f2c14406e378f42c47ce4294b228021d2ad2 (patch)
tree94f925f653d3a3ec475906d7bdb54468389bedad
parent863fd6e52fb0cf091106c5763e688392aecc3bff (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.c18
-rw-r--r--libbanshee/banshee-player-private.h1
-rw-r--r--libbanshee/banshee-player-replaygain.c6
-rw-r--r--libbanshee/banshee-player.c39
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