Skip to content

Commit

Permalink
Strip one frame from the file length to compensate the legacy off-by-…
Browse files Browse the repository at this point in the history
…one issue
  • Loading branch information
daschuer committed Dec 30, 2022
1 parent 96a0156 commit 30fe711
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions src/sources/soundsourcemp3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ SoundSource::OpenResult SoundSourceMp3::tryOpen(
// 7000 days of audio duration.
quint64 sumBitrateFrames = 0; // nominator
quint64 cntBitrateFrames = 0; // denominator
long madFrameLength = 0;

mad_header madHeader;
mad_header_init(&madHeader);
Expand Down Expand Up @@ -264,7 +265,7 @@ SoundSource::OpenResult SoundSourceMp3::tryOpen(
static_assert(MAD_UNITS_8000_HZ == 8000);
const mad_units madUnits = static_cast<mad_units>(madSampleRate);

const long madFrameLength = mad_timer_count(madHeader.duration, madUnits);
madFrameLength = mad_timer_count(madHeader.duration, madUnits);
if (0 >= madFrameLength) {
kLogger.warning() << "Skipping MP3 frame with invalid length"
<< madFrameLength
Expand Down Expand Up @@ -386,7 +387,11 @@ SoundSource::OpenResult SoundSourceMp3::tryOpen(
return OpenResult::Failed;
}
initSampleRateOnce(getSampleRateByIndex(mostCommonSampleRateIndex));
initFrameIndexRangeOnce(IndexRange::forward(0, m_curFrameIndex));

// Because of an off-by-one issue we need to short the file by one frame.
// See comments in restartDecoding()
DEBUG_ASSERT(m_curFrameIndex - madFrameLength == m_seekFrameList.back().frameIndex);
initFrameIndexRangeOnce(IndexRange::forward(0, m_seekFrameList.back().frameIndex));

// Calculate average bitrate values
DEBUG_ASSERT(m_seekFrameList.size() > 0); // see above
Expand All @@ -398,8 +403,10 @@ SoundSource::OpenResult SoundSourceMp3::tryOpen(
kLogger.warning() << "Bitrate cannot be calculated from headers";
}

// Terminate m_seekFrameList
addSeekFrame(m_curFrameIndex, nullptr);
// Terminate m_seekFrameList by removing the last frame.
// This is not needed because it would decode data past the last frame
// due to the legacy off-by-one issue
m_seekFrameList.back().pInputData = nullptr;
DEBUG_ASSERT(m_seekFrameList.back().frameIndex == frameIndexMax());

// Restart decoding at the beginning of the audio stream
Expand Down

0 comments on commit 30fe711

Please sign in to comment.