From 215a5fdb57ce2e7dfccdfc7aae29f954db5ff3b4 Mon Sep 17 00:00:00 2001 From: paulfd Date: Fri, 23 Aug 2019 20:48:44 +0200 Subject: [PATCH] Voice and synth logic --- sources/FilePool.cpp | 24 +++++++++--------------- sources/Synth.h | 19 ++++++++++++------- sources/Voice.h | 35 +++++++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/sources/FilePool.cpp b/sources/FilePool.cpp index 716c239a..d6304380 100644 --- a/sources/FilePool.cpp +++ b/sources/FilePool.cpp @@ -8,16 +8,15 @@ std::optional sfz::FilePool::getFileInformation( std::filesystem::path file { rootDirectory / filename }; if (!std::filesystem::exists(file)) return {}; - - SndfileHandle sndFile ( reinterpret_cast(file.c_str()) ); + + SndfileHandle sndFile(reinterpret_cast(file.c_str())); FileInformation returnedValue; returnedValue.end = static_cast(sndFile.frames()); returnedValue.sampleRate = static_cast(sndFile.samplerate()); SF_INSTRUMENT instrumentInfo; sndFile.command(SFC_GET_INSTRUMENT, &instrumentInfo, sizeof(instrumentInfo)); - if (instrumentInfo.loop_count == 1) - { + if (instrumentInfo.loop_count == 1) { returnedValue.loopBegin = instrumentInfo.loops[0].start; returnedValue.loopEnd = instrumentInfo.loops[0].end; } @@ -34,8 +33,7 @@ std::optional sfz::FilePool::getFileInformation( void sfz::FilePool::enqueueLoading(Voice* voice, std::string_view sample, int numFrames) { - if (!loadingQueue.try_enqueue({ voice, sample, numFrames })) - { + if (!loadingQueue.try_enqueue({ voice, sample, numFrames })) { DBG("Problem enqueuing a file read for file " << sample); } } @@ -43,31 +41,27 @@ void sfz::FilePool::enqueueLoading(Voice* voice, std::string_view sample, int nu void sfz::FilePool::loadingThread() { FileLoadingInformation fileToLoad {}; - while (!quitThread) - { + while (!quitThread) { if (!loadingQueue.wait_dequeue_timed(fileToLoad, 1ms)) continue; - if (fileToLoad.voice == nullptr) - { + if (fileToLoad.voice == nullptr) { DBG("Background thread error: voice is null."); continue; } DBG("Background loading of: " << fileToLoad.sample); std::filesystem::path file { rootDirectory / fileToLoad.sample }; - if (!std::filesystem::exists(file)) - { + if (!std::filesystem::exists(file)) { DBG("Background thread: no file " << fileToLoad.sample << " exists."); continue; } - - SndfileHandle sndFile ( reinterpret_cast(file.c_str()) ); + + SndfileHandle sndFile(reinterpret_cast(file.c_str())); auto fileLoaded = std::make_unique>(fileToLoad.numFrames); auto readBuffer = std::make_unique>(fileToLoad.numFrames * 2); sndFile.readf(readBuffer->data(), fileToLoad.numFrames); fileLoaded->readInterleaved(*readBuffer); fileToLoad.voice->setFileData(std::move(fileLoaded)); } - } \ No newline at end of file diff --git a/sources/Synth.h b/sources/Synth.h index 97a17b82..8d504a92 100644 --- a/sources/Synth.h +++ b/sources/Synth.h @@ -3,6 +3,7 @@ #include "Parser.h" #include "Region.h" #include "SfzHelpers.h" +#include "absl/types/span.h" #include #include #include @@ -36,6 +37,8 @@ public: void renderBlock(StereoBuffer& buffer) { + buffer.fill(0.0f); + for (auto& voice : voices) { voice->renderBlock(tempBuffer); buffer.add(tempBuffer); @@ -45,11 +48,16 @@ public: void noteOn(int delay, int channel, int noteNumber, uint8_t velocity) { auto randValue = getUniform(); - for (auto& voice : voices) - voice->registerNoteOn(delay, channel, noteNumber, velocity); for (auto& region : regions) { if (region->registerNoteOn(channel, noteNumber, velocity, randValue)) { + + for (auto& voice: voices) + { + if (voice->checkOffGroup(delay, region->group)) + noteOff(delay, voice->getTriggerChannel(), voice->getTriggerNumber(), 0); + } + auto voice = findFreeVoice(); if (voice == nullptr) continue; @@ -62,11 +70,8 @@ public: void noteOff(int delay, int channel, int noteNumber, uint8_t velocity) { auto randValue = getUniform(); - for (auto& voice : voices) { - if (voice->registerNoteOff(delay, channel, noteNumber, velocity)) { - // do something - } - } + for (auto& voice : voices) + voice->registerNoteOff(delay, channel, noteNumber, velocity); for (auto& region : regions) { if (region->registerNoteOff(channel, noteNumber, velocity, randValue)) { diff --git a/sources/Voice.h b/sources/Voice.h index b173ac08..1f316ad1 100644 --- a/sources/Voice.h +++ b/sources/Voice.h @@ -32,8 +32,7 @@ public: return (region == nullptr); } - void registerNoteOn(int delay, int channel, int noteNumber, uint8_t velocity); - bool registerNoteOff(int delay, int channel, int noteNumber, uint8_t velocity); + void registerNoteOff(int delay, int channel, int noteNumber, uint8_t velocity); bool registerCC(int delay, int channel, int ccNumber, uint8_t ccValue); void registerPitchWheel(int delay, int channel, int pitch); void registerAftertouch(int delay, int channel, uint8_t aftertouch); @@ -45,6 +44,38 @@ public: buffer.fill(0.0f); } + bool checkOffGroup(int delay [[maybe_unused]], uint32_t group) noexcept + { + if (region != nullptr && triggerType == TriggerType::NoteOn && region->offBy && *region->offBy == group ) + { + // TODO: release + return true; + } + + return false; + } + + int getTriggerNumber() const + { + return triggerNumber; + } + + int getTriggerChannel() const + { + return triggerNumber; + } + + uint8_t getTriggerValue() const + { + return triggerNumber; + } + + TriggerType getTriggerType() const + { + return triggerType; + } + + void reset() { dataReady.store(false);