diff options
author | Eric Wong <normalperson@yhbt.net> | 2008-08-23 15:52:44 -0700 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2008-08-23 15:52:44 -0700 |
commit | 5655d2e5922955763455134814035e7ad76d2529 (patch) | |
tree | 020cc15899b30596a4d8477a120d50cf536293a8 /src/outputBuffer_xfade.h | |
parent | d822bdec0700b94d83f2e15c2aa6602307179724 (diff) | |
download | mpd-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.h | 45 |
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; |