From 5e7e6f5f876cca8559ecbfeee1ee9257dddfcb7c Mon Sep 17 00:00:00 2001 From: Daniel Wolf Date: Sat, 14 Jul 2018 22:09:06 +0200 Subject: [PATCH] Increase Ogg Vorbis read performance through buffering Reduces runtime by factor 10 --- rhubarb/src/audio/OggVorbisFileReader.cpp | 29 ++++++++++++++--------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/rhubarb/src/audio/OggVorbisFileReader.cpp b/rhubarb/src/audio/OggVorbisFileReader.cpp index 6415b2d..0d39c0d 100644 --- a/rhubarb/src/audio/OggVorbisFileReader.cpp +++ b/rhubarb/src/audio/OggVorbisFileReader.cpp @@ -98,22 +98,29 @@ SampleReader OggVorbisFileReader::createUnsafeSampleReader() const { return [ channelCount = channelCount, file = make_shared(filePath), - currentIndex = size_type(0) + buffer = static_cast(nullptr), + bufferStart = size_type(0), + bufferSize = size_type(0) ](size_type index) mutable { - // Seek - if (index != currentIndex) { + if (index < bufferStart || index >= bufferStart + bufferSize) { + // Seek throwOnError(ov_pcm_seek(file->get(), index)); - } - // Read a single sample - value_type** p = nullptr; - long readCount = throwOnError(ov_read_float(file->get(), &p, 1, nullptr)); - if (readCount == 0) { - throw std::runtime_error("Unexpected end of file."); + // Read a block of samples + constexpr int maxSize = 1024; + bufferStart = index; + bufferSize = throwOnError(ov_read_float(file->get(), &buffer, maxSize, nullptr)); + if (bufferSize == 0) { + throw std::runtime_error("Unexpected end of file."); + } } - ++currentIndex; // 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; }; }