mirror of
https://github.com/SFML/SFML.git
synced 2024-11-25 12:51:05 +08:00
Addressed Seeking Quirks in FLAC Reader
This commit is contained in:
parent
746bb9c8ca
commit
5eaa748adb
@ -107,10 +107,6 @@ namespace
|
|||||||
{
|
{
|
||||||
sf::priv::SoundFileReaderFlac::ClientData* data = static_cast<sf::priv::SoundFileReaderFlac::ClientData*>(clientData);
|
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
|
// Reserve memory if we're going to use the leftovers buffer
|
||||||
unsigned int frameSamples = frame->header.blocksize * frame->header.channels;
|
unsigned int frameSamples = frame->header.blocksize * frame->header.channels;
|
||||||
if (data->remaining < frameSamples)
|
if (data->remaining < frameSamples)
|
||||||
@ -142,15 +138,16 @@ namespace
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->remaining > 0)
|
if (data->buffer && data->remaining > 0)
|
||||||
{
|
{
|
||||||
// There's room in the output buffer, copy the sample there
|
// If there's room in the output buffer, copy the sample there
|
||||||
*data->buffer++ = sample;
|
*data->buffer++ = sample;
|
||||||
data->remaining--;
|
data->remaining--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We have decoded all the requested samples, put the sample in a temporary buffer until next call
|
// We are either seeking (null buffer) or have decoded all the requested samples during a
|
||||||
|
// normal read (0 remaining), so we put the sample in a temporary buffer until next call
|
||||||
data->leftovers.push_back(sample);
|
data->leftovers.push_back(sample);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,8 +207,7 @@ bool SoundFileReaderFlac::check(InputStream& stream)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SoundFileReaderFlac::SoundFileReaderFlac() :
|
SoundFileReaderFlac::SoundFileReaderFlac() :
|
||||||
m_decoder(NULL),
|
m_decoder(NULL),
|
||||||
m_clientData(),
|
m_clientData()
|
||||||
m_channelCount(0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,9 +245,6 @@ bool SoundFileReaderFlac::open(InputStream& stream, Info& info)
|
|||||||
// Retrieve the sound properties
|
// Retrieve the sound properties
|
||||||
info = m_clientData.info; // was filled in the "metadata" callback
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +260,21 @@ void SoundFileReaderFlac::seek(Uint64 sampleOffset)
|
|||||||
m_clientData.leftovers.clear();
|
m_clientData.leftovers.clear();
|
||||||
|
|
||||||
// FLAC decoder expects absolute sample offset, so we take the channel count out
|
// 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, (m_clientData.info.sampleCount / 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -283,7 +290,7 @@ Uint64 SoundFileReaderFlac::read(Int16* samples, Uint64 maxCount)
|
|||||||
if (left > maxCount)
|
if (left > maxCount)
|
||||||
{
|
{
|
||||||
// There are more leftovers than needed
|
// 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());
|
std::vector<Int16> leftovers(m_clientData.leftovers.begin() + maxCount, m_clientData.leftovers.end());
|
||||||
m_clientData.leftovers.swap(leftovers);
|
m_clientData.leftovers.swap(leftovers);
|
||||||
return maxCount;
|
return maxCount;
|
||||||
|
@ -131,9 +131,8 @@ private:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
FLAC__StreamDecoder* m_decoder; ///< FLAC decoder
|
FLAC__StreamDecoder* m_decoder; ///< FLAC decoder
|
||||||
ClientData m_clientData; ///< Structure passed to the decoder callbacks
|
ClientData m_clientData; ///< Structure passed to the decoder callbacks
|
||||||
unsigned int m_channelCount; ///< number of channels of the sound file
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace priv
|
} // namespace priv
|
||||||
|
Loading…
Reference in New Issue
Block a user