One more level of dispatch in the synth

This is in order to be able to trigger note-off regions without killing
all notes of the same group
This commit is contained in:
Paul Ferrand 2019-12-29 23:00:20 +01:00
parent 7aff30f58a
commit 126e4674db
2 changed files with 32 additions and 20 deletions

View file

@ -409,22 +409,7 @@ void sfz::Synth::noteOn(int delay, int noteNumber, uint8_t velocity) noexcept
if (!canEnterCallback)
return;
auto randValue = randNoteDistribution(Random::randomGenerator);
for (auto& region : noteActivationLists[noteNumber]) {
if (region->registerNoteOn(noteNumber, velocity, randValue)) {
for (auto& voice : voices) {
if (voice->checkOffGroup(delay, region->group))
noteOff(delay, voice->getTriggerNumber(), 0);
}
auto voice = findFreeVoice();
if (voice == nullptr)
continue;
voice->startVoice(region, delay, noteNumber, velocity, Voice::TriggerType::NoteOn);
}
}
noteOnDispatch(delay, noteNumber, velocity);
}
void sfz::Synth::noteOff(int delay, int noteNumber, uint8_t velocity [[maybe_unused]]) noexcept
@ -439,19 +424,43 @@ void sfz::Synth::noteOff(int delay, int noteNumber, uint8_t velocity [[maybe_unu
// FIXME: Some keyboards (e.g. Casio PX5S) can send a real note-off velocity. In this case, do we have a
// way in sfz to specify that a release trigger should NOT use the note-on velocity?
// auto replacedVelocity = (velocity == 0 ? sfz::getNoteVelocity(noteNumber) : velocity);
auto replacedVelocity = midiState.getNoteVelocity(noteNumber);
auto randValue = randNoteDistribution(Random::randomGenerator);
const auto replacedVelocity = midiState.getNoteVelocity(noteNumber);
for (auto& voice : voices)
voice->registerNoteOff(delay, noteNumber, replacedVelocity);
noteOffDispatch(delay, noteNumber, replacedVelocity);
}
void sfz::Synth::noteOffDispatch(int delay, int noteNumber, uint8_t velocity) noexcept
{
const auto randValue = randNoteDistribution(Random::randomGenerator);
for (auto& region : noteActivationLists[noteNumber]) {
if (region->registerNoteOff(noteNumber, replacedVelocity, randValue)) {
if (region->registerNoteOff(noteNumber, velocity, randValue)) {
auto voice = findFreeVoice();
if (voice == nullptr)
continue;
voice->startVoice(region, delay, noteNumber, replacedVelocity, Voice::TriggerType::NoteOff);
voice->startVoice(region, delay, noteNumber, velocity, Voice::TriggerType::NoteOff);
}
}
}
void sfz::Synth::noteOnDispatch(int delay, int noteNumber, uint8_t velocity) noexcept
{
const auto randValue = randNoteDistribution(Random::randomGenerator);
for (auto& region : noteActivationLists[noteNumber]) {
if (region->registerNoteOn(noteNumber, velocity, randValue)) {
for (auto& voice : voices) {
if (voice->checkOffGroup(delay, region->group))
noteOffDispatch(delay, voice->getTriggerNumber(), voice->getTriggerValue());
}
auto voice = findFreeVoice();
if (voice == nullptr)
continue;
voice->startVoice(region, delay, noteNumber, velocity, Voice::TriggerType::NoteOn);
}
}
}

View file

@ -413,6 +413,9 @@ private:
fs::file_time_type checkModificationTime();
void noteOnDispatch(int delay, int noteNumber, uint8_t velocity) noexcept;
void noteOffDispatch(int delay, int noteNumber, uint8_t velocity) noexcept;
// Opcode memory; these are used to build regions, as a new region
// will integrate opcodes from the group, master and global block
std::vector<Opcode> globalOpcodes;