diff options
author | Max Kellermann <max@duempel.org> | 2014-08-21 17:46:25 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2014-08-21 17:46:25 +0200 |
commit | dedc2986c69967793bddecb5af41d2021e0af87f (patch) | |
tree | 5515e6c4f126a2e183419e2a57cfec99abe49c83 | |
parent | 74cdc0005a032c5473027e372eee3a522ccaf750 (diff) | |
download | mpd-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-- | NEWS | 1 | ||||
-rw-r--r-- | src/decoder/plugins/DsfDecoderPlugin.cxx | 22 |
2 files changed, 8 insertions, 15 deletions
@@ -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: |