From dedc2986c69967793bddecb5af41d2021e0af87f Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Thu, 21 Aug 2014 17:46:25 +0200
Subject: [PATCH] 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.
---
 NEWS                                     |  1 +
 src/decoder/plugins/DsfDecoderPlugin.cxx | 22 +++++++---------------
 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: