Increase Ogg Vorbis read performance through buffering
Reduces runtime by factor 10
This commit is contained in:
parent
e13c222e28
commit
5e7e6f5f87
|
@ -98,22 +98,29 @@ SampleReader OggVorbisFileReader::createUnsafeSampleReader() const {
|
||||||
return [
|
return [
|
||||||
channelCount = channelCount,
|
channelCount = channelCount,
|
||||||
file = make_shared<OggVorbisFile>(filePath),
|
file = make_shared<OggVorbisFile>(filePath),
|
||||||
currentIndex = size_type(0)
|
buffer = static_cast<value_type**>(nullptr),
|
||||||
|
bufferStart = size_type(0),
|
||||||
|
bufferSize = size_type(0)
|
||||||
](size_type index) mutable {
|
](size_type index) mutable {
|
||||||
|
if (index < bufferStart || index >= bufferStart + bufferSize) {
|
||||||
// Seek
|
// Seek
|
||||||
if (index != currentIndex) {
|
|
||||||
throwOnError(ov_pcm_seek(file->get(), index));
|
throwOnError(ov_pcm_seek(file->get(), index));
|
||||||
}
|
|
||||||
|
|
||||||
// Read a single sample
|
// Read a block of samples
|
||||||
value_type** p = nullptr;
|
constexpr int maxSize = 1024;
|
||||||
long readCount = throwOnError(ov_read_float(file->get(), &p, 1, nullptr));
|
bufferStart = index;
|
||||||
if (readCount == 0) {
|
bufferSize = throwOnError(ov_read_float(file->get(), &buffer, maxSize, nullptr));
|
||||||
|
if (bufferSize == 0) {
|
||||||
throw std::runtime_error("Unexpected end of file.");
|
throw std::runtime_error("Unexpected end of file.");
|
||||||
}
|
}
|
||||||
++currentIndex;
|
}
|
||||||
|
|
||||||
// Downmix channels
|
// Downmix channels
|
||||||
return std::accumulate(*p, *p + channelCount, 0.0f) / channelCount;
|
size_type bufferIndex = index - bufferStart;
|
||||||
|
value_type sum = 0.0f;
|
||||||
|
for (int channel = 0; channel < channelCount; ++channel) {
|
||||||
|
sum += buffer[channel][bufferIndex];
|
||||||
|
}
|
||||||
|
return sum / channelCount;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue