Merge pull request #896 from paulfd/fill-gaps-2
Fill gaps on opcodes related to velocity and aftertouch triggers
This commit is contained in:
commit
f8c498b227
6 changed files with 50 additions and 47 deletions
|
|
@ -50,18 +50,18 @@ UInt8Spec loKey { 0, {0, 127}, kCanBeNote };
|
||||||
UInt8Spec hiKey { 127, {0, 127}, kCanBeNote };
|
UInt8Spec hiKey { 127, {0, 127}, kCanBeNote };
|
||||||
FloatSpec loCC { 0, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
|
FloatSpec loCC { 0, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
|
||||||
FloatSpec hiCC { 127, {0.0f, 127.0f}, kNormalizeMidi|kFillGap|kPermissiveBounds };
|
FloatSpec hiCC { 127, {0.0f, 127.0f}, kNormalizeMidi|kFillGap|kPermissiveBounds };
|
||||||
FloatSpec xfoutLoCC { 127.0f, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
|
FloatSpec xfoutLo { 127.0f, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
|
||||||
FloatSpec xfoutHiCC { 127.0f, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
|
FloatSpec xfoutHi { 127.0f, {0.0f, 127.0f}, kNormalizeMidi|kFillGap|kPermissiveBounds };
|
||||||
FloatSpec xfinLoCC { 0.0f, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
|
FloatSpec xfinLo { 0.0f, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
|
||||||
FloatSpec xfinHiCC { 0.0f, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
|
FloatSpec xfinHi { 0.0f, {0.0f, 127.0f}, kNormalizeMidi|kFillGap|kPermissiveBounds };
|
||||||
FloatSpec loVel { 0, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
|
FloatSpec loVel { 0, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
|
||||||
FloatSpec hiVel { 127, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
|
FloatSpec hiVel { 127, {0.0f, 127.0f}, kNormalizeMidi|kFillGap|kPermissiveBounds };
|
||||||
FloatSpec loChannelAftertouch { 0, {0, 127}, kNormalizeMidi|kPermissiveBounds };
|
FloatSpec loChannelAftertouch { 0, {0, 127}, kNormalizeMidi|kPermissiveBounds };
|
||||||
FloatSpec hiChannelAftertouch { 127, {0, 127}, kNormalizeMidi|kPermissiveBounds };
|
FloatSpec hiChannelAftertouch { 127, {0, 127}, kNormalizeMidi|kFillGap|kPermissiveBounds };
|
||||||
FloatSpec loPolyAftertouch { 0, {0, 127}, kNormalizeMidi|kPermissiveBounds };
|
FloatSpec loPolyAftertouch { 0, {0, 127}, kNormalizeMidi|kPermissiveBounds };
|
||||||
FloatSpec hiPolyAftertouch { 127, {0, 127}, kNormalizeMidi|kPermissiveBounds };
|
FloatSpec hiPolyAftertouch { 127, {0, 127}, kNormalizeMidi|kFillGap|kPermissiveBounds };
|
||||||
FloatSpec loBend { -8191, {-8192.0f, 8191.0f}, kNormalizeBend|kPermissiveBounds };
|
FloatSpec loBend { -8191, {-8192.0f, 8191.0f}, kNormalizeBend|kPermissiveBounds };
|
||||||
FloatSpec hiBend { 8191, {-8192.0f, 8191.0f}, kNormalizeBend|kPermissiveBounds };
|
FloatSpec hiBend { 8191, {-8192.0f, 8191.0f}, kNormalizeBend|kFillGap|kPermissiveBounds };
|
||||||
FloatSpec loNormalized { 0.0f, {0.0f, 1.0f}, kPermissiveBounds };
|
FloatSpec loNormalized { 0.0f, {0.0f, 1.0f}, kPermissiveBounds };
|
||||||
FloatSpec hiNormalized { 1.0f, {0.0f, 1.0f}, kPermissiveBounds };
|
FloatSpec hiNormalized { 1.0f, {0.0f, 1.0f}, kPermissiveBounds };
|
||||||
FloatSpec loBipolar { -1.0f, {-1.0f, 1.0f}, kPermissiveBounds };
|
FloatSpec loBipolar { -1.0f, {-1.0f, 1.0f}, kPermissiveBounds };
|
||||||
|
|
|
||||||
|
|
@ -164,10 +164,10 @@ namespace Default
|
||||||
extern const OpcodeSpec<float> hiVel;
|
extern const OpcodeSpec<float> hiVel;
|
||||||
extern const OpcodeSpec<float> loCC;
|
extern const OpcodeSpec<float> loCC;
|
||||||
extern const OpcodeSpec<float> hiCC;
|
extern const OpcodeSpec<float> hiCC;
|
||||||
extern const OpcodeSpec<float> xfoutLoCC;
|
extern const OpcodeSpec<float> xfoutLo;
|
||||||
extern const OpcodeSpec<float> xfoutHiCC;
|
extern const OpcodeSpec<float> xfoutHi;
|
||||||
extern const OpcodeSpec<float> xfinHiCC;
|
extern const OpcodeSpec<float> xfinHi;
|
||||||
extern const OpcodeSpec<float> xfinLoCC;
|
extern const OpcodeSpec<float> xfinLo;
|
||||||
extern const OpcodeSpec<float> loBend;
|
extern const OpcodeSpec<float> loBend;
|
||||||
extern const OpcodeSpec<float> hiBend;
|
extern const OpcodeSpec<float> hiBend;
|
||||||
extern const OpcodeSpec<float> loNormalized;
|
extern const OpcodeSpec<float> loNormalized;
|
||||||
|
|
|
||||||
|
|
@ -18,15 +18,17 @@ namespace sfz {
|
||||||
template <class T, bool C, class U>
|
template <class T, bool C, class U>
|
||||||
float crossfadeIn(const sfz::Range<T, C>& crossfadeRange, U value, CrossfadeCurve curve)
|
float crossfadeIn(const sfz::Range<T, C>& crossfadeRange, U value, CrossfadeCurve curve)
|
||||||
{
|
{
|
||||||
|
constexpr float gapOffset { static_cast<T>(normalize7Bits(1)) };
|
||||||
if (value < crossfadeRange.getStart())
|
if (value < crossfadeRange.getStart())
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
const auto length = static_cast<float>(crossfadeRange.length());
|
const auto length = static_cast<float>(crossfadeRange.length()) - gapOffset;
|
||||||
if (length <= 0.0f)
|
if (length <= 0.0f)
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
|
|
||||||
else if (value < crossfadeRange.getEnd()) {
|
else if (value < crossfadeRange.getEnd()) {
|
||||||
const auto crossfadePosition = static_cast<float>(value - crossfadeRange.getStart()) / length;
|
const auto distanceFromStart = static_cast<float>(value - crossfadeRange.getStart());
|
||||||
|
const auto crossfadePosition = distanceFromStart / length;
|
||||||
if (curve == CrossfadeCurve::power)
|
if (curve == CrossfadeCurve::power)
|
||||||
return sqrt(crossfadePosition);
|
return sqrt(crossfadePosition);
|
||||||
if (curve == CrossfadeCurve::gain)
|
if (curve == CrossfadeCurve::gain)
|
||||||
|
|
@ -42,15 +44,16 @@ float crossfadeIn(const sfz::Range<T, C>& crossfadeRange, U value, CrossfadeCurv
|
||||||
template <class T, bool C, class U>
|
template <class T, bool C, class U>
|
||||||
float crossfadeOut(const sfz::Range<T, C>& crossfadeRange, U value, CrossfadeCurve curve)
|
float crossfadeOut(const sfz::Range<T, C>& crossfadeRange, U value, CrossfadeCurve curve)
|
||||||
{
|
{
|
||||||
if (value > crossfadeRange.getEnd())
|
constexpr float gapOffset { static_cast<T>(normalize7Bits(1)) };
|
||||||
return 0.0f;
|
const auto length = static_cast<float>(crossfadeRange.length()) - gapOffset;
|
||||||
|
|
||||||
const auto length = static_cast<float>(crossfadeRange.length());
|
|
||||||
if (length <= 0.0f)
|
if (length <= 0.0f)
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
|
|
||||||
else if (value > crossfadeRange.getStart()) {
|
else if (value > crossfadeRange.getStart()) {
|
||||||
const auto crossfadePosition = static_cast<float>(value - crossfadeRange.getStart()) / length;
|
const auto distanceFromStart = static_cast<float>(value - crossfadeRange.getStart());
|
||||||
|
const auto crossfadePosition = distanceFromStart / length;
|
||||||
|
if (crossfadePosition > 1.0f)
|
||||||
|
return 0.0f;
|
||||||
if (curve == CrossfadeCurve::power)
|
if (curve == CrossfadeCurve::power)
|
||||||
return std::sqrt(1 - crossfadePosition);
|
return std::sqrt(1 - crossfadePosition);
|
||||||
if (curve == CrossfadeCurve::gain)
|
if (curve == CrossfadeCurve::gain)
|
||||||
|
|
|
||||||
|
|
@ -474,16 +474,16 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode, bool cleanOpcode)
|
||||||
crossfadeKeyOutRange.setEnd(opcode.read(Default::hiKey));
|
crossfadeKeyOutRange.setEnd(opcode.read(Default::hiKey));
|
||||||
break;
|
break;
|
||||||
case hash("xfin_lovel"):
|
case hash("xfin_lovel"):
|
||||||
crossfadeVelInRange.setStart(opcode.read(Default::loVel));
|
crossfadeVelInRange.setStart(opcode.read(Default::xfinLo));
|
||||||
break;
|
break;
|
||||||
case hash("xfin_hivel"):
|
case hash("xfin_hivel"):
|
||||||
crossfadeVelInRange.setEnd(opcode.read(Default::loVel)); // loVel for the proper default
|
crossfadeVelInRange.setEnd(opcode.read(Default::xfinHi));
|
||||||
break;
|
break;
|
||||||
case hash("xfout_lovel"):
|
case hash("xfout_lovel"):
|
||||||
crossfadeVelOutRange.setStart(opcode.read(Default::hiVel)); // hiVel for the proper default
|
crossfadeVelOutRange.setStart(opcode.read(Default::xfoutLo));
|
||||||
break;
|
break;
|
||||||
case hash("xfout_hivel"):
|
case hash("xfout_hivel"):
|
||||||
crossfadeVelOutRange.setEnd(opcode.read(Default::hiVel));
|
crossfadeVelOutRange.setEnd(opcode.read(Default::xfoutHi));
|
||||||
break;
|
break;
|
||||||
case hash("xf_keycurve"):
|
case hash("xf_keycurve"):
|
||||||
crossfadeKeyCurve = opcode.read(Default::crossfadeCurve);
|
crossfadeKeyCurve = opcode.read(Default::crossfadeCurve);
|
||||||
|
|
@ -495,28 +495,28 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode, bool cleanOpcode)
|
||||||
if (opcode.parameters.back() >= config::numCCs)
|
if (opcode.parameters.back() >= config::numCCs)
|
||||||
return false;
|
return false;
|
||||||
crossfadeCCInRange[opcode.parameters.back()].setStart(
|
crossfadeCCInRange[opcode.parameters.back()].setStart(
|
||||||
opcode.read(Default::xfinLoCC)
|
opcode.read(Default::xfinLo)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case hash("xfin_hicc&"):
|
case hash("xfin_hicc&"):
|
||||||
if (opcode.parameters.back() >= config::numCCs)
|
if (opcode.parameters.back() >= config::numCCs)
|
||||||
return false;
|
return false;
|
||||||
crossfadeCCInRange[opcode.parameters.back()].setEnd(
|
crossfadeCCInRange[opcode.parameters.back()].setEnd(
|
||||||
opcode.read(Default::xfinHiCC)
|
opcode.read(Default::xfinHi)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case hash("xfout_locc&"):
|
case hash("xfout_locc&"):
|
||||||
if (opcode.parameters.back() >= config::numCCs)
|
if (opcode.parameters.back() >= config::numCCs)
|
||||||
return false;
|
return false;
|
||||||
crossfadeCCOutRange[opcode.parameters.back()].setStart(
|
crossfadeCCOutRange[opcode.parameters.back()].setStart(
|
||||||
opcode.read(Default::xfoutLoCC)
|
opcode.read(Default::xfoutLo)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case hash("xfout_hicc&"):
|
case hash("xfout_hicc&"):
|
||||||
if (opcode.parameters.back() >= config::numCCs)
|
if (opcode.parameters.back() >= config::numCCs)
|
||||||
return false;
|
return false;
|
||||||
crossfadeCCOutRange[opcode.parameters.back()].setEnd(
|
crossfadeCCOutRange[opcode.parameters.back()].setEnd(
|
||||||
opcode.read(Default::xfoutHiCC)
|
opcode.read(Default::xfoutHi)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case hash("xf_cccurve"):
|
case hash("xf_cccurve"):
|
||||||
|
|
|
||||||
|
|
@ -149,10 +149,10 @@ TEST_CASE("[Files] Group from AVL")
|
||||||
REQUIRE(synth.getRegionView(i)->keyRange == Range<uint8_t>(36, 36));
|
REQUIRE(synth.getRegionView(i)->keyRange == Range<uint8_t>(36, 36));
|
||||||
}
|
}
|
||||||
|
|
||||||
almostEqualRanges(synth.getRegionView(0)->velocityRange, { 1_norm, 26_norm });
|
almostEqualRanges(synth.getRegionView(0)->velocityRange, { 1_norm, std::nextafter(27_norm, 0.0f) });
|
||||||
almostEqualRanges(synth.getRegionView(1)->velocityRange, { 27_norm, 52_norm });
|
almostEqualRanges(synth.getRegionView(1)->velocityRange, { 27_norm, std::nextafter(53_norm, 0.0f) });
|
||||||
almostEqualRanges(synth.getRegionView(2)->velocityRange, { 53_norm, 77_norm });
|
almostEqualRanges(synth.getRegionView(2)->velocityRange, { 53_norm, std::nextafter(78_norm, 0.0f) });
|
||||||
almostEqualRanges(synth.getRegionView(3)->velocityRange, { 78_norm, 102_norm });
|
almostEqualRanges(synth.getRegionView(3)->velocityRange, { 78_norm, std::nextafter(103_norm, 0.0f) });
|
||||||
almostEqualRanges(synth.getRegionView(4)->velocityRange, { 103_norm, 127_norm });
|
almostEqualRanges(synth.getRegionView(4)->velocityRange, { 103_norm, 127_norm });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -599,8 +599,8 @@ TEST_CASE("[Values] Velocity range")
|
||||||
synth.dispatchMessage(client, 0, "/region3/vel_range", "", nullptr);
|
synth.dispatchMessage(client, 0, "/region3/vel_range", "", nullptr);
|
||||||
std::vector<std::string> expected {
|
std::vector<std::string> expected {
|
||||||
"/region0/vel_range,ff : { 0, 1 }",
|
"/region0/vel_range,ff : { 0, 1 }",
|
||||||
"/region1/vel_range,ff : { 0.267717, 0.472441 }",
|
"/region1/vel_range,ff : { 0.267717, 0.480315 }",
|
||||||
"/region2/vel_range,ff : { -0.023622, 0.472441 }",
|
"/region2/vel_range,ff : { -0.023622, 0.480315 }",
|
||||||
"/region3/vel_range,ff : { 0, -0.00787402 }",
|
"/region3/vel_range,ff : { 0, -0.00787402 }",
|
||||||
};
|
};
|
||||||
REQUIRE(messageList == expected);
|
REQUIRE(messageList == expected);
|
||||||
|
|
@ -914,10 +914,10 @@ TEST_CASE("[Values] Aftertouch range")
|
||||||
synth.dispatchMessage(client, 0, "/region4/chanaft_range", "", nullptr);
|
synth.dispatchMessage(client, 0, "/region4/chanaft_range", "", nullptr);
|
||||||
std::vector<std::string> expected {
|
std::vector<std::string> expected {
|
||||||
"/region0/chanaft_range,ff : { 0, 1 }",
|
"/region0/chanaft_range,ff : { 0, 1 }",
|
||||||
"/region1/chanaft_range,ff : { 0.267717, 0.472441 }",
|
"/region1/chanaft_range,ff : { 0.267717, 0.480315 }",
|
||||||
"/region2/chanaft_range,ff : { -0.023622, 0.472441 }",
|
"/region2/chanaft_range,ff : { -0.023622, 0.480315 }",
|
||||||
"/region3/chanaft_range,ff : { 0.15748, -0.00787402 }",
|
"/region3/chanaft_range,ff : { 0.15748, -0.00787402 }",
|
||||||
"/region4/chanaft_range,ff : { 0.15748, 0.0787402 }",
|
"/region4/chanaft_range,ff : { 0.15748, 0.0866142 }",
|
||||||
};
|
};
|
||||||
REQUIRE(messageList == expected);
|
REQUIRE(messageList == expected);
|
||||||
}
|
}
|
||||||
|
|
@ -942,10 +942,10 @@ TEST_CASE("[Values] Polyaftertouch range")
|
||||||
synth.dispatchMessage(client, 0, "/region4/polyaft_range", "", nullptr);
|
synth.dispatchMessage(client, 0, "/region4/polyaft_range", "", nullptr);
|
||||||
std::vector<std::string> expected {
|
std::vector<std::string> expected {
|
||||||
"/region0/polyaft_range,ff : { 0, 1 }",
|
"/region0/polyaft_range,ff : { 0, 1 }",
|
||||||
"/region1/polyaft_range,ff : { 0.267717, 0.472441 }",
|
"/region1/polyaft_range,ff : { 0.267717, 0.480315 }",
|
||||||
"/region2/polyaft_range,ff : { -0.023622, 0.472441 }",
|
"/region2/polyaft_range,ff : { -0.023622, 0.480315 }",
|
||||||
"/region3/polyaft_range,ff : { 0.15748, -0.00787402 }",
|
"/region3/polyaft_range,ff : { 0.15748, -0.00787402 }",
|
||||||
"/region4/polyaft_range,ff : { 0.15748, 0.0787402 }",
|
"/region4/polyaft_range,ff : { 0.15748, 0.0866142 }",
|
||||||
};
|
};
|
||||||
REQUIRE(messageList == expected);
|
REQUIRE(messageList == expected);
|
||||||
}
|
}
|
||||||
|
|
@ -1747,8 +1747,8 @@ TEST_CASE("[Values] Crossfade velocity range")
|
||||||
synth.dispatchMessage(client, 0, "/region3/xfin_vel_range", "", nullptr);
|
synth.dispatchMessage(client, 0, "/region3/xfin_vel_range", "", nullptr);
|
||||||
std::vector<std::string> expected {
|
std::vector<std::string> expected {
|
||||||
"/region0/xfin_vel_range,ff : { 0, 0 }",
|
"/region0/xfin_vel_range,ff : { 0, 0 }",
|
||||||
"/region1/xfin_vel_range,ff : { 0.0787402, 0.314961 }",
|
"/region1/xfin_vel_range,ff : { 0.0787402, 0.322835 }",
|
||||||
"/region2/xfin_vel_range,ff : { -0.0787402, 0.314961 }",
|
"/region2/xfin_vel_range,ff : { -0.0787402, 0.322835 }",
|
||||||
"/region3/xfin_vel_range,ff : { 0.0787402, 1.10236 }",
|
"/region3/xfin_vel_range,ff : { 0.0787402, 1.10236 }",
|
||||||
};
|
};
|
||||||
REQUIRE(messageList == expected);
|
REQUIRE(messageList == expected);
|
||||||
|
|
@ -1768,8 +1768,8 @@ TEST_CASE("[Values] Crossfade velocity range")
|
||||||
synth.dispatchMessage(client, 0, "/region3/xfout_vel_range", "", nullptr);
|
synth.dispatchMessage(client, 0, "/region3/xfout_vel_range", "", nullptr);
|
||||||
std::vector<std::string> expected {
|
std::vector<std::string> expected {
|
||||||
"/region0/xfout_vel_range,ff : { 1, 1 }",
|
"/region0/xfout_vel_range,ff : { 1, 1 }",
|
||||||
"/region1/xfout_vel_range,ff : { 0.0787402, 0.314961 }",
|
"/region1/xfout_vel_range,ff : { 0.0787402, 0.322835 }",
|
||||||
"/region2/xfout_vel_range,ff : { -0.0787402, 0.314961 }",
|
"/region2/xfout_vel_range,ff : { -0.0787402, 0.322835 }",
|
||||||
"/region3/xfout_vel_range,ff : { 0.0787402, 1.10236 }",
|
"/region3/xfout_vel_range,ff : { 0.0787402, 1.10236 }",
|
||||||
};
|
};
|
||||||
REQUIRE(messageList == expected);
|
REQUIRE(messageList == expected);
|
||||||
|
|
@ -1868,8 +1868,8 @@ TEST_CASE("[Values] Crossfade CC range")
|
||||||
synth.dispatchMessage(client, 0, "/region3/xfin_cc_range4", "", nullptr);
|
synth.dispatchMessage(client, 0, "/region3/xfin_cc_range4", "", nullptr);
|
||||||
std::vector<std::string> expected {
|
std::vector<std::string> expected {
|
||||||
"/region0/xfin_cc_range4,N : { }",
|
"/region0/xfin_cc_range4,N : { }",
|
||||||
"/region1/xfin_cc_range4,ff : { 0.0787402, 0.314961 }",
|
"/region1/xfin_cc_range4,ff : { 0.0787402, 0.322835 }",
|
||||||
"/region2/xfin_cc_range4,ff : { -0.0787402, 0.314961 }",
|
"/region2/xfin_cc_range4,ff : { -0.0787402, 0.322835 }",
|
||||||
"/region3/xfin_cc_range4,ff : { 0.0787402, 1.10236 }",
|
"/region3/xfin_cc_range4,ff : { 0.0787402, 1.10236 }",
|
||||||
};
|
};
|
||||||
REQUIRE(messageList == expected);
|
REQUIRE(messageList == expected);
|
||||||
|
|
@ -1889,8 +1889,8 @@ TEST_CASE("[Values] Crossfade CC range")
|
||||||
synth.dispatchMessage(client, 0, "/region3/xfout_cc_range4", "", nullptr);
|
synth.dispatchMessage(client, 0, "/region3/xfout_cc_range4", "", nullptr);
|
||||||
std::vector<std::string> expected {
|
std::vector<std::string> expected {
|
||||||
"/region0/xfout_cc_range4,N : { }",
|
"/region0/xfout_cc_range4,N : { }",
|
||||||
"/region1/xfout_cc_range4,ff : { 0.0787402, 0.314961 }",
|
"/region1/xfout_cc_range4,ff : { 0.0787402, 0.322835 }",
|
||||||
"/region2/xfout_cc_range4,ff : { -0.0787402, 0.314961 }",
|
"/region2/xfout_cc_range4,ff : { -0.0787402, 0.322835 }",
|
||||||
"/region3/xfout_cc_range4,ff : { 0.0787402, 1.10236 }",
|
"/region3/xfout_cc_range4,ff : { 0.0787402, 1.10236 }",
|
||||||
};
|
};
|
||||||
REQUIRE(messageList == expected);
|
REQUIRE(messageList == expected);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue