aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/decode.c21
-rw-r--r--src/outputBuffer.c17
-rw-r--r--src/outputBuffer.h6
3 files changed, 27 insertions, 17 deletions
diff --git a/src/decode.c b/src/decode.c
index 05e4c4a56..fd65dc5ae 100644
--- a/src/decode.c
+++ b/src/decode.c
@@ -503,7 +503,6 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
(fadePosition = next - cb->begin +
buffered_chunks) <= crossFadeChunks))) {
/* perform cross fade */
- unsigned int test = end;
if (nextChunk < 0) {
/* beginning of the cross fade
- adjust crossFadeChunks
@@ -512,13 +511,8 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
chunks in the old song */
crossFadeChunks = fadePosition;
}
- if (end < cb->begin)
- test += buffered_chunks;
- nextChunk = cb->begin + crossFadeChunks;
- if ((unsigned)nextChunk < test) {
- if ((unsigned)nextChunk >= buffered_chunks) {
- nextChunk -= buffered_chunks;
- }
+ nextChunk = outputBufferAbsolute(cb, crossFadeChunks);
+ if (nextChunk >= 0) {
pcm_mix(cb->chunks +
cb->begin * CHUNK_SIZE,
cb->chunks +
@@ -575,16 +569,9 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
/* the cross-fade is finished; skip
the section which was cross-faded
(and thus already played) */
- unsigned int test = end;
- nextChunk = cb->begin + crossFadeChunks;
- if (end < cb->begin)
- test += buffered_chunks;
- if ((unsigned)nextChunk < test) {
- if ((unsigned)nextChunk >= buffered_chunks) {
- nextChunk -= buffered_chunks;
- }
+ nextChunk = outputBufferAbsolute(cb, crossFadeChunks);
+ if (nextChunk >= 0)
advanceOutputBufferTo(cb, nextChunk);
- }
}
/* wait for the decoder to work on the new song */
diff --git a/src/outputBuffer.c b/src/outputBuffer.c
index f5a6dbf51..b5fddd98d 100644
--- a/src/outputBuffer.c
+++ b/src/outputBuffer.c
@@ -65,6 +65,23 @@ unsigned availableOutputBuffer(const OutputBuffer * cb)
return cb->end + buffered_chunks - cb->begin;
}
+int outputBufferAbsolute(const OutputBuffer * cb, unsigned relative)
+{
+ unsigned i, max;
+
+ max = cb->end;
+ if (max < cb->begin)
+ max += buffered_chunks;
+ i = (unsigned)cb->begin + relative;
+ if (i >= max)
+ return -1;
+
+ if (i >= buffered_chunks)
+ i -= buffered_chunks;
+
+ return (int)i;
+}
+
/**
* Return the tail chunk has room for additional data. If there is no
* room in the queue, this function blocks until the player thread has
diff --git a/src/outputBuffer.h b/src/outputBuffer.h
index 08124dffa..06ec60d19 100644
--- a/src/outputBuffer.h
+++ b/src/outputBuffer.h
@@ -58,6 +58,12 @@ void flushOutputBuffer(OutputBuffer * cb);
/** determine the number of decoded chunks */
unsigned availableOutputBuffer(const OutputBuffer * cb);
+/**
+ * Get the absolute index of the nth used chunk after the first one.
+ * Returns -1 if there is no such chunk.
+ */
+int outputBufferAbsolute(const OutputBuffer * cb, unsigned relative);
+
/* we send inStream for buffering the inputStream while waiting to
send the next chunk */
int sendDataToOutputBuffer(OutputBuffer * cb,