diff --git a/sfizz/FilePool.cpp b/sfizz/FilePool.cpp index 6dd709b4..52fcfc07 100644 --- a/sfizz/FilePool.cpp +++ b/sfizz/FilePool.cpp @@ -85,9 +85,9 @@ std::optional sfz::FilePool::getFileInformation( return returnedValue; } -void sfz::FilePool::enqueueLoading(Voice* voice, std::string_view sample, int numFrames) noexcept +void sfz::FilePool::enqueueLoading(Voice* voice, std::string_view sample, int numFrames, unsigned ticket) noexcept { - if (!loadingQueue.try_enqueue({ voice, sample, numFrames })) { + if (!loadingQueue.try_enqueue({ voice, sample, numFrames, ticket })) { DBG("Problem enqueuing a file read for file " << sample); } } @@ -113,6 +113,6 @@ void sfz::FilePool::loadingThread() noexcept SndfileHandle sndFile(reinterpret_cast(file.c_str())); auto fileLoaded = std::make_unique>(sndFile.channels(), fileToLoad.numFrames); - fileToLoad.voice->setFileData(readFromFile(sndFile, fileToLoad.numFrames)); + fileToLoad.voice->setFileData(readFromFile(sndFile, fileToLoad.numFrames), fileToLoad.ticket); } } \ No newline at end of file diff --git a/sfizz/FilePool.h b/sfizz/FilePool.h index f27bb870..a7b795df 100644 --- a/sfizz/FilePool.h +++ b/sfizz/FilePool.h @@ -57,13 +57,14 @@ public: std::shared_ptr> preloadedData; }; std::optional getFileInformation(std::string_view filename) noexcept; - void enqueueLoading(Voice* voice, std::string_view sample, int numFrames) noexcept; + void enqueueLoading(Voice* voice, std::string_view sample, int numFrames, unsigned ticket) noexcept; private: std::filesystem::path rootDirectory; struct FileLoadingInformation { Voice* voice; std::string_view sample; int numFrames; + unsigned ticket; }; moodycamel::BlockingReaderWriterQueue loadingQueue; diff --git a/sfizz/Synth.cpp b/sfizz/Synth.cpp index 976aa4e8..7b23219f 100644 --- a/sfizz/Synth.cpp +++ b/sfizz/Synth.cpp @@ -22,8 +22,8 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Synth.h" -#include "ScopedFTZ.h" #include "Debug.h" +#include "ScopedFTZ.h" #include "StringViewHelpers.h" #include "absl/algorithm/container.h" #include @@ -106,6 +106,7 @@ void sfz::Synth::clear() numGroups = 0; numMasters = 0; numCurves = 0; + fileTicket = -1; defaultSwitch = std::nullopt; for (auto& state : ccState) state = 0; @@ -152,23 +153,19 @@ void sfz::Synth::handleControlOpcodes(const std::vector& members) void addEndpointsToVelocityCurve(sfz::Region& region) { - if (region.velocityPoints.size() > 0) - { + if (region.velocityPoints.size() > 0) { absl::c_sort(region.velocityPoints, [](auto& lhs, auto& rhs) { return lhs.first < rhs.first; }); - if (region.ampVeltrack > 0) - { + if (region.ampVeltrack > 0) { if (region.velocityPoints.back().first != sfz::Default::velocityRange.getEnd()) region.velocityPoints.push_back(std::make_pair(127, 1.0f)); if (region.velocityPoints.front().first != sfz::Default::velocityRange.getStart()) region.velocityPoints.insert(region.velocityPoints.begin(), std::make_pair(0, 0.0f)); - } - else - { + } else { if (region.velocityPoints.front().first != sfz::Default::velocityRange.getEnd()) region.velocityPoints.insert(region.velocityPoints.begin(), std::make_pair(127, 0.0f)); if (region.velocityPoints.back().first != sfz::Default::velocityRange.getStart()) region.velocityPoints.push_back(std::make_pair(0, 1.0f)); - } + } } } @@ -299,7 +296,10 @@ void sfz::Synth::noteOn(int delay, int channel, int noteNumber, uint8_t velocity continue; voice->startVoice(region.get(), delay, channel, noteNumber, velocity, Voice::TriggerType::NoteOn); - filePool.enqueueLoading(voice, region->sample, region->trueSampleEnd()); + if (!region->isGenerator()) { + voice->expectFileData(fileTicket); + filePool.enqueueLoading(voice, region->sample, region->trueSampleEnd(), fileTicket++); + } } } } @@ -317,7 +317,10 @@ void sfz::Synth::noteOff(int delay, int channel, int noteNumber, uint8_t velocit continue; voice->startVoice(region.get(), delay, channel, noteNumber, velocity, Voice::TriggerType::NoteOff); - filePool.enqueueLoading(voice, region->sample, region->trueSampleEnd()); + if (!region->isGenerator()) { + voice->expectFileData(fileTicket); + filePool.enqueueLoading(voice, region->sample, region->trueSampleEnd(), fileTicket++); + } } } } @@ -336,7 +339,10 @@ void sfz::Synth::cc(int delay, int channel, int ccNumber, uint8_t ccValue) noexc continue; voice->startVoice(region.get(), delay, channel, ccNumber, ccValue, Voice::TriggerType::CC); - filePool.enqueueLoading(voice, region->sample, region->trueSampleEnd()); + if (!region->isGenerator()) { + voice->expectFileData(fileTicket); + filePool.enqueueLoading(voice, region->sample, region->trueSampleEnd(), fileTicket++); + } } } } diff --git a/sfizz/Synth.h b/sfizz/Synth.h index 7c7f58d9..fc5f4f69 100644 --- a/sfizz/Synth.h +++ b/sfizz/Synth.h @@ -96,6 +96,7 @@ private: float sampleRate { config::defaultSampleRate }; std::uniform_real_distribution randNoteDistribution { 0, 1 }; + unsigned fileTicket { 1 }; LEAK_DETECTOR(Synth); }; diff --git a/sfizz/Voice.cpp b/sfizz/Voice.cpp index d8e40f99..3e340606 100644 --- a/sfizz/Voice.cpp +++ b/sfizz/Voice.cpp @@ -101,9 +101,11 @@ void sfz::Voice::prepareEGEnvelope(int delay, uint8_t velocity) noexcept normalizePercents(region->amplitudeEG.getStart(ccState, velocity))); } -void sfz::Voice::setFileData(std::unique_ptr> file) noexcept +void sfz::Voice::setFileData(std::unique_ptr> file, unsigned ticket) noexcept { - // DBG("File data set for sample " << region->sample); + if (ticket != this->ticket) + return; + fileData = std::move(file); dataReady.store(true); } @@ -422,3 +424,8 @@ void sfz::Voice::garbageCollect() noexcept if (state == State::idle && region == nullptr) fileData.reset(); } + +void sfz::Voice::expectFileData(unsigned ticket) +{ + this->ticket = ticket; +} \ No newline at end of file diff --git a/sfizz/Voice.h b/sfizz/Voice.h index 61f6f135..37fbccf3 100644 --- a/sfizz/Voice.h +++ b/sfizz/Voice.h @@ -47,7 +47,8 @@ public: void startVoice(Region* region, int delay, int channel, int number, uint8_t value, TriggerType triggerType) noexcept; - void setFileData(std::unique_ptr> file) noexcept; + void expectFileData(unsigned ticket); + void setFileData(std::unique_ptr> file, unsigned ticket) noexcept; void registerNoteOff(int delay, int channel, int noteNumber, uint8_t velocity) noexcept; void registerCC(int delay, int channel, int ccNumber, uint8_t ccValue) noexcept; void registerPitchWheel(int delay, int channel, int pitch) noexcept; @@ -102,6 +103,7 @@ private: std::atomic dataReady { false }; std::unique_ptr> fileData { nullptr }; + unsigned ticket { 0 }; Buffer tempBuffer1; Buffer tempBuffer2;