diff --git a/src/sfizz/Config.h b/src/sfizz/Config.h index 332b6ea6..63c66ff2 100644 --- a/src/sfizz/Config.h +++ b/src/sfizz/Config.h @@ -49,6 +49,7 @@ namespace config { constexpr float A440 { 440.0 }; constexpr unsigned powerHistoryLength { 16 }; constexpr float voiceStealingThreshold { 0.00001 }; + constexpr int numCCs { 143 }; } // namespace config // Enable or disable SIMD accelerators by default diff --git a/src/sfizz/Defaults.h b/src/sfizz/Defaults.h index a8578536..289dc707 100644 --- a/src/sfizz/Defaults.h +++ b/src/sfizz/Defaults.h @@ -23,6 +23,7 @@ #pragma once #include "Range.h" +#include "Config.h" #include #include @@ -62,7 +63,8 @@ namespace Default // Region logic: MIDI conditions constexpr Range channelRange { 1, 16 }; constexpr Range midiChannelRange { 0, 15 }; - constexpr Range ccRange { 0, 127 }; + constexpr Range ccNumberRange { 0, config::numCCs }; + constexpr Range ccValueRange { 0, 127 }; constexpr uint8_t cc { 0 }; constexpr Range bendRange { -8192, 8192 }; constexpr int bend { 0 }; diff --git a/src/sfizz/MidiState.cpp b/src/sfizz/MidiState.cpp index 1ee9bb35..50ddb6be 100644 --- a/src/sfizz/MidiState.cpp +++ b/src/sfizz/MidiState.cpp @@ -58,7 +58,7 @@ int sfz::MidiState::getPitchBend(int channel) const noexcept void sfz::MidiState::ccEvent(int channel, int ccNumber, uint8_t ccValue) noexcept { ASSERT(channel >= 0 && channel < 16); - ASSERT(ccNumber >= 0 && ccNumber <= 142); + ASSERT(ccNumber >= 0 && ccNumber < config::numCCs); ASSERT(ccValue >= 0 && ccValue <= 127); cc[channel][ccNumber] = ccValue; @@ -67,7 +67,7 @@ void sfz::MidiState::ccEvent(int channel, int ccNumber, uint8_t ccValue) noexcep uint8_t sfz::MidiState::getCCValue(int channel, int ccNumber) const noexcept { ASSERT(channel >= 0 && channel < 16); - ASSERT(ccNumber >= 0 && ccNumber <= 127); + ASSERT(ccNumber >= 0 && ccNumber < config::numCCs); return cc[channel][ccNumber]; } diff --git a/src/sfizz/Opcode.h b/src/sfizz/Opcode.h index 45011a82..b0046727 100644 --- a/src/sfizz/Opcode.h +++ b/src/sfizz/Opcode.h @@ -203,7 +203,7 @@ template inline void setCCPairFromOpcode(const Opcode& opcode, absl::optional& target, const Range& validRange) { auto value = readOpcode(opcode.value, validRange); - if (value && opcode.parameter && Default::ccRange.containsWithEnd(*opcode.parameter)) + if (value && opcode.parameter && Default::ccNumberRange.containsWithEnd(*opcode.parameter)) target = std::make_pair(*opcode.parameter, *value); else target = {}; diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index 77b61d17..edbfd06c 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -35,7 +35,7 @@ bool sfz::Region::parseOpcode(const Opcode& opcode) { // Check that the parameter is well formed - if (opcode.parameter && !sfz::Default::ccRange.containsWithEnd(*opcode.parameter)) { + if (opcode.parameter && !sfz::Default::ccNumberRange.containsWithEnd(*opcode.parameter)) { DBG("Wrong parameter value (" << std::to_string(*opcode.parameter) << ") for opcode " << opcode.opcode); return false; } @@ -164,12 +164,12 @@ bool sfz::Region::parseOpcode(const Opcode& opcode) break; case hash("locc"): if (opcode.parameter) { - setRangeStartFromOpcode(opcode, ccConditions[*opcode.parameter], Default::ccRange); + setRangeStartFromOpcode(opcode, ccConditions[*opcode.parameter], Default::ccValueRange); } break; case hash("hicc"): if (opcode.parameter) - setRangeEndFromOpcode(opcode, ccConditions[*opcode.parameter], Default::ccRange); + setRangeEndFromOpcode(opcode, ccConditions[*opcode.parameter], Default::ccValueRange); break; case hash("sw_lokey"): setRangeStartFromOpcode(opcode, keyswitchRange, Default::keyRange); @@ -261,11 +261,11 @@ bool sfz::Region::parseOpcode(const Opcode& opcode) break; case hash("on_locc"): if (opcode.parameter) - setRangeStartFromOpcode(opcode, ccTriggers[*opcode.parameter], Default::ccRange); + setRangeStartFromOpcode(opcode, ccTriggers[*opcode.parameter], Default::ccTriggerValueRange); break; case hash("on_hicc"): if (opcode.parameter) - setRangeEndFromOpcode(opcode, ccTriggers[*opcode.parameter], Default::ccRange); + setRangeEndFromOpcode(opcode, ccTriggers[*opcode.parameter], Default::ccTriggerValueRange); break; // Performance parameters: amplifier @@ -315,7 +315,7 @@ bool sfz::Region::parseOpcode(const Opcode& opcode) volumeDistribution.param(std::uniform_real_distribution::param_type(-ampRandom, ampRandom)); break; case hash("amp_velcurve_"): - if (opcode.parameter && Default::ccRange.containsWithEnd(*opcode.parameter)) { + { auto value = readOpcode(opcode.value, Default::ampVelcurveRange); if (value) velocityPoints.emplace_back(*opcode.parameter, *value); @@ -371,22 +371,22 @@ bool sfz::Region::parseOpcode(const Opcode& opcode) break; case hash("xfin_locc"): if (opcode.parameter) { - setRangeStartFromOpcode(opcode, crossfadeCCInRange[*opcode.parameter], Default::ccRange); + setRangeStartFromOpcode(opcode, crossfadeCCInRange[*opcode.parameter], Default::ccValueRange); } break; case hash("xfin_hicc"): if (opcode.parameter) { - setRangeEndFromOpcode(opcode, crossfadeCCInRange[*opcode.parameter], Default::velocityRange); + setRangeEndFromOpcode(opcode, crossfadeCCInRange[*opcode.parameter], Default::ccValueRange); } break; case hash("xfout_locc"): if (opcode.parameter) { - setRangeStartFromOpcode(opcode, crossfadeCCOutRange[*opcode.parameter], Default::velocityRange); + setRangeStartFromOpcode(opcode, crossfadeCCOutRange[*opcode.parameter], Default::ccValueRange); } break; case hash("xfout_hicc"): if (opcode.parameter) { - setRangeEndFromOpcode(opcode, crossfadeCCOutRange[*opcode.parameter], Default::velocityRange); + setRangeEndFromOpcode(opcode, crossfadeCCOutRange[*opcode.parameter], Default::ccValueRange); } break; case hash("xf_cccurve"): diff --git a/src/sfizz/Region.h b/src/sfizz/Region.h index 9b6eb81e..310d985f 100644 --- a/src/sfizz/Region.h +++ b/src/sfizz/Region.h @@ -249,7 +249,7 @@ struct Region { // Region logic: MIDI conditions Range channelRange { Default::midiChannelRange }; //lochan and hichan Range bendRange { Default::bendRange }; // hibend and lobend - CCMap> ccConditions { Default::ccRange }; + CCMap> ccConditions { Default::ccValueRange }; Range keyswitchRange { Default::keyRange }; // sw_hikey and sw_lokey absl::optional keyswitch {}; // sw_last absl::optional keyswitchUp {}; // sw_up diff --git a/src/sfizz/SfzHelpers.h b/src/sfizz/SfzHelpers.h index 5ea4262d..a708fe32 100644 --- a/src/sfizz/SfzHelpers.h +++ b/src/sfizz/SfzHelpers.h @@ -27,11 +27,12 @@ //#include #include #include +#include "Config.h" namespace sfz { -using SfzCCArray = std::array; +using SfzCCArray = std::array; using CCValuePair = std::pair ; using CCNamePair = std::pair; diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index fba33cc8..8bae75ad 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -166,15 +166,16 @@ void sfz::Synth::handleControlOpcodes(const std::vector& members) case hash("Set_cc"): [[fallthrough]]; case hash("set_cc"): - if (member.parameter && Default::ccRange.containsWithEnd(*member.parameter)){ - for (int channel=1; channel <=16; channel++) - midiState.ccEvent(channel, *member.parameter, readOpcode(member.value, Default::ccRange).value_or(0)); + if (member.parameter && Default::ccNumberRange.containsWithEnd(*member.parameter)) { + const auto ccValue = readOpcode(member.value, Default::ccValueRange).value_or(0); + for (int channel = 0; channel < 16; channel++) + midiState.ccEvent(channel, *member.parameter, ccValue); } break; case hash("Label_cc"): [[fallthrough]]; case hash("label_cc"): - if (member.parameter && Default::ccRange.containsWithEnd(*member.parameter)) + if (member.parameter && Default::ccNumberRange.containsWithEnd(*member.parameter)) ccNames.emplace_back(*member.parameter, member.value); break; case hash("Default_path"): diff --git a/src/sfizz/Synth.h b/src/sfizz/Synth.h index bda482c3..6c3241f8 100644 --- a/src/sfizz/Synth.h +++ b/src/sfizz/Synth.h @@ -345,6 +345,8 @@ public: * */ void disableFreeWheeling() noexcept; + + const MidiState& getMidiState() const noexcept { return midiState; } protected: /** * @brief The parser callback; this is called by the parent object each time