Use float internally in the voices
This commit is contained in:
parent
601126db0d
commit
e7686d233e
7 changed files with 47 additions and 44 deletions
|
|
@ -43,7 +43,7 @@ namespace config {
|
||||||
constexpr int allNotesOffCC { 123 };
|
constexpr int allNotesOffCC { 123 };
|
||||||
constexpr int omniOffCC { 124 };
|
constexpr int omniOffCC { 124 };
|
||||||
constexpr int omniOnCC { 125 };
|
constexpr int omniOnCC { 125 };
|
||||||
constexpr int halfCCThreshold { 64 };
|
constexpr float halfCCThreshold { 0.5f };
|
||||||
constexpr int centPerSemitone { 100 };
|
constexpr int centPerSemitone { 100 };
|
||||||
constexpr float virtuallyZero { 0.00005f };
|
constexpr float virtuallyZero { 0.00005f };
|
||||||
constexpr float fastReleaseDuration { 0.01f };
|
constexpr float fastReleaseDuration { 0.01f };
|
||||||
|
|
|
||||||
|
|
@ -902,6 +902,7 @@ bool sfz::Region::registerCC(int ccNumber, uint8_t ccValue) noexcept
|
||||||
|
|
||||||
bool sfz::Region::registerCCNormalized(int ccNumber, float ccValue) noexcept
|
bool sfz::Region::registerCCNormalized(int ccNumber, float ccValue) noexcept
|
||||||
{
|
{
|
||||||
|
ASSERT(ccValue >= 0.0f && ccValue <= 1.0f);
|
||||||
if (ccConditions.getWithDefault(ccNumber).containsWithEnd(ccValue))
|
if (ccConditions.getWithDefault(ccNumber).containsWithEnd(ccValue))
|
||||||
ccSwitched.set(ccNumber, true);
|
ccSwitched.set(ccNumber, true);
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -523,7 +523,7 @@ void multiplyAdd<float, true>(absl::Span<const float> gain, absl::Span<const flo
|
||||||
template <class T, bool SIMD = SIMDConfig::multiplyAdd>
|
template <class T, bool SIMD = SIMDConfig::multiplyAdd>
|
||||||
void multiplyAdd(const T gain, absl::Span<const T> input, absl::Span<T> output) noexcept
|
void multiplyAdd(const T gain, absl::Span<const T> input, absl::Span<T> output) noexcept
|
||||||
{
|
{
|
||||||
ASSERT(input.size() <= output.size());
|
// ASSERT(input.size() <= output.size());
|
||||||
auto* in = input.begin();
|
auto* in = input.begin();
|
||||||
auto* out = output.begin();
|
auto* out = output.begin();
|
||||||
auto* sentinel = out + std::min(output.size(), input.size());
|
auto* sentinel = out + std::min(output.size(), input.size());
|
||||||
|
|
|
||||||
|
|
@ -600,15 +600,15 @@ void sfz::Synth::noteOn(int delay, int noteNumber, uint8_t velocity) noexcept
|
||||||
{
|
{
|
||||||
ASSERT(noteNumber < 128);
|
ASSERT(noteNumber < 128);
|
||||||
ASSERT(noteNumber >= 0);
|
ASSERT(noteNumber >= 0);
|
||||||
|
const auto normalizedVelocity = normalizeVelocity(velocity);
|
||||||
ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration };
|
ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration };
|
||||||
resources.midiState.noteOnEvent(delay, noteNumber, velocity);
|
resources.midiState.noteOnEventNormalized(delay, noteNumber, normalizedVelocity);
|
||||||
|
|
||||||
AtomicGuard callbackGuard { inCallback };
|
AtomicGuard callbackGuard { inCallback };
|
||||||
if (!canEnterCallback)
|
if (!canEnterCallback)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
noteOnDispatch(delay, noteNumber, velocity);
|
noteOnDispatch(delay, noteNumber, normalizedVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Synth::noteOff(int delay, int noteNumber, uint8_t velocity) noexcept
|
void sfz::Synth::noteOff(int delay, int noteNumber, uint8_t velocity) noexcept
|
||||||
|
|
@ -627,7 +627,7 @@ void sfz::Synth::noteOff(int delay, int noteNumber, uint8_t velocity) noexcept
|
||||||
// FIXME: Some keyboards (e.g. Casio PX5S) can send a real note-off velocity. In this case, do we have a
|
// 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?
|
// 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 = (velocity == 0 ? sfz::getNoteVelocity(noteNumber) : velocity);
|
||||||
const auto replacedVelocity = resources.midiState.getNoteVelocity(noteNumber);
|
const auto replacedVelocity = resources.midiState.getNoteVelocityNormalized(noteNumber);
|
||||||
|
|
||||||
for (auto& voice : voices)
|
for (auto& voice : voices)
|
||||||
voice->registerNoteOff(delay, noteNumber, replacedVelocity);
|
voice->registerNoteOff(delay, noteNumber, replacedVelocity);
|
||||||
|
|
@ -635,11 +635,11 @@ void sfz::Synth::noteOff(int delay, int noteNumber, uint8_t velocity) noexcept
|
||||||
noteOffDispatch(delay, noteNumber, replacedVelocity);
|
noteOffDispatch(delay, noteNumber, replacedVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Synth::noteOffDispatch(int delay, int noteNumber, uint8_t velocity) noexcept
|
void sfz::Synth::noteOffDispatch(int delay, int noteNumber, float velocity) noexcept
|
||||||
{
|
{
|
||||||
const auto randValue = randNoteDistribution(Random::randomGenerator);
|
const auto randValue = randNoteDistribution(Random::randomGenerator);
|
||||||
for (auto& region : noteActivationLists[noteNumber]) {
|
for (auto& region : noteActivationLists[noteNumber]) {
|
||||||
if (region->registerNoteOff(noteNumber, velocity, randValue)) {
|
if (region->registerNoteOffNormalized(noteNumber, velocity, randValue)) {
|
||||||
auto voice = findFreeVoice();
|
auto voice = findFreeVoice();
|
||||||
if (voice == nullptr)
|
if (voice == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -649,11 +649,11 @@ void sfz::Synth::noteOffDispatch(int delay, int noteNumber, uint8_t velocity) no
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Synth::noteOnDispatch(int delay, int noteNumber, uint8_t velocity) noexcept
|
void sfz::Synth::noteOnDispatch(int delay, int noteNumber, float velocity) noexcept
|
||||||
{
|
{
|
||||||
const auto randValue = randNoteDistribution(Random::randomGenerator);
|
const auto randValue = randNoteDistribution(Random::randomGenerator);
|
||||||
for (auto& region : noteActivationLists[noteNumber]) {
|
for (auto& region : noteActivationLists[noteNumber]) {
|
||||||
if (region->registerNoteOn(noteNumber, velocity, randValue)) {
|
if (region->registerNoteOnNormalized(noteNumber, velocity, randValue)) {
|
||||||
for (auto& voice : voices) {
|
for (auto& voice : voices) {
|
||||||
if (voice->checkOffGroup(delay, region->group))
|
if (voice->checkOffGroup(delay, region->group))
|
||||||
noteOffDispatch(delay, voice->getTriggerNumber(), voice->getTriggerValue());
|
noteOffDispatch(delay, voice->getTriggerNumber(), voice->getTriggerValue());
|
||||||
|
|
@ -672,9 +672,10 @@ void sfz::Synth::cc(int delay, int ccNumber, uint8_t ccValue) noexcept
|
||||||
{
|
{
|
||||||
ASSERT(ccNumber < config::numCCs);
|
ASSERT(ccNumber < config::numCCs);
|
||||||
ASSERT(ccNumber >= 0);
|
ASSERT(ccNumber >= 0);
|
||||||
|
const auto normalizedCC = normalizeCC(ccValue);
|
||||||
|
|
||||||
ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration };
|
ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration };
|
||||||
resources.midiState.ccEvent(delay, ccNumber, ccValue);
|
resources.midiState.ccEventNormalized(delay, ccNumber, normalizedCC);
|
||||||
|
|
||||||
AtomicGuard callbackGuard { inCallback };
|
AtomicGuard callbackGuard { inCallback };
|
||||||
if (!canEnterCallback)
|
if (!canEnterCallback)
|
||||||
|
|
@ -686,7 +687,7 @@ void sfz::Synth::cc(int delay, int ccNumber, uint8_t ccValue) noexcept
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& voice : voices)
|
for (auto& voice : voices)
|
||||||
voice->registerCC(delay, ccNumber, ccValue);
|
voice->registerCC(delay, ccNumber, normalizedCC);
|
||||||
|
|
||||||
for (auto& region : ccActivationLists[ccNumber]) {
|
for (auto& region : ccActivationLists[ccNumber]) {
|
||||||
if (region->registerCC(ccNumber, ccValue)) {
|
if (region->registerCC(ccNumber, ccValue)) {
|
||||||
|
|
@ -694,7 +695,7 @@ void sfz::Synth::cc(int delay, int ccNumber, uint8_t ccValue) noexcept
|
||||||
if (voice == nullptr)
|
if (voice == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
voice->startVoice(region, delay, ccNumber, ccValue, Voice::TriggerType::CC);
|
voice->startVoice(region, delay, ccNumber, normalizedCC, Voice::TriggerType::CC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -952,12 +953,12 @@ void sfz::Synth::resetAllControllers(int delay) noexcept
|
||||||
for (auto& voice : voices) {
|
for (auto& voice : voices) {
|
||||||
voice->registerPitchWheel(delay, 0);
|
voice->registerPitchWheel(delay, 0);
|
||||||
for (unsigned cc = 0; cc < config::numCCs; ++cc)
|
for (unsigned cc = 0; cc < config::numCCs; ++cc)
|
||||||
voice->registerCC(delay, cc, 0);
|
voice->registerCC(delay, cc, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& region : regions) {
|
for (auto& region : regions) {
|
||||||
for (unsigned cc = 0; cc < config::numCCs; ++cc)
|
for (unsigned cc = 0; cc < config::numCCs; ++cc)
|
||||||
region->registerCC(cc, 0);
|
region->registerCCNormalized(cc, 0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -463,8 +463,8 @@ private:
|
||||||
|
|
||||||
fs::file_time_type checkModificationTime();
|
fs::file_time_type checkModificationTime();
|
||||||
|
|
||||||
void noteOnDispatch(int delay, int noteNumber, uint8_t velocity) noexcept;
|
void noteOnDispatch(int delay, int noteNumber, float velocity) noexcept;
|
||||||
void noteOffDispatch(int delay, int noteNumber, uint8_t velocity) noexcept;
|
void noteOffDispatch(int delay, int noteNumber, float velocity) noexcept;
|
||||||
|
|
||||||
// Opcode memory; these are used to build regions, as a new region
|
// Opcode memory; these are used to build regions, as a new region
|
||||||
// will integrate opcodes from the group, master and global block
|
// will integrate opcodes from the group, master and global block
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,10 @@ sfz::Voice::Voice(sfz::Resources& resources)
|
||||||
waveOscillator.init(sampleRate);
|
waveOscillator.init(sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::startVoice(Region* region, int delay, int number, uint8_t value, sfz::Voice::TriggerType triggerType) noexcept
|
void sfz::Voice::startVoice(Region* region, int delay, int number, float value, sfz::Voice::TriggerType triggerType) noexcept
|
||||||
{
|
{
|
||||||
|
ASSERT(value >= 0.0f && value <= 1.0f);
|
||||||
|
|
||||||
this->triggerType = triggerType;
|
this->triggerType = triggerType;
|
||||||
triggerNumber = number;
|
triggerNumber = number;
|
||||||
triggerValue = value;
|
triggerValue = value;
|
||||||
|
|
@ -71,22 +73,21 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, uint8_t value
|
||||||
}
|
}
|
||||||
speedRatio = static_cast<float>(currentPromise->sampleRate / this->sampleRate);
|
speedRatio = static_cast<float>(currentPromise->sampleRate / this->sampleRate);
|
||||||
}
|
}
|
||||||
|
pitchRatio = region->getBasePitchVariationNormalized(number, value);
|
||||||
pitchRatio = region->getBasePitchVariation(number, value);
|
|
||||||
|
|
||||||
baseVolumedB = region->getBaseVolumedB(number);
|
baseVolumedB = region->getBaseVolumedB(number);
|
||||||
auto volumedB = baseVolumedB;
|
auto volumedB = baseVolumedB;
|
||||||
if (region->volumeCC)
|
if (region->volumeCC)
|
||||||
volumedB += normalizeCC(resources.midiState.getCCValue(region->volumeCC->cc)) * region->volumeCC->value;
|
volumedB += resources.midiState.getCCValueNormalized(region->volumeCC->cc) * region->volumeCC->value;
|
||||||
volumeEnvelope.reset(db2mag(Default::volumeRange.clamp(volumedB)));
|
volumeEnvelope.reset(db2mag(Default::volumeRange.clamp(volumedB)));
|
||||||
|
|
||||||
baseGain = region->getBaseGain();
|
baseGain = region->getBaseGain();
|
||||||
if (triggerType != TriggerType::CC)
|
if (triggerType != TriggerType::CC)
|
||||||
baseGain *= region->getNoteGain(number, value);
|
baseGain *= region->getNoteGainNormalized(number, value);
|
||||||
|
|
||||||
float gain { baseGain };
|
float gain { baseGain };
|
||||||
if (region->amplitudeCC)
|
if (region->amplitudeCC)
|
||||||
gain += normalizeCC(resources.midiState.getCCValue(region->amplitudeCC->cc)) * normalizePercents(region->amplitudeCC->value);
|
gain += resources.midiState.getCCValueNormalized(region->amplitudeCC->cc) * normalizePercents(region->amplitudeCC->value);
|
||||||
amplitudeEnvelope.reset(Default::normalizedRange.clamp(gain));
|
amplitudeEnvelope.reset(Default::normalizedRange.clamp(gain));
|
||||||
|
|
||||||
float crossfadeGain { region->getCrossfadeGain() };
|
float crossfadeGain { region->getCrossfadeGain() };
|
||||||
|
|
@ -95,19 +96,19 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, uint8_t value
|
||||||
basePan = normalizePercents(region->pan);
|
basePan = normalizePercents(region->pan);
|
||||||
auto pan = basePan;
|
auto pan = basePan;
|
||||||
if (region->panCC)
|
if (region->panCC)
|
||||||
pan += normalizeCC(resources.midiState.getCCValue(region->panCC->cc)) * normalizePercents(region->panCC->value);
|
pan += resources.midiState.getCCValueNormalized(region->panCC->cc) * normalizePercents(region->panCC->value);
|
||||||
panEnvelope.reset(Default::symmetricNormalizedRange.clamp(pan));
|
panEnvelope.reset(Default::symmetricNormalizedRange.clamp(pan));
|
||||||
|
|
||||||
basePosition = normalizePercents(region->position);
|
basePosition = normalizePercents(region->position);
|
||||||
auto position = basePosition;
|
auto position = basePosition;
|
||||||
if (region->positionCC)
|
if (region->positionCC)
|
||||||
position += normalizeCC(resources.midiState.getCCValue(region->positionCC->cc)) * normalizePercents(region->positionCC->value);
|
position += resources.midiState.getCCValueNormalized(region->positionCC->cc) * normalizePercents(region->positionCC->value);
|
||||||
positionEnvelope.reset(Default::symmetricNormalizedRange.clamp(position));
|
positionEnvelope.reset(Default::symmetricNormalizedRange.clamp(position));
|
||||||
|
|
||||||
baseWidth = normalizePercents(region->width);
|
baseWidth = normalizePercents(region->width);
|
||||||
auto width = baseWidth;
|
auto width = baseWidth;
|
||||||
if (region->widthCC)
|
if (region->widthCC)
|
||||||
width += normalizeCC(resources.midiState.getCCValue(region->widthCC->cc)) * normalizePercents(region->widthCC->value);
|
width += resources.midiState.getCCValueNormalized(region->widthCC->cc) * normalizePercents(region->widthCC->value);
|
||||||
widthEnvelope.reset(Default::symmetricNormalizedRange.clamp(width));
|
widthEnvelope.reset(Default::symmetricNormalizedRange.clamp(width));
|
||||||
|
|
||||||
pitchBendEnvelope.setFunction([region](float pitchValue){
|
pitchBendEnvelope.setFunction([region](float pitchValue){
|
||||||
|
|
@ -123,13 +124,13 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, uint8_t value
|
||||||
|
|
||||||
const unsigned numChannels = region->isStereo ? 2 : 1;
|
const unsigned numChannels = region->isStereo ? 2 : 1;
|
||||||
for (auto& filter: region->filters) {
|
for (auto& filter: region->filters) {
|
||||||
auto newFilter = resources.filterPool.getFilter(filter, numChannels, number, value);
|
auto newFilter = resources.filterPool.getFilter(filter, numChannels, number, denormalize7Bits<uint8_t>(value));
|
||||||
if (newFilter)
|
if (newFilter)
|
||||||
filters.push_back(newFilter);
|
filters.push_back(newFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& eq: region->equalizers) {
|
for (auto& eq: region->equalizers) {
|
||||||
auto newEQ = resources.eqPool.getEQ(eq, numChannels, value);
|
auto newEQ = resources.eqPool.getEQ(eq, numChannels, denormalize7Bits<uint8_t>(value));
|
||||||
if (newEQ)
|
if (newEQ)
|
||||||
equalizers.push_back(newEQ);
|
equalizers.push_back(newEQ);
|
||||||
}
|
}
|
||||||
|
|
@ -139,7 +140,7 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, uint8_t value
|
||||||
initialDelay = delay + static_cast<int>(region->getDelay() * sampleRate);
|
initialDelay = delay + static_cast<int>(region->getDelay() * sampleRate);
|
||||||
baseFrequency = midiNoteFrequency(number);
|
baseFrequency = midiNoteFrequency(number);
|
||||||
bendStepFactor = centsFactor(region->bendStep);
|
bendStepFactor = centsFactor(region->bendStep);
|
||||||
egEnvelope.reset(*region, resources.midiState, delay, value, sampleRate);
|
egEnvelope.reset(*region, resources.midiState, delay, denormalize7Bits<uint8_t>(value), sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sfz::Voice::isFree() const noexcept
|
bool sfz::Voice::isFree() const noexcept
|
||||||
|
|
@ -159,7 +160,7 @@ void sfz::Voice::release(int delay, bool fastRelease) noexcept
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::registerNoteOff(int delay, int noteNumber, uint8_t velocity) noexcept
|
void sfz::Voice::registerNoteOff(int delay, int noteNumber, float velocity) noexcept
|
||||||
{
|
{
|
||||||
UNUSED(velocity);
|
UNUSED(velocity);
|
||||||
if (region == nullptr)
|
if (region == nullptr)
|
||||||
|
|
@ -174,12 +175,12 @@ void sfz::Voice::registerNoteOff(int delay, int noteNumber, uint8_t velocity) no
|
||||||
if (region->loopMode == SfzLoopMode::one_shot)
|
if (region->loopMode == SfzLoopMode::one_shot)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!region->checkSustain || resources.midiState.getCCValue(config::sustainCC) < config::halfCCThreshold)
|
if (!region->checkSustain || resources.midiState.getCCValueNormalized(config::sustainCC) < config::halfCCThreshold)
|
||||||
release(delay);
|
release(delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::registerCC(int delay, int ccNumber, uint8_t ccValue) noexcept
|
void sfz::Voice::registerCC(int delay, int ccNumber, float ccValue) noexcept
|
||||||
{
|
{
|
||||||
if (region == nullptr)
|
if (region == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
@ -200,27 +201,27 @@ void sfz::Voice::registerCC(int delay, int ccNumber, uint8_t ccValue) noexcept
|
||||||
delay = max(delay, minEnvelopeDelay);
|
delay = max(delay, minEnvelopeDelay);
|
||||||
|
|
||||||
if (region->amplitudeCC && ccNumber == region->amplitudeCC->cc) {
|
if (region->amplitudeCC && ccNumber == region->amplitudeCC->cc) {
|
||||||
const float newGain { baseGain + normalizeCC(ccValue) * normalizePercents(region->amplitudeCC->value) };
|
const float newGain { baseGain + ccValue * normalizePercents(region->amplitudeCC->value) };
|
||||||
amplitudeEnvelope.registerEvent(delay, Default::normalizedRange.clamp(newGain));
|
amplitudeEnvelope.registerEvent(delay, Default::normalizedRange.clamp(newGain));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (region->volumeCC && ccNumber == region->volumeCC->cc) {
|
if (region->volumeCC && ccNumber == region->volumeCC->cc) {
|
||||||
const float newVolumedB { baseVolumedB + normalizeCC(ccValue) * region->volumeCC->value };
|
const float newVolumedB { baseVolumedB + ccValue * region->volumeCC->value };
|
||||||
volumeEnvelope.registerEvent(delay, db2mag(Default::volumeRange.clamp(newVolumedB)));
|
volumeEnvelope.registerEvent(delay, db2mag(Default::volumeRange.clamp(newVolumedB)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (region->panCC && ccNumber == region->panCC->cc) {
|
if (region->panCC && ccNumber == region->panCC->cc) {
|
||||||
const float newPan { basePan + normalizeCC(ccValue) * normalizePercents(region->panCC->value) };
|
const float newPan { basePan + ccValue * normalizePercents(region->panCC->value) };
|
||||||
panEnvelope.registerEvent(delay, Default::symmetricNormalizedRange.clamp(newPan));
|
panEnvelope.registerEvent(delay, Default::symmetricNormalizedRange.clamp(newPan));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (region->positionCC && ccNumber == region->positionCC->cc) {
|
if (region->positionCC && ccNumber == region->positionCC->cc) {
|
||||||
const float newPosition { basePosition + normalizeCC(ccValue) * normalizePercents(region->positionCC->value) };
|
const float newPosition { basePosition + ccValue * normalizePercents(region->positionCC->value) };
|
||||||
positionEnvelope.registerEvent(delay, Default::symmetricNormalizedRange.clamp(newPosition));
|
positionEnvelope.registerEvent(delay, Default::symmetricNormalizedRange.clamp(newPosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (region->widthCC && ccNumber == region->widthCC->cc) {
|
if (region->widthCC && ccNumber == region->widthCC->cc) {
|
||||||
const float newWidth { baseWidth + normalizeCC(ccValue) * normalizePercents(region->widthCC->value) };
|
const float newWidth { baseWidth + ccValue * normalizePercents(region->widthCC->value) };
|
||||||
widthEnvelope.registerEvent(delay, Default::symmetricNormalizedRange.clamp(newWidth));
|
widthEnvelope.registerEvent(delay, Default::symmetricNormalizedRange.clamp(newWidth));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -552,7 +553,7 @@ int sfz::Voice::getTriggerNumber() const noexcept
|
||||||
return triggerNumber;
|
return triggerNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t sfz::Voice::getTriggerValue() const noexcept
|
float sfz::Voice::getTriggerValue() const noexcept
|
||||||
{
|
{
|
||||||
return triggerValue;
|
return triggerValue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ public:
|
||||||
* @param value
|
* @param value
|
||||||
* @param triggerType
|
* @param triggerType
|
||||||
*/
|
*/
|
||||||
void startVoice(Region* region, int delay, int number, uint8_t value, TriggerType triggerType) noexcept;
|
void startVoice(Region* region, int delay, int number, float value, TriggerType triggerType) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Register a note-off event; this may trigger a release.
|
* @brief Register a note-off event; this may trigger a release.
|
||||||
|
|
@ -90,7 +90,7 @@ public:
|
||||||
* @param noteNumber
|
* @param noteNumber
|
||||||
* @param velocity
|
* @param velocity
|
||||||
*/
|
*/
|
||||||
void registerNoteOff(int delay, int noteNumber, uint8_t velocity) noexcept;
|
void registerNoteOff(int delay, int noteNumber, float velocity) noexcept;
|
||||||
/**
|
/**
|
||||||
* @brief Register a CC event; this may trigger a release. If the voice is playing and its
|
* @brief Register a CC event; this may trigger a release. If the voice is playing and its
|
||||||
* region has CC modifiers, it will use this value to compute the CC envelope to apply to the
|
* region has CC modifiers, it will use this value to compute the CC envelope to apply to the
|
||||||
|
|
@ -100,7 +100,7 @@ public:
|
||||||
* @param ccNumber
|
* @param ccNumber
|
||||||
* @param ccValue
|
* @param ccValue
|
||||||
*/
|
*/
|
||||||
void registerCC(int delay, int ccNumber, uint8_t ccValue) noexcept;
|
void registerCC(int delay, int ccNumber, float ccValue) noexcept;
|
||||||
/**
|
/**
|
||||||
* @brief Register a pitch wheel event; for now this does nothing
|
* @brief Register a pitch wheel event; for now this does nothing
|
||||||
*
|
*
|
||||||
|
|
@ -163,9 +163,9 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Get the value that triggered the voice (note velocity or cc value)
|
* @brief Get the value that triggered the voice (note velocity or cc value)
|
||||||
*
|
*
|
||||||
* @return uint8_t
|
* @return float
|
||||||
*/
|
*/
|
||||||
uint8_t getTriggerValue() const noexcept;
|
float getTriggerValue() const noexcept;
|
||||||
/**
|
/**
|
||||||
* @brief Get the type of trigger
|
* @brief Get the type of trigger
|
||||||
*
|
*
|
||||||
|
|
@ -261,7 +261,7 @@ private:
|
||||||
|
|
||||||
TriggerType triggerType;
|
TriggerType triggerType;
|
||||||
int triggerNumber;
|
int triggerNumber;
|
||||||
uint8_t triggerValue;
|
float triggerValue;
|
||||||
absl::optional<int> triggerDelay;
|
absl::optional<int> triggerDelay;
|
||||||
|
|
||||||
float speedRatio { 1.0 };
|
float speedRatio { 1.0 };
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue