From c94eea2a3f939a5e0209ca4c89cb909f69a8df80 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Thu, 11 Jun 2020 03:12:31 +0200 Subject: [PATCH] Eliminate excessFileFrames from FilePool, use fixed padding buffer --- src/sfizz/FilePool.cpp | 47 +++++++++++++++++------------------------- src/sfizz/FilePool.h | 23 +++++++++------------ 2 files changed, 29 insertions(+), 41 deletions(-) diff --git a/src/sfizz/FilePool.cpp b/src/sfizz/FilePool.cpp index 6143ebef..d0ac449e 100644 --- a/src/sfizz/FilePool.cpp +++ b/src/sfizz/FilePool.cpp @@ -39,11 +39,10 @@ #include #include -template -void readBaseFile(SndfileHandle& sndFile, sfz::AudioBuffer& output, uint32_t numFrames, bool reverse) +void readBaseFile(SndfileHandle& sndFile, sfz::FileAudioBuffer& output, uint32_t numFrames, bool reverse) { output.reset(); - output.resize(numFrames + 2 * sfz::config::excessFileFrames); + output.resize(numFrames); if (reverse) sndFile.seek(-static_cast(numFrames), SEEK_END); @@ -53,48 +52,42 @@ void readBaseFile(SndfileHandle& sndFile, sfz::AudioBuffer& output, uint32_t if (channels == 1) { output.addChannel(); output.clear(); - sndFile.readf(output.channelWriter(0) + sfz::config::excessFileFrames, numFrames); + sndFile.readf(output.channelWriter(0), numFrames); } else if (channels == 2) { output.addChannel(); output.addChannel(); output.clear(); - sfz::Buffer tempReadBuffer { 2 * numFrames }; + sfz::Buffer tempReadBuffer { 2 * numFrames }; sndFile.readf(tempReadBuffer.data(), numFrames); - sfz::readInterleaved(tempReadBuffer, - output.getSpan(0).subspan(sfz::config::excessFileFrames, numFrames), - output.getSpan(1).subspan(sfz::config::excessFileFrames, numFrames) - ); + sfz::readInterleaved(tempReadBuffer, output.getSpan(0), output.getSpan(1)); } if (reverse) { for (unsigned c = 0; c < channels; ++c) { // TODO: consider optimizing with SIMD - absl::Span channel = output.getSpan(c).subspan(sfz::config::excessFileFrames, numFrames); + absl::Span channel = output.getSpan(c); std::reverse(channel.begin(), channel.end()); } } } -template -std::unique_ptr> readFromFile(SndfileHandle& sndFile, uint32_t numFrames, sfz::Oversampling factor, bool reverse) +std::unique_ptr readFromFile(SndfileHandle& sndFile, uint32_t numFrames, sfz::Oversampling factor, bool reverse) { - auto baseBuffer = absl::make_unique>(); + auto baseBuffer = absl::make_unique(); readBaseFile(sndFile, *baseBuffer, numFrames, reverse); if (factor == sfz::Oversampling::x1) return baseBuffer; - auto outputBuffer = absl::make_unique>(sndFile.channels(), numFrames * static_cast(factor) + 2 * sfz::config::excessFileFrames); + auto outputBuffer = absl::make_unique(sndFile.channels(), numFrames * static_cast(factor)); outputBuffer->clear(); - auto baseSpan = sfz::AudioSpan(*baseBuffer).subspan(sfz::config::excessFileFrames, numFrames); - auto outputSpan = sfz::AudioSpan(*outputBuffer).subspan(sfz::config::excessFileFrames, numFrames * static_cast(factor)); sfz::Oversampler oversampler { factor }; - oversampler.stream(baseSpan, outputSpan); + oversampler.stream(*baseBuffer, *outputBuffer); return outputBuffer; } template -void streamFromFile(SndfileHandle& sndFile, uint32_t numFrames, sfz::Oversampling factor, bool reverse, sfz::AudioBuffer& output, std::atomic* filledFrames = nullptr) +void streamFromFile(SndfileHandle& sndFile, uint32_t numFrames, sfz::Oversampling factor, bool reverse, sfz::FileAudioBuffer& output, std::atomic* filledFrames = nullptr) { if (factor == sfz::Oversampling::x1) { readBaseFile(sndFile, output, numFrames, reverse); @@ -103,15 +96,13 @@ void streamFromFile(SndfileHandle& sndFile, uint32_t numFrames, sfz::Oversamplin return; } - auto baseBuffer = readFromFile(sndFile, numFrames, sfz::Oversampling::x1, reverse); + auto baseBuffer = readFromFile(sndFile, numFrames, sfz::Oversampling::x1, reverse); output.reset(); output.addChannels(baseBuffer->getNumChannels()); - output.resize(numFrames * static_cast(factor) + 2 * sfz::config::excessFileFrames); + output.resize(numFrames * static_cast(factor)); output.clear(); sfz::Oversampler oversampler { factor }; - auto baseSpan = sfz::AudioSpan(*baseBuffer).subspan(sfz::config::excessFileFrames, numFrames); - auto outputSpan = sfz::AudioSpan(output).subspan(sfz::config::excessFileFrames, numFrames * static_cast(factor)); - oversampler.stream(baseSpan, outputSpan, filledFrames); + oversampler.stream(*baseBuffer, output, filledFrames); } sfz::FilePool::FilePool(sfz::Logger& logger) @@ -272,12 +263,12 @@ bool sfz::FilePool::preloadFile(const FileId& fileId, uint32_t maxOffset) noexce const auto existingFile = preloadedFiles.find(fileId); if (existingFile != preloadedFiles.end()) { if (framesToLoad > existingFile->second.preloadedData->getNumFrames()) { - preloadedFiles[fileId].preloadedData = readFromFile(sndFile, framesToLoad, oversamplingFactor, fileId.isReverse()); + preloadedFiles[fileId].preloadedData = readFromFile(sndFile, framesToLoad, oversamplingFactor, fileId.isReverse()); } } else { fileInformation->sampleRate = static_cast(oversamplingFactor) * static_cast(sndFile.samplerate()); FileDataHandle handle { - readFromFile(sndFile, framesToLoad, oversamplingFactor, fileId.isReverse()), + readFromFile(sndFile, framesToLoad, oversamplingFactor, fileId.isReverse()), *fileInformation }; preloadedFiles.insert_or_assign(fileId, handle); @@ -302,7 +293,7 @@ absl::optional sfz::FilePool::loadFile(const FileId& fileId } else { fileInformation->sampleRate = static_cast(oversamplingFactor) * static_cast(sndFile.samplerate()); FileDataHandle handle { - readFromFile(sndFile, frames, oversamplingFactor, fileId.isReverse()), + readFromFile(sndFile, frames, oversamplingFactor, fileId.isReverse()), *fileInformation }; loadedFiles.insert_or_assign(fileId, handle); @@ -352,7 +343,7 @@ void sfz::FilePool::setPreloadSize(uint32_t preloadSize) noexcept const auto maxOffset = numFrames > this->preloadSize ? static_cast(numFrames) - this->preloadSize : 0; fs::path file { rootDirectory / preloadedFile.first.filename() }; SndfileHandle sndFile(file.string().c_str()); - preloadedFile.second.preloadedData = readFromFile(sndFile, preloadSize + maxOffset, oversamplingFactor, preloadedFile.first.isReverse()); + preloadedFile.second.preloadedData = readFromFile(sndFile, preloadSize + maxOffset, oversamplingFactor, preloadedFile.first.isReverse()); } this->preloadSize = preloadSize; } @@ -481,7 +472,7 @@ void sfz::FilePool::setOversamplingFactor(sfz::Oversampling factor) noexcept const uint32_t maxOffset = numFrames > this->preloadSize ? static_cast(numFrames) - this->preloadSize : 0; fs::path file { rootDirectory / preloadedFile.first.filename() }; SndfileHandle sndFile(file.string().c_str()); - preloadedFile.second.preloadedData = readFromFile(sndFile, preloadSize + maxOffset, factor, preloadedFile.first.isReverse()); + preloadedFile.second.preloadedData = readFromFile(sndFile, preloadSize + maxOffset, factor, preloadedFile.first.isReverse()); preloadedFile.second.information.sampleRate *= samplerateChange; } diff --git a/src/sfizz/FilePool.h b/src/sfizz/FilePool.h index 1e996756..70973a87 100644 --- a/src/sfizz/FilePool.h +++ b/src/sfizz/FilePool.h @@ -43,7 +43,9 @@ #include namespace sfz { -using AudioBufferPtr = std::shared_ptr>; +using FileAudioBuffer = AudioBuffer; +using FileAudioBufferPtr = std::shared_ptr; struct FileInformation { uint32_t end { Default::sampleEndRange.getEnd() }; @@ -56,7 +58,7 @@ struct FileInformation { // Strict C++11 disallows member initialization if aggregate initialization is to be used... struct FileDataHandle { - std::shared_ptr> preloadedData; + FileAudioBufferPtr preloadedData; FileInformation information; }; @@ -65,16 +67,11 @@ struct FilePromise AudioSpan getData() { if (dataStatus == DataStatus::Ready) - return AudioSpan(fileData) - .subspan(sfz::config::excessFileFrames, - fileData.getNumFrames() - 2 * sfz::config::excessFileFrames); - else if (availableFrames > preloadedData->getNumFrames() + sfz::config::excessFileFrames) - return AudioSpan(fileData) - .subspan(sfz::config::excessFileFrames, availableFrames - sfz::config::excessFileFrames); + return AudioSpan(fileData); + else if (availableFrames > preloadedData->getNumFrames()) + return AudioSpan(fileData).first(availableFrames); else - return AudioSpan(*preloadedData) - .subspan(sfz::config::excessFileFrames, - preloadedData->getNumFrames() - 2 * sfz::config::excessFileFrames); + return AudioSpan(*preloadedData); } void reset() @@ -101,8 +98,8 @@ struct FilePromise }; FileId fileId {}; - AudioBufferPtr preloadedData {}; - AudioBuffer fileData {}; + FileAudioBufferPtr preloadedData {}; + FileAudioBuffer fileData {}; float sampleRate { config::defaultSampleRate }; Oversampling oversamplingFactor { config::defaultOversamplingFactor }; std::atomic availableFrames { 0 };