aboutsummaryrefslogtreecommitdiffstats
path: root/src/outputBuffer_xfade.h
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2008-08-23 15:52:44 -0700
committerEric Wong <normalperson@yhbt.net>2008-08-23 15:52:44 -0700
commit5655d2e5922955763455134814035e7ad76d2529 (patch)
tree020cc15899b30596a4d8477a120d50cf536293a8 /src/outputBuffer_xfade.h
parentd822bdec0700b94d83f2e15c2aa6602307179724 (diff)
downloadmpd-5655d2e5922955763455134814035e7ad76d2529.tar.gz
mpd-5655d2e5922955763455134814035e7ad76d2529.tar.xz
mpd-5655d2e5922955763455134814035e7ad76d2529.zip
outputBuffer: fix buffer_before_play handling
buffer_before_play is a prebuffer; always respecting it is almost as good as having no buffer at all. So we only respect it when we haven't played anything. Bugs that were a side effect of this also got fixed: The player would not stop when we got to the end of the last song on non-repeating playlists. The playlist would continuously show the song in the last few seconds of playback, and never move. Having crossfade enabled would also amplify the above effect. So, as a side effect, crossfade now correctly handles end-of-playlist conditions, as well. It will fade out to silence when we're at the end of a playlist.
Diffstat (limited to '')
-rw-r--r--src/outputBuffer_xfade.h45
1 files changed, 20 insertions, 25 deletions
diff --git a/src/outputBuffer_xfade.h b/src/outputBuffer_xfade.h
index 0f3a4d5a7..80efe704e 100644
--- a/src/outputBuffer_xfade.h
+++ b/src/outputBuffer_xfade.h
@@ -18,7 +18,7 @@ static size_t calculate_xfade_chunks(struct iovec vec[2])
if (!ob.total_time ||
(ob.elapsed_time + ob.xfade_time) < ob.total_time ||
!isCurrentAudioFormat(af))
- return ob.nr_bpp; /* too early, don't enable xfade yet */
+ return ob.bpp_cur; /* too early, don't enable xfade yet */
assert(af->bits > 0);
assert(af->channels > 0);
@@ -26,35 +26,30 @@ static size_t calculate_xfade_chunks(struct iovec vec[2])
chunks = af->sampleRate * af->bits * af->channels / 8.0 / CHUNK_SIZE;
chunks = chunks * (ob.xfade_time + 0.5);
+ assert(chunks);
- assert(ob.index->size >= ob.nr_bpp);
- if (chunks > (ob.index->size - ob.nr_bpp))
- chunks = ob.index->size - ob.nr_bpp;
+ assert(ob.index->size >= ob.bpp_cur);
+ if (chunks > (ob.index->size - ob.bpp_cur))
+ chunks = ob.index->size - ob.bpp_cur;
DEBUG("calculated xfade chunks: %d\n", chunks);
nr = vec[0].iov_len + vec[1].iov_len;
- if (chunks > nr)
- return chunks; /* not enough work with */
-
- c = get_chunk(vec, chunks);
- assert(c);
- if (c->seq == ob.seq_player) {
- do {
- if (!(c = get_chunk(vec, ++chunks)))
- return chunks; /* not enough to work with */
- } while (c->seq == ob.seq_player);
- } else {
- do {
- c = get_chunk(vec, --chunks);
- assert(c);
- } while (c->seq == ob.seq_decoder);
- assert((c = get_chunk(vec, chunks)));
- assert(c->seq != ob.seq_decoder);
- ++chunks;
- assert((c = get_chunk(vec, chunks)));
- assert(c->seq == ob.seq_decoder);
+ if (chunks <= nr) {
+ c = get_chunk(vec, chunks);
+ assert(c);
+ if (c->seq != ob.seq_player) {
+ do {
+ c = get_chunk(vec, --chunks);
+ assert(c);
+ } while (chunks && c->seq == ob.seq_decoder);
+ assert((c = get_chunk(vec, chunks)));
+ assert(c->seq != ob.seq_decoder);
+ ++chunks;
+ assert((c = get_chunk(vec, chunks)));
+ assert(c->seq == ob.seq_decoder);
+ }
+ DEBUG("adjusted xfade chunks: %d\n", chunks);
}
- DEBUG("adjusted xfade chunks: %d\n", chunks);
ob.xfade_cur = chunks;
ob.xfade_max = chunks;