Added a ticket system so that if the background loader fails to provide the file in time it gets discarded.

This commit is contained in:
paulfd 2019-09-07 17:23:13 +02:00
parent dd08115dc4
commit 32efd60ec9
6 changed files with 36 additions and 19 deletions

View file

@ -85,9 +85,9 @@ std::optional<sfz::FilePool::FileInformation> 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<const char*>(file.c_str()));
auto fileLoaded = std::make_unique<AudioBuffer<float>>(sndFile.channels(), fileToLoad.numFrames);
fileToLoad.voice->setFileData(readFromFile<float>(sndFile, fileToLoad.numFrames));
fileToLoad.voice->setFileData(readFromFile<float>(sndFile, fileToLoad.numFrames), fileToLoad.ticket);
}
}

View file

@ -57,13 +57,14 @@ public:
std::shared_ptr<AudioBuffer<float>> preloadedData;
};
std::optional<FileInformation> 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<FileLoadingInformation> loadingQueue;

View file

@ -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 <algorithm>
@ -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<Opcode>& 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<int, float>(127, 1.0f));
if (region.velocityPoints.front().first != sfz::Default::velocityRange.getStart())
region.velocityPoints.insert(region.velocityPoints.begin(), std::make_pair<int, float>(0, 0.0f));
}
else
{
} else {
if (region.velocityPoints.front().first != sfz::Default::velocityRange.getEnd())
region.velocityPoints.insert(region.velocityPoints.begin(), std::make_pair<int, float>(127, 0.0f));
if (region.velocityPoints.back().first != sfz::Default::velocityRange.getStart())
region.velocityPoints.push_back(std::make_pair<int, float>(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++);
}
}
}
}

View file

@ -96,6 +96,7 @@ private:
float sampleRate { config::defaultSampleRate };
std::uniform_real_distribution<float> randNoteDistribution { 0, 1 };
unsigned fileTicket { 1 };
LEAK_DETECTOR(Synth);
};

View file

@ -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<AudioBuffer<float>> file) noexcept
void sfz::Voice::setFileData(std::unique_ptr<AudioBuffer<float>> 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;
}

View file

@ -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<AudioBuffer<float>> file) noexcept;
void expectFileData(unsigned ticket);
void setFileData(std::unique_ptr<AudioBuffer<float>> 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<bool> dataReady { false };
std::unique_ptr<AudioBuffer<float>> fileData { nullptr };
unsigned ticket { 0 };
Buffer<float> tempBuffer1;
Buffer<float> tempBuffer2;