WIP for Voices

This commit is contained in:
paulfd 2019-08-23 14:16:33 +02:00
parent 7815623115
commit 04181f0d10
5 changed files with 59 additions and 5 deletions

View file

@ -127,4 +127,5 @@ private:
int activeNotesInRange { -1 };
int sequenceCounter { 0 };
};
} // namespace sfz

View file

@ -11,7 +11,7 @@ using CCValueArray = std::array<uint8_t, 128>;
using CCValuePair = std::pair<uint8_t, float> ;
using CCNamePair = std::pair<uint8_t, std::string>;
inline std::optional<uint8_t> readNoteValue(const std::string_view&value)
inline std::optional<uint8_t> readNoteValue(const std::string_view& value)
{
switch(hash(value))
{

View file

@ -127,7 +127,7 @@ bool sfz::Synth::loadSfzFile(const std::filesystem::path& filename)
auto currentRegion = regions.begin();
while (currentRegion <= lastRegion)
{
auto region = &**currentRegion;
auto region = currentRegion->get();
if (region->isGenerator())
{

View file

@ -6,6 +6,7 @@
#include <vector>
#include <set>
#include <optional>
#include <random>
#include <string_view>
namespace sfz
@ -44,16 +45,56 @@ public:
}
}
void noteOn(int delay, int channel, int noteNumber, uint8_t velocity);
void noteOff(int delay, int channel, int noteNumber, uint8_t velocity);
void noteOn(int delay, int channel, int noteNumber, uint8_t velocity)
{
auto randValue = getUniform();
for (auto& region: regions)
{
if (region->registerNoteOn(channel, noteNumber, velocity, randValue))
{
auto voice = findFreeVoice();
if (voice == nullptr)
continue;
voice->startVoice(region.get(), channel, noteNumber, velocity, Voice::TriggerType::NoteOn);
}
}
}
void noteOff(int delay, int channel, int noteNumber, uint8_t velocity)
{
auto randValue = getUniform();
for (auto& region: regions)
{
if (region->registerNoteOff(channel, noteNumber, velocity, randValue))
{
auto voice = findFreeVoice();
if (voice == nullptr)
continue;
voice->startVoice(region.get(), channel, noteNumber, velocity, Voice::TriggerType::NoteOff);
voice->startVoice(region.get(), channel, noteNumber, velocity, Voice::TriggerType::NoteOff);
}
}
}
void cc(int delay, int channel, int ccNumber, uint8_t ccValue);
void pitchWheel(int delay, int channel, int pitch);
void aftertouch(int delay, int channel, uint8_t aftertouch);
void tempo(int delay, float secondsPerQuarter);
protected:
void callback(std::string_view header, std::vector<Opcode> members) final;
private:
Voice* findFreeVoice()
{
auto freeVoice = absl::c_find_if(voices, [](const auto& voice) { return voice->isFree(); });
if (freeVoice == voices.end())
{
DBG("Voices are overloaded, can't start a new note");
return {};
}
return freeVoice->get();
}
bool hasGlobal { false };
bool hasControl { false };
int numGroups { 0 };
@ -81,6 +122,13 @@ private:
StereoBuffer<float> tempBuffer { config::defaultSamplesPerBlock };
int samplesPerBlock { config::defaultSamplesPerBlock };
float sampleRate { config::defaultSampleRate };
std::random_device rd { };
std::mt19937 randomGenerator { rd() };
std::uniform_real_distribution<float> randomDistribution { 0, 1 };
float getUniform()
{
return randomDistribution(randomGenerator);
}
};
}

View file

@ -27,6 +27,11 @@ public:
dataReady.store(true);
}
bool isFree()
{
return (region == nullptr);
}
bool registerNoteOn(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);