From 4459a46181549b54dbf40cbe891b019c7793601a Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Mon, 9 Mar 2009 19:14:06 +0100
Subject: player_thread: moved code to play_next_chunk()

Moved some cruft out of do_play().
---
 src/player_thread.c | 176 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 103 insertions(+), 73 deletions(-)

diff --git a/src/player_thread.c b/src/player_thread.c
index f42b74a1f..9b9787261 100644
--- a/src/player_thread.c
+++ b/src/player_thread.c
@@ -78,6 +78,16 @@ struct player {
 	 */
 	enum xfade_state xfade;
 
+	/**
+	 * has cross-fading begun?
+	 */
+	bool cross_fading;
+
+	/**
+	 * The number of chunks used for crossfading.
+	 */
+	unsigned cross_fade_chunks;
+
 	/**
 	 * The current audio format for the audio outputs.
 	 */
@@ -364,6 +374,91 @@ play_chunk(struct song *song, struct music_chunk *chunk,
 	return true;
 }
 
+/**
+ * Obtains the next chunk from the music pipe, optionally applies
+ * cross-fading, and sends it to all audio outputs.
+ *
+ * @return true on success, false on error (playback will be stopped)
+ */
+static bool
+play_next_chunk(struct player *player)
+{
+	struct music_chunk *chunk = NULL;
+	unsigned cross_fade_position;
+	bool success;
+
+	if (player->xfade == XFADE_ENABLED &&
+	    dc.pipe != NULL && dc.pipe != player->pipe &&
+	    (cross_fade_position = music_pipe_size(player->pipe))
+	    <= player->cross_fade_chunks) {
+		/* perform cross fade */
+		struct music_chunk *other_chunk =
+			music_pipe_shift(dc.pipe);
+
+		if (!player->cross_fading) {
+			/* beginning of the cross fade
+			   - adjust crossFadeChunks
+			   which might be bigger than
+			   the remaining number of
+			   chunks in the old song */
+			player->cross_fade_chunks = cross_fade_position;
+			player->cross_fading = true;
+		}
+
+		if (other_chunk != NULL) {
+			chunk = music_pipe_shift(player->pipe);
+			assert(chunk != NULL);
+
+			cross_fade_apply(chunk, other_chunk,
+					 &dc.out_audio_format,
+					 cross_fade_position,
+					 player->cross_fade_chunks);
+			music_buffer_return(player_buffer, other_chunk);
+		} else {
+			/* there are not enough
+			   decoded chunks yet */
+			if (decoder_is_idle()) {
+				/* the decoder isn't
+				   running, abort
+				   cross fading */
+				player->xfade = XFADE_DISABLED;
+			} else {
+				/* wait for the
+				   decoder */
+				notify_signal(&dc.notify);
+				notify_wait(&pc.notify);
+
+				return true;
+			}
+		}
+	}
+
+	if (chunk == NULL)
+		chunk = music_pipe_shift(player->pipe);
+
+	assert(chunk != NULL);
+
+	/* play the current chunk */
+
+	success = play_chunk(player->song, chunk, &player->play_audio_format,
+			     player->size_to_time);
+	music_buffer_return(player_buffer, chunk);
+
+	if (!success)
+		return false;
+
+	/* this formula should prevent that the
+	   decoder gets woken up with each chunk; it
+	   is more efficient to make it decode a
+	   larger block at a time */
+	if (!decoder_is_idle() &&
+	    music_pipe_size(dc.pipe) <= (pc.buffered_before_play +
+					 music_buffer_size(player_buffer) * 3) / 4)
+		notify_signal(&dc.notify);
+
+	return true;
+}
+
 static void do_play(void)
 {
 	struct player player = {
@@ -373,11 +468,10 @@ static void do_play(void)
 		.queued = false,
 		.song = NULL,
 		.xfade = XFADE_UNKNOWN,
+		.cross_fading = false,
+		.cross_fade_chunks = 0,
 		.size_to_time = 0.0,
 	};
-	unsigned int crossFadeChunks = 0;
-	/** has cross-fading begun? */
-	bool cross_fading = false;
 	static const char silence[CHUNK_SIZE];
 
 	player.pipe = music_pipe_new();
@@ -452,15 +546,15 @@ static void do_play(void)
 			/* enable cross fading in this song?  if yes,
 			   calculate how many chunks will be required
 			   for it */
-			crossFadeChunks =
+			player.cross_fade_chunks =
 				cross_fade_calc(pc.cross_fade_seconds, dc.total_time,
 						&dc.out_audio_format,
 						&player.play_audio_format,
 						music_buffer_size(player_buffer) -
 						pc.buffered_before_play);
-			if (crossFadeChunks > 0) {
+			if (player.cross_fade_chunks > 0) {
 				player.xfade = XFADE_ENABLED;
-				cross_fading = false;
+				player.cross_fading = false;
 			} else
 				/* cross fading is disabled or the
 				   next song is too short */
@@ -470,75 +564,11 @@ static void do_play(void)
 		if (player.paused)
 			notify_wait(&pc.notify);
 		else if (music_pipe_size(player.pipe) > 0) {
-			struct music_chunk *chunk = NULL;
-			unsigned int fadePosition;
-			bool success;
-
-			if (player.xfade == XFADE_ENABLED &&
-			    dc.pipe != NULL && dc.pipe != player.pipe &&
-			    (fadePosition = music_pipe_size(player.pipe))
-			    <= crossFadeChunks) {
-				/* perform cross fade */
-				struct music_chunk *other_chunk =
-					music_pipe_shift(dc.pipe);
-
-				if (!cross_fading) {
-					/* beginning of the cross fade
-					   - adjust crossFadeChunks
-					   which might be bigger than
-					   the remaining number of
-					   chunks in the old song */
-					crossFadeChunks = fadePosition;
-					cross_fading = true;
-				}
-
-				if (other_chunk != NULL) {
-					chunk = music_pipe_shift(player.pipe);
-					cross_fade_apply(chunk, other_chunk,
-							 &dc.out_audio_format,
-							 fadePosition,
-							 crossFadeChunks);
-					music_buffer_return(player_buffer, other_chunk);
-				} else {
-					/* there are not enough
-					   decoded chunks yet */
-					if (decoder_is_idle()) {
-						/* the decoder isn't
-						   running, abort
-						   cross fading */
-						player.xfade = XFADE_DISABLED;
-					} else {
-						/* wait for the
-						   decoder */
-						notify_signal(&dc.notify);
-						notify_wait(&pc.notify);
-
-						continue;
-					}
-				}
-			}
-
-			if (chunk == NULL)
-				chunk = music_pipe_shift(player.pipe);
+			/* at least one music chunk is ready - send it
+			   to the audio output */
 
-			/* play the current chunk */
-
-			success = play_chunk(player.song, chunk,
-					     &player.play_audio_format,
-					     player.size_to_time);
-			music_buffer_return(player_buffer, chunk);
-
-			if (!success)
+			if (!play_next_chunk(&player))
 				break;
-
-			/* this formula should prevent that the
-			   decoder gets woken up with each chunk; it
-			   is more efficient to make it decode a
-			   larger block at a time */
-			if (!decoder_is_idle() &&
-			    music_pipe_size(dc.pipe) <= (pc.buffered_before_play +
-							 music_buffer_size(player_buffer) * 3) / 4)
-				notify_signal(&dc.notify);
 		} else if (dc.pipe != NULL && dc.pipe != player.pipe) {
 			/* at the beginning of a new song */
 
-- 
cgit v1.2.3