Skip to content

Commit 3776d2e

Browse files
committed
Warm-up decoder after seek
After a seek and decoder reset, the decoder needs to be fed a previous frame (if available) to have the required overlap data and decode the frame at the requested position correctly.
1 parent 180cbf1 commit 3776d2e

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

NAudio/Wave/WaveStreams/Mp3FileReader.cs

+19-6
Original file line numberDiff line numberDiff line change
@@ -388,23 +388,36 @@ public override int Read(byte[] sampleBuffer, int offset, int numBytes)
388388
offset += toCopy;
389389
}
390390

391+
int targetTocIndex = tocIndex; // the frame index that contains the requested data
392+
393+
if (repositionedFlag)
394+
{
395+
decompressor.Reset();
396+
397+
// Seek back a few frames of the stream to get the reset decoder decode a few
398+
// warm-up frames before reading the requested data. Without the warm-up phase,
399+
// the first half of the frame after the reset is attenuated and does not resemble
400+
// the data as it would be when reading sequentially from the beginning, because
401+
// the decoder is missing the required overlap from the previous frame.
402+
tocIndex = Math.Max(0, tocIndex - 3); // no warm-up at the beginning of the stream
403+
mp3Stream.Position = tableOfContents[tocIndex].FilePosition;
404+
405+
repositionedFlag = false;
406+
}
407+
391408
while (bytesRead < numBytes)
392409
{
393410
Mp3Frame frame = ReadNextFrame();
394411
if (frame != null)
395412
{
396-
if (repositionedFlag)
397-
{
398-
decompressor.Reset();
399-
repositionedFlag = false;
400-
}
401413
int decompressed = decompressor.DecompressFrame(frame, decompressBuffer, 0);
402414

403-
if (decompressed == 0)
415+
if (tocIndex <= targetTocIndex || decompressed == 0)
404416
{
405417
// The first frame after a reset usually does not immediately yield decoded samples.
406418
// Because the next instructions will fail if a buffer offset is set and the frame
407419
// decoding didn't return data, we skip the part.
420+
// We skip the following instructions also after decoding a warm-up frame.
408421
continue;
409422
}
410423

0 commit comments

Comments
 (0)