diff --git a/src/sfizz/MidiState.h b/src/sfizz/MidiState.h index 0315b30a..a6183f0d 100644 --- a/src/sfizz/MidiState.h +++ b/src/sfizz/MidiState.h @@ -8,6 +8,8 @@ #include #include #include "SfzHelpers.h" +#include "CCMap.h" +#include "Range.h" namespace sfz { @@ -103,6 +105,26 @@ public: */ void resetAllControllers() noexcept; + /** + * @brief Modulate a value using the last entered CCs in the midiState + * + * @tparam T + * @tparam U + * @param value the base value + * @param modifiers the list of CC modifiers + * @param validRange a range to clamp the output + * @param lambda the function to apply for each modifier + * @return T + */ + template + T modulate(T value, const CCMap& modifiers, const Range& validRange, const modFunction& lambda = addToBase) const noexcept + { + for (auto& mod: modifiers) { + lambda(value, getCCValue(mod.first) * mod.second); + } + return validRange.clamp(value); + } + private: template using MidiNoteArray = std::array; diff --git a/src/sfizz/SfzHelpers.h b/src/sfizz/SfzHelpers.h index 71d3c4f1..1e590d1b 100644 --- a/src/sfizz/SfzHelpers.h +++ b/src/sfizz/SfzHelpers.h @@ -172,5 +172,37 @@ bool findDefine(absl::string_view line, absl::string_view& variable, absl::strin */ bool findInclude(absl::string_view line, std::string& path); +/** + * @brief Defines a function that modulates a base value with another one + * + * @tparam T + */ +template +using modFunction = std::function; + +/** + * @brief Modulation helper that adds the modifier to the base value + * + * @tparam T + * @param base the base value + * @param modifier the modifier value + */ +template +constexpr void addToBase(T& base, T modifier) +{ + base += modifier; +} + +/** + * @brief multiply a value by a factor, in cents. To be used for pitch variations. + * + * @param base + * @param modifier + */ +constexpr void multiplyByCents(float& base, int modifier) +{ + base *= centsFactor(modifier); +} + } // namespace sfz