WIP
This commit is contained in:
parent
293e7a935f
commit
9a1e3971a9
10 changed files with 113 additions and 81 deletions
|
|
@ -137,7 +137,6 @@ set(SFIZZ_SOURCES
|
|||
sfizz/Wavetables.cpp
|
||||
sfizz/Tuning.cpp
|
||||
sfizz/RegionSet.cpp
|
||||
sfizz/Defaults.cpp
|
||||
sfizz/PolyphonyGroup.cpp
|
||||
sfizz/VoiceManager.cpp
|
||||
sfizz/VoiceStealing.cpp
|
||||
|
|
@ -201,6 +200,7 @@ set(SFIZZ_PARSER_HEADERS
|
|||
|
||||
set(SFIZZ_PARSER_SOURCES
|
||||
sfizz/Opcode.cpp
|
||||
sfizz/Defaults.cpp
|
||||
sfizz/OpcodeCleanup.cpp
|
||||
sfizz/parser/Parser.cpp
|
||||
sfizz/parser/ParserPrivate.cpp)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
#include "Defaults.h"
|
||||
#include "MathHelpers.h"
|
||||
#include "SfzHelpers.h"
|
||||
|
||||
namespace sfz {
|
||||
|
||||
|
|
@ -23,7 +21,7 @@ extern const OpcodeSpec<int> oscillatorMode { 0, Range<int>(0, 2), 0 };
|
|||
extern const OpcodeSpec<int> oscillatorMulti { 1, Range<int>(1, config::oscillatorsPerVoice), 0 };
|
||||
extern const OpcodeSpec<float> oscillatorDetune { 0.0f, Range<float>(-12000.0f, 12000.0f), 0 };
|
||||
extern const OpcodeSpec<float> oscillatorDetuneMod { 0.0f, Range<float>(-12000.0f, 12000.0f), 0 };
|
||||
extern const OpcodeSpec<float> oscillatorModDepth { 0.0f, Range<float>(0.0f, 10000.0f), kNormalizePercent };
|
||||
extern const OpcodeSpec<float> oscillatorModDepth { 0.0f, Range<float>(0.0f, 10000.0f), 0 };
|
||||
extern const OpcodeSpec<float> oscillatorModDepthMod { 0.0f, Range<float>(0.0f, 10000.0f), 0 };
|
||||
extern const OpcodeSpec<int> oscillatorQuality { 1, Range<int>(0, 3), 0 };
|
||||
extern const OpcodeSpec<uint32_t> group { 0, Range<uint32_t>(0, uint32_t_max), 0 };
|
||||
|
|
@ -33,14 +31,14 @@ extern const OpcodeSpec<uint32_t> notePolyphony { config::maxVoices, Range<uint3
|
|||
extern const OpcodeSpec<uint8_t> key { 60, Range<uint8_t>(0, 127), kCanBeNote };
|
||||
extern const OpcodeSpec<uint8_t> loKey { 0, Range<uint8_t>(0, 127), kCanBeNote };
|
||||
extern const OpcodeSpec<uint8_t> hiKey { 127, Range<uint8_t>(0, 127), kCanBeNote };
|
||||
extern const OpcodeSpec<float> loCC { 0.0f , Range<float>(0.0f, 127.0f), kNormalizeMidi };
|
||||
extern const OpcodeSpec<float> hiCC { 1.0f , Range<float>(0.0f, 127.0f), kNormalizeMidi };
|
||||
extern const OpcodeSpec<float> loVel { 0.0f , Range<float>(0.0f, 127.0f), kNormalizeMidi };
|
||||
extern const OpcodeSpec<float> hiVel { 1.0f , Range<float>(0.0f, 127.0f), kNormalizeMidi };
|
||||
extern const OpcodeSpec<float> loCC { 0, Range<float>(0.0f, 127.0f), kNormalizeMidi };
|
||||
extern const OpcodeSpec<float> hiCC { 127, Range<float>(0.0f, 127.0f), kNormalizeMidi };
|
||||
extern const OpcodeSpec<float> loVel { 0, Range<float>(0.0f, 127.0f), kNormalizeMidi };
|
||||
extern const OpcodeSpec<float> hiVel { 127, Range<float>(0.0f, 127.0f), kNormalizeMidi };
|
||||
extern const OpcodeSpec<uint8_t> loChannelAftertouch { 0, Range<uint8_t>(0, 127), 0 };
|
||||
extern const OpcodeSpec<uint8_t> hiChannelAftertouch { 127, Range<uint8_t>(0, 127), 0 };
|
||||
extern const OpcodeSpec<float> loBend { -1.0f, Range<float>(-8192.0f, 8192.0f), kNormalizeBend };
|
||||
extern const OpcodeSpec<float> hiBend { 1.0f, Range<float>(-8192.0f, 8192.0f), kNormalizeBend };
|
||||
extern const OpcodeSpec<float> loBend { -8192, Range<float>(-8192.0f, 8192.0f), kNormalizeBend };
|
||||
extern const OpcodeSpec<float> hiBend { 8192, Range<float>(-8192.0f, 8192.0f), kNormalizeBend };
|
||||
extern const OpcodeSpec<float> loNormalized { 0.0f, Range<float>(0.0f, 1.0f), 0 };
|
||||
extern const OpcodeSpec<float> hiNormalized { 1.0f, Range<float>(0.0f, 1.0f), 0 };
|
||||
extern const OpcodeSpec<float> loBipolar { -1.0f, Range<float>(-1.0f, 1.0f), 0 };
|
||||
|
|
@ -49,7 +47,7 @@ extern const OpcodeSpec<uint16_t> ccNumber { 0, Range<uint16_t>(0, config::numCC
|
|||
extern const OpcodeSpec<uint8_t> smoothCC { 0, Range<uint8_t>(0, 100), 0 };
|
||||
extern const OpcodeSpec<uint8_t> curveCC { 0, Range<uint8_t>(0, 255), 0 };
|
||||
extern const OpcodeSpec<uint8_t> sustainCC { 64, Range<uint8_t>(0, 127), 0 };
|
||||
extern const OpcodeSpec<float> sustainThreshold { 0.0039f, Range<float>(0.0f, 127.0f), kNormalizeMidi };
|
||||
extern const OpcodeSpec<float> sustainThreshold { 1, Range<float>(0.0f, 127.0f), kNormalizeMidi };
|
||||
extern const OpcodeSpec<bool> checkSustain { true, Range<bool>(0, 1), 0 };
|
||||
extern const OpcodeSpec<bool> checkSostenuto { true, Range<bool>(0, 1), 0 };
|
||||
extern const OpcodeSpec<float> loBPM { 0.0f, Range<float>(0.0f, 500.0f), 0 };
|
||||
|
|
@ -58,19 +56,19 @@ extern const OpcodeSpec<uint8_t> sequence { 1, Range<uint8_t>(1, 100), 0 };
|
|||
extern const OpcodeSpec<float> volume { 0.0f, Range<float>(-144.0f, 48.0f), 0 };
|
||||
extern const OpcodeSpec<float> volumeMod { 0.0f, Range<float>(-144.0f, 48.0f), 0 };
|
||||
extern const OpcodeSpec<float> amplitude { 100.0f, Range<float>(0.0f, 10000.0f), kNormalizePercent };
|
||||
extern const OpcodeSpec<float> amplitudeMod { 0.0f, Range<float>(0.0f, 10000.0f), kNormalizePercent };
|
||||
extern const OpcodeSpec<float> amplitudeMod { 0.0f, Range<float>(0.0f, 10000.0f), 0 };
|
||||
extern const OpcodeSpec<float> pan { 0.0f, Range<float>(-100.0f, 100.0f), kNormalizePercent };
|
||||
extern const OpcodeSpec<float> panMod { 0.0f, Range<float>(-200.0f, 200.0f), kNormalizePercent };
|
||||
extern const OpcodeSpec<float> panMod { 0.0f, Range<float>(-200.0f, 200.0f), 0 };
|
||||
extern const OpcodeSpec<float> position { 0.0f, Range<float>(-100.0f, 100.0f), kNormalizePercent };
|
||||
extern const OpcodeSpec<float> positionMod { 0.0f, Range<float>(-200.0f, 200.0f), kNormalizePercent };
|
||||
extern const OpcodeSpec<float> positionMod { 0.0f, Range<float>(-200.0f, 200.0f), 0 };
|
||||
extern const OpcodeSpec<float> width { 100.0f, Range<float>(-100.0f, 100.0f), kNormalizePercent };
|
||||
extern const OpcodeSpec<float> widthMod { 0.0f, Range<float>(-200.0f, 200.0f), kNormalizePercent };
|
||||
extern const OpcodeSpec<float> widthMod { 0.0f, Range<float>(-200.0f, 200.0f), 0 };
|
||||
extern const OpcodeSpec<float> crossfadeIn { 0.0f, Range<float>(0.0f, 127.0f), kNormalizeMidi };
|
||||
extern const OpcodeSpec<float> crossfadeInNorm { 0.0f, Range<float>(0.0f, 1.0f), 0 };
|
||||
extern const OpcodeSpec<float> crossfadeOut { 1.0f, Range<float>(0.0f, 127.0f), kNormalizeMidi };
|
||||
extern const OpcodeSpec<float> crossfadeOut { 127.0f, Range<float>(0.0f, 127.0f), kNormalizeMidi };
|
||||
extern const OpcodeSpec<float> crossfadeOutNorm { 1.0f, Range<float>(0.0f, 1.0f), 0 };
|
||||
extern const OpcodeSpec<float> ampKeytrack { 0.0f, Range<float>(-96.0f, 12.0f), 0 };
|
||||
extern const OpcodeSpec<float> ampVeltrack { 100.0f, Range<float>(-100.0f, 100.0f), 0 };
|
||||
extern const OpcodeSpec<float> ampVeltrack { 100.0f, Range<float>(-100.0f, 100.0f), kNormalizePercent };
|
||||
extern const OpcodeSpec<float> ampVelcurve { 0.0f, Range<float>(0.0f, 1.0f), 0 };
|
||||
extern const OpcodeSpec<float> ampRandom { 0.0f, Range<float>(0.0f, 24.0f), 0 };
|
||||
extern const OpcodeSpec<bool> rtDead { false, Range<bool>(0, 1), 0 };
|
||||
|
|
@ -144,7 +142,7 @@ extern const OpcodeSpec<float> compRelease { 0.05f, Range<float>(0.0f, 10.0f), 0
|
|||
extern const OpcodeSpec<bool> compSTLink { false, Range<bool>(0, 1), 0 };
|
||||
extern const OpcodeSpec<float> compThreshold { 0.0f, Range<float>(-100.0f, 0.0f), 0 };
|
||||
extern const OpcodeSpec<float> compRatio { 1.0f, Range<float>(1.0f, 50.0f), 0 };
|
||||
extern const OpcodeSpec<float> compGain { 1.0f, Range<float>(-100.0f, 100.0f), kDb2Mag };
|
||||
extern const OpcodeSpec<float> compGain { 0.0f, Range<float>(-100.0f, 100.0f), kDb2Mag };
|
||||
extern const OpcodeSpec<float> fverbSize { 0.0f, Range<float>(0.0f, 100.0f), 0 };
|
||||
extern const OpcodeSpec<float> fverbPredelay { 0.0f, Range<float>(0.0f, 10.0f), 0 };
|
||||
extern const OpcodeSpec<float> fverbTone { 100.0f, Range<float>(0.0f, 100.0f), 0 };
|
||||
|
|
|
|||
|
|
@ -24,11 +24,14 @@
|
|||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
#include <limits>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#include "Range.h"
|
||||
#include "Config.h"
|
||||
#include "SfzFilter.h"
|
||||
#include <limits>
|
||||
#include <cstdint>
|
||||
#include "SfzHelpers.h"
|
||||
#include "MathHelpers.h"
|
||||
|
||||
|
||||
namespace sfz
|
||||
|
|
@ -68,10 +71,40 @@ enum OpcodeFlags : int {
|
|||
template<class T>
|
||||
struct OpcodeSpec
|
||||
{
|
||||
T defaultValue;
|
||||
T defaultInputValue;
|
||||
Range<T> bounds;
|
||||
int flags;
|
||||
operator T() const { return defaultValue; }
|
||||
template<class U=T>
|
||||
typename std::enable_if<std::is_arithmetic<U>::value, U>::type normalizeInput(U input) const
|
||||
{
|
||||
constexpr auto needsOperation {
|
||||
kNormalizePercent |
|
||||
kNormalizeMidi |
|
||||
kNormalizeBend |
|
||||
kDb2Mag
|
||||
};
|
||||
|
||||
if (!(flags & needsOperation))
|
||||
return input;
|
||||
else if (flags & kNormalizePercent)
|
||||
return normalizePercents(input);
|
||||
else if (flags & kNormalizeMidi)
|
||||
return normalize7Bits(input);
|
||||
else if (flags & kNormalizeBend)
|
||||
return normalizeBend(input);
|
||||
else if (flags & kDb2Mag)
|
||||
return db2mag(input);
|
||||
else // just in case
|
||||
return input;
|
||||
}
|
||||
|
||||
template<class U=T>
|
||||
typename std::enable_if<!std::is_arithmetic<U>::value, U>::type normalizeInput(U input) const
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
||||
operator T() const { return normalizeInput(defaultInputValue); }
|
||||
};
|
||||
|
||||
namespace Default
|
||||
|
|
|
|||
|
|
@ -155,9 +155,9 @@ absl::optional<T> readInt_(OpcodeSpec<T> spec, absl::string_view v)
|
|||
|
||||
#define INSTANTIATE_FOR_INTEGRAL(T) \
|
||||
template <> \
|
||||
T Opcode::read(OpcodeSpec<T> spec) const \
|
||||
absl::optional<T> Opcode::readOptional(OpcodeSpec<T> spec) const \
|
||||
{ \
|
||||
return readInt_<T>(spec, value).value_or(spec.defaultValue); \
|
||||
return readInt_<T>(spec, value); \
|
||||
}
|
||||
|
||||
INSTANTIATE_FOR_INTEGRAL(uint8_t)
|
||||
|
|
@ -205,23 +205,14 @@ absl::optional<T> readFloat_(OpcodeSpec<T> spec, absl::string_view v)
|
|||
return {};
|
||||
}
|
||||
|
||||
if (spec.flags & kNormalizeMidi)
|
||||
returnedValue = normalize7Bits(returnedValue);
|
||||
else if (spec.flags & kNormalizePercent)
|
||||
returnedValue = normalizePercents(returnedValue);
|
||||
else if (spec.flags & kNormalizeBend)
|
||||
returnedValue = normalizeBend(returnedValue);
|
||||
else if (spec.flags & kDb2Mag)
|
||||
returnedValue = db2mag(returnedValue);
|
||||
|
||||
return returnedValue;
|
||||
return spec.normalizeInput(returnedValue);
|
||||
}
|
||||
|
||||
#define INSTANTIATE_FOR_FLOATING_POINT(T) \
|
||||
template <> \
|
||||
T Opcode::read(OpcodeSpec<T> spec) const \
|
||||
absl::optional<T> Opcode::readOptional(OpcodeSpec<T> spec) const \
|
||||
{ \
|
||||
return readFloat_<T>(spec, value).value_or(spec.defaultValue); \
|
||||
return readFloat_<T>(spec, value); \
|
||||
}
|
||||
|
||||
INSTANTIATE_FOR_FLOATING_POINT(float)
|
||||
|
|
@ -292,17 +283,17 @@ absl::optional<bool> readBooleanFromOpcode(const Opcode& opcode)
|
|||
}
|
||||
|
||||
template <>
|
||||
OscillatorEnabled Opcode::read(OpcodeSpec<OscillatorEnabled> spec) const
|
||||
absl::optional<OscillatorEnabled> Opcode::readOptional(OpcodeSpec<OscillatorEnabled>) const
|
||||
{
|
||||
auto v = readBooleanFromOpcode(*this);
|
||||
if (!v)
|
||||
return spec.defaultValue;
|
||||
return {};
|
||||
|
||||
return *v ? OscillatorEnabled::On : OscillatorEnabled::Off;
|
||||
}
|
||||
|
||||
template <>
|
||||
Trigger Opcode::read(OpcodeSpec<Trigger> spec) const
|
||||
absl::optional<Trigger> Opcode::readOptional(OpcodeSpec<Trigger>) const
|
||||
{
|
||||
switch (hash(value)) {
|
||||
case hash("attack"): return Trigger::attack;
|
||||
|
|
@ -313,11 +304,11 @@ Trigger Opcode::read(OpcodeSpec<Trigger> spec) const
|
|||
}
|
||||
|
||||
DBG("Unknown trigger value: " << value);
|
||||
return spec.defaultValue;
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
template <>
|
||||
CrossfadeCurve Opcode::read(OpcodeSpec<CrossfadeCurve> spec) const
|
||||
absl::optional<CrossfadeCurve> Opcode::readOptional(OpcodeSpec<CrossfadeCurve>) const
|
||||
{
|
||||
switch (hash(value)) {
|
||||
case hash("power"): return CrossfadeCurve::power;
|
||||
|
|
@ -325,11 +316,11 @@ CrossfadeCurve Opcode::read(OpcodeSpec<CrossfadeCurve> spec) const
|
|||
}
|
||||
|
||||
DBG("Unknown crossfade power curve: " << value);
|
||||
return spec.defaultValue;
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
template <>
|
||||
OffMode Opcode::read(OpcodeSpec<OffMode> spec) const
|
||||
absl::optional<OffMode> Opcode::readOptional(OpcodeSpec<OffMode>) const
|
||||
{
|
||||
switch (hash(value)) {
|
||||
case hash("fast"): return OffMode::fast;
|
||||
|
|
@ -338,11 +329,11 @@ OffMode Opcode::read(OpcodeSpec<OffMode> spec) const
|
|||
}
|
||||
|
||||
DBG("Unknown off mode: " << value);
|
||||
return spec.defaultValue;
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
template <>
|
||||
FilterType Opcode::read(OpcodeSpec<FilterType> spec) const
|
||||
absl::optional<FilterType> Opcode::readOptional(OpcodeSpec<FilterType>) const
|
||||
{
|
||||
switch (hash(value)) {
|
||||
case hash("lpf_1p"): return kFilterLpf1p;
|
||||
|
|
@ -371,11 +362,11 @@ FilterType Opcode::read(OpcodeSpec<FilterType> spec) const
|
|||
}
|
||||
|
||||
DBG("Unknown filter type: " << value);
|
||||
return spec.defaultValue;
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
template <>
|
||||
EqType Opcode::read(OpcodeSpec<EqType> spec) const
|
||||
absl::optional<EqType> Opcode::readOptional(OpcodeSpec<EqType>) const
|
||||
{
|
||||
switch (hash(value)) {
|
||||
case hash("peak"): return kEqPeak;
|
||||
|
|
@ -384,11 +375,11 @@ EqType Opcode::read(OpcodeSpec<EqType> spec) const
|
|||
}
|
||||
|
||||
DBG("Unknown EQ type: " << value);
|
||||
return spec.defaultValue;
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
template <>
|
||||
VelocityOverride Opcode::read(OpcodeSpec<VelocityOverride> spec) const
|
||||
absl::optional<VelocityOverride> Opcode::readOptional(OpcodeSpec<VelocityOverride>) const
|
||||
{
|
||||
switch (hash(value)) {
|
||||
case hash("current"): return VelocityOverride::current;
|
||||
|
|
@ -396,11 +387,11 @@ VelocityOverride Opcode::read(OpcodeSpec<VelocityOverride> spec) const
|
|||
}
|
||||
|
||||
DBG("Unknown velocity override: " << value);
|
||||
return spec.defaultValue;
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
template <>
|
||||
SelfMask Opcode::read(OpcodeSpec<SelfMask> spec) const
|
||||
absl::optional<SelfMask> Opcode::readOptional(OpcodeSpec<SelfMask>) const
|
||||
{
|
||||
switch (hash(value)) {
|
||||
case hash("on"):
|
||||
|
|
@ -409,25 +400,28 @@ SelfMask Opcode::read(OpcodeSpec<SelfMask> spec) const
|
|||
}
|
||||
|
||||
DBG("Unknown velocity override: " << value);
|
||||
return spec.defaultValue;
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool Opcode::read(OpcodeSpec<bool> spec) const
|
||||
absl::optional<bool> Opcode::readOptional(OpcodeSpec<bool>) const
|
||||
{
|
||||
return readBooleanFromOpcode(*this).value_or(spec.defaultValue);
|
||||
return readBooleanFromOpcode(*this);
|
||||
}
|
||||
|
||||
template <>
|
||||
LFOWave Opcode::read(OpcodeSpec<LFOWave> spec) const
|
||||
absl::optional<LFOWave> Opcode::readOptional(OpcodeSpec<LFOWave> spec) const
|
||||
{
|
||||
const OpcodeSpec<int> intSpec {
|
||||
static_cast<int>(spec.defaultValue),
|
||||
static_cast<int>(spec.defaultInputValue),
|
||||
Range<int>(static_cast<int>(spec.bounds.getStart()), static_cast<int>(spec.bounds.getEnd())),
|
||||
0
|
||||
};
|
||||
int value = read(intSpec);
|
||||
return static_cast<LFOWave>(value);
|
||||
|
||||
if (auto value = readOptional(intSpec))
|
||||
return static_cast<LFOWave>(*value);
|
||||
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
} // namespace sfz
|
||||
|
|
|
|||
|
|
@ -102,7 +102,10 @@ struct Opcode {
|
|||
}
|
||||
|
||||
template <class T>
|
||||
T read(OpcodeSpec<T> spec) const;
|
||||
absl::optional<T> readOptional(OpcodeSpec<T> spec) const;
|
||||
|
||||
template <class T>
|
||||
T read(OpcodeSpec<T> spec) const { return readOptional(spec).value_or(spec); }
|
||||
|
||||
private:
|
||||
static OpcodeCategory identifyCategory(absl::string_view name);
|
||||
|
|
|
|||
|
|
@ -283,8 +283,8 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
|
|||
break;
|
||||
case hash("sw_last"):
|
||||
if (!lastKeyswitchRange) {
|
||||
lastKeyswitch = opcode.read(Default::key);
|
||||
keySwitched = false;
|
||||
lastKeyswitch = opcode.readOptional(Default::key);
|
||||
keySwitched = !lastKeyswitch.has_value();
|
||||
}
|
||||
break;
|
||||
case hash("sw_lolast"):
|
||||
|
|
@ -315,15 +315,15 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
|
|||
keyswitchLabel = opcode.value;
|
||||
break;
|
||||
case hash("sw_down"):
|
||||
downKeyswitch = opcode.read(Default::key);
|
||||
keySwitched = false;
|
||||
downKeyswitch = opcode.readOptional(Default::key);
|
||||
keySwitched = !downKeyswitch.has_value();
|
||||
break;
|
||||
case hash("sw_up"):
|
||||
upKeyswitch = opcode.read(Default::key);
|
||||
upKeyswitch = opcode.readOptional(Default::key);
|
||||
break;
|
||||
case hash("sw_previous"):
|
||||
previousKeyswitch = opcode.read(Default::key);
|
||||
previousKeySwitched = false;
|
||||
previousKeyswitch = opcode.readOptional(Default::key);
|
||||
previousKeySwitched = !previousKeyswitch.has_value();
|
||||
break;
|
||||
case hash("sw_vel"):
|
||||
velocityOverride =
|
||||
|
|
|
|||
|
|
@ -389,7 +389,7 @@ struct Region {
|
|||
float position { normalizePercents(Default::position) }; // position
|
||||
uint8_t ampKeycenter { Default::key }; // amp_keycenter
|
||||
float ampKeytrack { Default::ampKeytrack }; // amp_keytrack
|
||||
float ampVeltrack { normalizePercents(Default::ampVeltrack) }; // amp_veltrack
|
||||
float ampVeltrack { Default::ampVeltrack }; // amp_veltrack
|
||||
std::vector<std::pair<uint8_t, float>> velocityPoints; // amp_velcurve_N
|
||||
absl::optional<Curve> velCurve {};
|
||||
float ampRandom { Default::ampRandom }; // amp_random
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
#include "MathHelpers.h"
|
||||
#include "SIMDHelpers.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "Defaults.h"
|
||||
|
||||
namespace sfz {
|
||||
|
||||
|
|
@ -126,6 +125,12 @@ constexpr float normalize7Bits(T value)
|
|||
return static_cast<float>(min(max(value, T { 0 }), T { 127 })) / 127.0f;
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr float normalize7Bits(bool value)
|
||||
{
|
||||
return value ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Normalize a CC value between 0.0 and 1.0
|
||||
*
|
||||
|
|
@ -188,11 +193,11 @@ inline CXX14_CONSTEXPR uint8_t offsetAndClampKey(uint8_t key, int offset)
|
|||
{
|
||||
const int offsetKey { key + offset };
|
||||
if (offsetKey > std::numeric_limits<uint8_t>::max())
|
||||
return Default::key.bounds.getEnd();
|
||||
return 127;
|
||||
if (offsetKey < std::numeric_limits<uint8_t>::min())
|
||||
return Default::key.bounds.getStart();
|
||||
return 0;
|
||||
|
||||
return Default::key.bounds.clamp(static_cast<uint8_t>(offsetKey));
|
||||
return clamp<uint8_t>(static_cast<uint8_t>(offsetKey), 0, 127);
|
||||
}
|
||||
|
||||
namespace literals {
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ TEST_CASE("[Opcode] opcode read (uint8_t)")
|
|||
{
|
||||
Opcode opcode { "", "110" };
|
||||
OpcodeSpec<uint8_t> spec { 0, Range<uint8_t>(0, 100), 0 };
|
||||
REQUIRE( opcode.read(spec) == spec.defaultValue );
|
||||
REQUIRE( opcode.read(spec) == spec.defaultInputValue );
|
||||
}
|
||||
|
||||
SECTION("Clamp upper")
|
||||
|
|
@ -353,7 +353,7 @@ TEST_CASE("[Opcode] opcode read (uint8_t)")
|
|||
{
|
||||
Opcode opcode { "", "garbage10" };
|
||||
OpcodeSpec<uint8_t> spec { 0, Range<uint8_t>(0, 100), 0 };
|
||||
REQUIRE( opcode.read(spec) == spec.defaultValue );
|
||||
REQUIRE( opcode.read(spec) == spec.defaultInputValue );
|
||||
}
|
||||
|
||||
SECTION("Can be note")
|
||||
|
|
@ -458,7 +458,7 @@ TEST_CASE("[Opcode] opcode read (float)")
|
|||
{
|
||||
Opcode opcode { "", "110" };
|
||||
OpcodeSpec<float> spec { 0.0f, Range<float>(-100.0f, 100.0f), 0 };
|
||||
REQUIRE( opcode.read(spec) == spec.defaultValue );
|
||||
REQUIRE( opcode.read(spec) == spec.defaultInputValue );
|
||||
}
|
||||
|
||||
SECTION("Clamp upper")
|
||||
|
|
|
|||
|
|
@ -747,7 +747,7 @@ TEST_CASE("[Values] Upswitch")
|
|||
"/region2/sw_up,N : { }",
|
||||
"/region3/sw_up,N : { }",
|
||||
"/region4/sw_up,i : { 60 }",
|
||||
"/region5/sw_up,i : { 60 }",
|
||||
"/region5/sw_up,N : { }",
|
||||
};
|
||||
REQUIRE(messageList == expected);
|
||||
}
|
||||
|
|
@ -778,7 +778,7 @@ TEST_CASE("[Values] Downswitch")
|
|||
"/region2/sw_down,N : { }",
|
||||
"/region3/sw_down,N : { }",
|
||||
"/region4/sw_down,i : { 60 }",
|
||||
"/region5/sw_down,i : { 60 }",
|
||||
"/region5/sw_down,N : { }",
|
||||
};
|
||||
REQUIRE(messageList == expected);
|
||||
}
|
||||
|
|
@ -809,7 +809,7 @@ TEST_CASE("[Values] Previous keyswitch")
|
|||
"/region2/sw_previous,N : { }",
|
||||
"/region3/sw_previous,N : { }",
|
||||
"/region4/sw_previous,i : { 60 }",
|
||||
"/region5/sw_previous,i : { 64 }",
|
||||
"/region5/sw_previous,N : { }",
|
||||
};
|
||||
REQUIRE(messageList == expected);
|
||||
}
|
||||
|
|
@ -889,7 +889,7 @@ TEST_CASE("[Values] BPM range")
|
|||
"/region0/bpm_range,ff : { 0, 500 }",
|
||||
"/region1/bpm_range,ff : { 34.1, 60.2 }",
|
||||
"/region2/bpm_range,ff : { 0, 60 }",
|
||||
"/region3/bpm_range,ff : { 0, 0 }",
|
||||
"/region3/bpm_range,ff : { 20, 500 }",
|
||||
"/region4/bpm_range,ff : { 10, 10 }",
|
||||
};
|
||||
REQUIRE(messageList == expected);
|
||||
|
|
@ -1553,12 +1553,11 @@ TEST_CASE("[Values] Amp Veltrack")
|
|||
)");
|
||||
synth.dispatchMessage(client, 0, "/region0/amp_veltrack", "", nullptr);
|
||||
synth.dispatchMessage(client, 0, "/region1/amp_veltrack", "", nullptr);
|
||||
// TODO: activate for the new region parser ; ignore oob
|
||||
// synth.dispatchMessage(client, 0, "/region2/amp_veltrack", "", nullptr);
|
||||
synth.dispatchMessage(client, 0, "/region2/amp_veltrack", "", nullptr);
|
||||
std::vector<std::string> expected {
|
||||
"/region0/amp_veltrack,f : { 100 }",
|
||||
"/region1/amp_veltrack,f : { 10.1 }",
|
||||
// "/region2/amp_veltrack,f : { 100 }",
|
||||
"/region2/amp_veltrack,f : { 100 }",
|
||||
};
|
||||
REQUIRE(messageList == expected);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue