Skip to content

Commit

Permalink
Addressed Seeking Quirks in FLAC Reader
Browse files Browse the repository at this point in the history
  • Loading branch information
Cobaltergeist committed Oct 14, 2016
1 parent 2207af4 commit cc25032
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 14 deletions.
34 changes: 21 additions & 13 deletions src/SFML/Audio/SoundFileReaderFlac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,6 @@ namespace
{
sf::priv::SoundFileReaderFlac::ClientData* data = static_cast<sf::priv::SoundFileReaderFlac::ClientData*>(clientData);

// If there's no output buffer, it means that we are seeking
if (!data->buffer)
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;

// Reserve memory if we're going to use the leftovers buffer
unsigned int frameSamples = frame->header.blocksize * frame->header.channels;
if (data->remaining < frameSamples)
Expand Down Expand Up @@ -142,10 +138,12 @@ namespace
break;
}

// If there's room in the output buffer, copy the sample there
if (data->remaining > 0)
{
// There's room in the output buffer, copy the sample there
*data->buffer++ = sample;
// If there's no output buffer, it means that we are seeking, so just skip the output write
if (data->buffer)
*data->buffer++ = sample;
data->remaining--;
}
else
Expand Down Expand Up @@ -210,8 +208,7 @@ bool SoundFileReaderFlac::check(InputStream& stream)
////////////////////////////////////////////////////////////
SoundFileReaderFlac::SoundFileReaderFlac() :
m_decoder(NULL),
m_clientData(),
m_channelCount(0)
m_clientData()
{
}

Expand Down Expand Up @@ -249,9 +246,6 @@ bool SoundFileReaderFlac::open(InputStream& stream, Info& info)
// Retrieve the sound properties
info = m_clientData.info; // was filled in the "metadata" callback

// We must keep the channel count for the seek function
m_channelCount = info.channelCount;

return true;
}

Expand All @@ -267,7 +261,21 @@ void SoundFileReaderFlac::seek(Uint64 sampleOffset)
m_clientData.leftovers.clear();

// FLAC decoder expects absolute sample offset, so we take the channel count out
FLAC__stream_decoder_seek_absolute(m_decoder, sampleOffset / m_channelCount);
if (sampleOffset < m_clientData.info.sampleCount)
{
// The "write" callback will populate the leftovers buffer with the first batch of samples from the
// seek destination, and since we want that data in this typical case, we don't re-clear it afterward
FLAC__stream_decoder_seek_absolute(m_decoder, sampleOffset / m_clientData.info.channelCount);
}
else
{
// FLAC decoder can't skip straight to EOF, so we short-seek by one sample and skip the rest
FLAC__stream_decoder_seek_absolute(m_decoder, (sampleOffset / m_clientData.info.channelCount) - 1);
FLAC__stream_decoder_skip_single_frame(m_decoder);

// This was re-populated during the seek, but we're skipping everything in this, so we need it emptied
m_clientData.leftovers.clear();
}
}


Expand All @@ -283,7 +291,7 @@ Uint64 SoundFileReaderFlac::read(Int16* samples, Uint64 maxCount)
if (left > maxCount)
{
// There are more leftovers than needed
std::copy(m_clientData.leftovers.begin(), m_clientData.leftovers.end(), samples);
std::copy(m_clientData.leftovers.begin(), m_clientData.leftovers.begin() + maxCount, samples);
std::vector<Int16> leftovers(m_clientData.leftovers.begin() + maxCount, m_clientData.leftovers.end());
m_clientData.leftovers.swap(leftovers);
return maxCount;
Expand Down
1 change: 0 additions & 1 deletion src/SFML/Audio/SoundFileReaderFlac.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ class SoundFileReaderFlac : public SoundFileReader
////////////////////////////////////////////////////////////
FLAC__StreamDecoder* m_decoder; ///< FLAC decoder
ClientData m_clientData; ///< Structure passed to the decoder callbacks
unsigned int m_channelCount; ///< number of channels of the sound file
};

} // namespace priv
Expand Down

0 comments on commit cc25032

Please sign in to comment.