aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2010-03-17 21:57:35 +0100
committerMax Kellermann <max@duempel.org>2010-03-17 23:14:54 +0100
commitcbfaa4a2662c55d7ad6339d70b3665d066bf491a (patch)
treebef857f6c2b113aee6f54967972e8b2d2aee7579
parent2e72a9b262ac71a8a7e8ed9b00efa80597d5f17d (diff)
downloadmpd-cbfaa4a2662c55d7ad6339d70b3665d066bf491a.tar.gz
mpd-cbfaa4a2662c55d7ad6339d70b3665d066bf491a.tar.xz
mpd-cbfaa4a2662c55d7ad6339d70b3665d066bf491a.zip
player_thread: postpone song tags during cross-fade
Previously, tags of the new song being cross-faded in were sent immediately. That can cause wrong information being displayed, because the "previous" song might send its tag at the end again, overriding the "next" song's tag. This patch saves & merges the tag of the next song, and sends it when cross-fading is finished, and the next song really starts.
Diffstat (limited to '')
-rw-r--r--NEWS1
-rw-r--r--src/player_thread.c27
2 files changed, 28 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 04fa38936..c2c9817ee 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ ver 0.15.9 (2009/??/??)
- mad: fix crash when seeking at end of song
- mpcdec: fix negative shift on fixed-point samples
* playlist: fix single+repeat in random mode
+* player: postpone song tags during cross-fade
ver 0.15.8 (2010/01/17)
diff --git a/src/player_thread.c b/src/player_thread.c
index 7fc55d3d1..e2c9b6f93 100644
--- a/src/player_thread.c
+++ b/src/player_thread.c
@@ -90,6 +90,13 @@ struct player {
unsigned cross_fade_chunks;
/**
+ * The tag of the "next" song during cross-fade. It is
+ * postponed, and sent to the output thread when the new song
+ * really begins.
+ */
+ struct tag *cross_fade_tag;
+
+ /**
* The current audio format for the audio outputs.
*/
struct audio_format play_audio_format;
@@ -518,6 +525,14 @@ play_next_chunk(struct player *player)
chunk = music_pipe_shift(player->pipe);
assert(chunk != NULL);
+ /* don't send the tags of the new song (which
+ is being faded in) yet; postpone it until
+ the current song is faded out */
+ player->cross_fade_tag =
+ tag_merge_replace(player->cross_fade_tag,
+ other_chunk->tag);
+ other_chunk->tag = NULL;
+
cross_fade_apply(chunk, other_chunk,
&dc.out_audio_format,
cross_fade_position,
@@ -544,6 +559,14 @@ play_next_chunk(struct player *player)
assert(chunk != NULL);
+ /* insert the postponed tag if cross-fading is finished */
+
+ if (player->xfade != XFADE_ENABLED && player->cross_fade_tag != NULL) {
+ chunk->tag = tag_merge_replace(chunk->tag,
+ player->cross_fade_tag);
+ player->cross_fade_tag = NULL;
+ }
+
/* play the current chunk */
success = play_chunk(player->song, chunk, &player->play_audio_format,
@@ -608,6 +631,7 @@ static void do_play(void)
.xfade = XFADE_UNKNOWN,
.cross_fading = false,
.cross_fade_chunks = 0,
+ .cross_fade_tag = NULL,
.size_to_time = 0.0,
};
@@ -754,6 +778,9 @@ static void do_play(void)
music_pipe_clear(player.pipe, player_buffer);
music_pipe_free(player.pipe);
+ if (player.cross_fade_tag != NULL)
+ tag_free(player.cross_fade_tag);
+
pc.state = PLAYER_STATE_STOP;
event_pipe_emit(PIPE_EVENT_PLAYLIST);
}