diff options
author | Max Kellermann <max@duempel.org> | 2008-09-29 17:25:08 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2008-09-29 17:25:08 +0200 |
commit | c85b570ad78a0185f45a08e63fefc667c4f056f7 (patch) | |
tree | 504cd571df6a1b58bfc717542700453e689f47e3 /src/crossfade.c | |
parent | 6e21e24caed1a9497e876e4b89b12687aa73d6ad (diff) | |
download | mpd-c85b570ad78a0185f45a08e63fefc667c4f056f7.tar.gz mpd-c85b570ad78a0185f45a08e63fefc667c4f056f7.tar.xz mpd-c85b570ad78a0185f45a08e63fefc667c4f056f7.zip |
pcm_utils: pass only one buffer size to pcm_mix()
pcm_mix() might overflow the destination buffer if it is smaller than
the second buffer. This is ok because the physical buffer size passed
by cross_fade_apply() is always big enough, but clutters pcm_mix()
with complicated length checks and contains a dangerous buffer
overflow pitfall. Simplify pcm_mix()/pcm_add() and pass only the
smaller buffer size; let cross_fade_apply() do the memcpy().
Diffstat (limited to 'src/crossfade.c')
-rw-r--r-- | src/crossfade.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/crossfade.c b/src/crossfade.c index b99b9f7f0..c4a26fa6b 100644 --- a/src/crossfade.c +++ b/src/crossfade.c @@ -49,14 +49,28 @@ void cross_fade_apply(ob_chunk * a, const ob_chunk * b, const struct audio_format *format, unsigned int current_chunk, unsigned int num_chunks) { + size_t size; + assert(current_chunk <= num_chunks); + size = b->chunkSize > a->chunkSize + ? a->chunkSize + : b->chunkSize; + pcm_mix(a->data, b->data, - a->chunkSize, - b->chunkSize, + size, format, ((float)current_chunk) / num_chunks); - if (b->chunkSize > a->chunkSize) + + if (b->chunkSize > a->chunkSize) { + /* the second buffer is larger than the first one: + there is unmixed rest at the end. Copy it over. + The output buffer API guarantees that there is + enough room in a->data. */ + memcpy(a->data + a->chunkSize, + b->data + a->chunkSize, + b->chunkSize - a->chunkSize); a->chunkSize = b->chunkSize; + } } |