aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-08-21 17:46:25 +0200
committerMax Kellermann <max@duempel.org>2014-08-21 17:46:25 +0200
commitdedc2986c69967793bddecb5af41d2021e0af87f (patch)
tree5515e6c4f126a2e183419e2a57cfec99abe49c83
parent74cdc0005a032c5473027e372eee3a522ccaf750 (diff)
downloadmpd-dedc2986c69967793bddecb5af41d2021e0af87f.tar.gz
mpd-dedc2986c69967793bddecb5af41d2021e0af87f.tar.xz
mpd-dedc2986c69967793bddecb5af41d2021e0af87f.zip
decoder/dsf: fix noise at end of malformed file
Read one block at a time. This discards the last partial block, which cannot be interleaved anyway. Previously, uninitialised memory was used to interleave the last block, which generated some noise.
-rw-r--r--NEWS1
-rw-r--r--src/decoder/plugins/DsfDecoderPlugin.cxx22
2 files changed, 8 insertions, 15 deletions
diff --git a/NEWS b/NEWS
index c5c10ca85..9c9e02eae 100644
--- a/NEWS
+++ b/NEWS
@@ -43,6 +43,7 @@ ver 0.19 (not yet released)
- audiofile: log libaudiofile errors
- dsdiff, dsf: report bit rate
- dsf: support DSD512
+ - dsf: fix noise at end of malformed file
- sndfile: support scanning remote files
- sndfile: support tags "comment", "album", "track", "genre"
- mp4v2: support playback of MP4 files.
diff --git a/src/decoder/plugins/DsfDecoderPlugin.cxx b/src/decoder/plugins/DsfDecoderPlugin.cxx
index d99550df1..98538a842 100644
--- a/src/decoder/plugins/DsfDecoderPlugin.cxx
+++ b/src/decoder/plugins/DsfDecoderPlugin.cxx
@@ -224,30 +224,22 @@ dsf_decode_chunk(Decoder &decoder, InputStream &is,
const unsigned buffer_frames = sizeof(buffer) / frame_size;
const unsigned buffer_samples = buffer_frames * frame_size;
const size_t buffer_size = buffer_samples * sample_size;
+ const size_t block_size = buffer_size;
- while (chunk_size >= frame_size) {
- /* see how much aligned data from the remaining chunk
- fits into the local buffer */
- size_t now_size = buffer_size;
- if (chunk_size < now_size) {
- unsigned now_frames = chunk_size / frame_size;
- now_size = now_frames * frame_size;
- }
+ while (chunk_size >= block_size) {
+ chunk_size -= block_size;
- if (!decoder_read_full(&decoder, is, buffer, now_size))
+ if (!decoder_read_full(&decoder, is, buffer, block_size))
return false;
- const size_t nbytes = now_size;
- chunk_size -= nbytes;
-
if (bitreverse)
- bit_reverse_buffer(buffer, buffer + nbytes);
+ bit_reverse_buffer(buffer, buffer + block_size);
uint8_t interleaved_buffer[DSF_BLOCK_SIZE * 2];
- dsf_to_pcm_order(interleaved_buffer, buffer, nbytes);
+ dsf_to_pcm_order(interleaved_buffer, buffer, block_size);
const auto cmd = decoder_data(decoder, is,
- interleaved_buffer, nbytes,
+ interleaved_buffer, block_size,
sample_rate / 1000);
switch (cmd) {
case DecoderCommand::NONE: