Merge pull request #896 from paulfd/fill-gaps-2

Fill gaps on opcodes related to velocity and aftertouch triggers
This commit is contained in:
Paul Ferrand 2021-05-20 20:58:05 +02:00 committed by GitHub
commit f8c498b227
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 50 additions and 47 deletions

View file

@ -50,18 +50,18 @@ UInt8Spec loKey { 0, {0, 127}, kCanBeNote };
UInt8Spec hiKey { 127, {0, 127}, kCanBeNote };
FloatSpec loCC { 0, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
FloatSpec hiCC { 127, {0.0f, 127.0f}, kNormalizeMidi|kFillGap|kPermissiveBounds };
FloatSpec xfoutLoCC { 127.0f, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
FloatSpec xfoutHiCC { 127.0f, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
FloatSpec xfinLoCC { 0.0f, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
FloatSpec xfinHiCC { 0.0f, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
FloatSpec xfoutLo { 127.0f, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
FloatSpec xfoutHi { 127.0f, {0.0f, 127.0f}, kNormalizeMidi|kFillGap|kPermissiveBounds };
FloatSpec xfinLo { 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 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 hiChannelAftertouch { 127, {0, 127}, kNormalizeMidi|kPermissiveBounds };
FloatSpec hiChannelAftertouch { 127, {0, 127}, kNormalizeMidi|kFillGap|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 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 hiNormalized { 1.0f, {0.0f, 1.0f}, kPermissiveBounds };
FloatSpec loBipolar { -1.0f, {-1.0f, 1.0f}, kPermissiveBounds };

View file

@ -164,10 +164,10 @@ namespace Default
extern const OpcodeSpec<float> hiVel;
extern const OpcodeSpec<float> loCC;
extern const OpcodeSpec<float> hiCC;
extern const OpcodeSpec<float> xfoutLoCC;
extern const OpcodeSpec<float> xfoutHiCC;
extern const OpcodeSpec<float> xfinHiCC;
extern const OpcodeSpec<float> xfinLoCC;
extern const OpcodeSpec<float> xfoutLo;
extern const OpcodeSpec<float> xfoutHi;
extern const OpcodeSpec<float> xfinHi;
extern const OpcodeSpec<float> xfinLo;
extern const OpcodeSpec<float> loBend;
extern const OpcodeSpec<float> hiBend;
extern const OpcodeSpec<float> loNormalized;

View file

@ -18,15 +18,17 @@ namespace sfz {
template <class T, bool C, class U>
float crossfadeIn(const sfz::Range<T, C>& crossfadeRange, U value, CrossfadeCurve curve)
{
constexpr float gapOffset { static_cast<T>(normalize7Bits(1)) };
if (value < crossfadeRange.getStart())
return 0.0f;
const auto length = static_cast<float>(crossfadeRange.length());
const auto length = static_cast<float>(crossfadeRange.length()) - gapOffset;
if (length <= 0.0f)
return 1.0f;
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)
return sqrt(crossfadePosition);
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>
float crossfadeOut(const sfz::Range<T, C>& crossfadeRange, U value, CrossfadeCurve curve)
{
if (value > crossfadeRange.getEnd())
return 0.0f;
const auto length = static_cast<float>(crossfadeRange.length());
constexpr float gapOffset { static_cast<T>(normalize7Bits(1)) };
const auto length = static_cast<float>(crossfadeRange.length()) - gapOffset;
if (length <= 0.0f)
return 1.0f;
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)
return std::sqrt(1 - crossfadePosition);
if (curve == CrossfadeCurve::gain)

View file

@ -474,16 +474,16 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode, bool cleanOpcode)
crossfadeKeyOutRange.setEnd(opcode.read(Default::hiKey));
break;
case hash("xfin_lovel"):
crossfadeVelInRange.setStart(opcode.read(Default::loVel));
crossfadeVelInRange.setStart(opcode.read(Default::xfinLo));
break;
case hash("xfin_hivel"):
crossfadeVelInRange.setEnd(opcode.read(Default::loVel)); // loVel for the proper default
crossfadeVelInRange.setEnd(opcode.read(Default::xfinHi));
break;
case hash("xfout_lovel"):
crossfadeVelOutRange.setStart(opcode.read(Default::hiVel)); // hiVel for the proper default
crossfadeVelOutRange.setStart(opcode.read(Default::xfoutLo));
break;
case hash("xfout_hivel"):
crossfadeVelOutRange.setEnd(opcode.read(Default::hiVel));
crossfadeVelOutRange.setEnd(opcode.read(Default::xfoutHi));
break;
case hash("xf_keycurve"):
crossfadeKeyCurve = opcode.read(Default::crossfadeCurve);
@ -495,28 +495,28 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode, bool cleanOpcode)
if (opcode.parameters.back() >= config::numCCs)
return false;
crossfadeCCInRange[opcode.parameters.back()].setStart(
opcode.read(Default::xfinLoCC)
opcode.read(Default::xfinLo)
);
break;
case hash("xfin_hicc&"):
if (opcode.parameters.back() >= config::numCCs)
return false;
crossfadeCCInRange[opcode.parameters.back()].setEnd(
opcode.read(Default::xfinHiCC)
opcode.read(Default::xfinHi)
);
break;
case hash("xfout_locc&"):
if (opcode.parameters.back() >= config::numCCs)
return false;
crossfadeCCOutRange[opcode.parameters.back()].setStart(
opcode.read(Default::xfoutLoCC)
opcode.read(Default::xfoutLo)
);
break;
case hash("xfout_hicc&"):
if (opcode.parameters.back() >= config::numCCs)
return false;
crossfadeCCOutRange[opcode.parameters.back()].setEnd(
opcode.read(Default::xfoutHiCC)
opcode.read(Default::xfoutHi)
);
break;
case hash("xf_cccurve"):

View file

@ -149,10 +149,10 @@ TEST_CASE("[Files] Group from AVL")
REQUIRE(synth.getRegionView(i)->keyRange == Range<uint8_t>(36, 36));
}
almostEqualRanges(synth.getRegionView(0)->velocityRange, { 1_norm, 26_norm });
almostEqualRanges(synth.getRegionView(1)->velocityRange, { 27_norm, 52_norm });
almostEqualRanges(synth.getRegionView(2)->velocityRange, { 53_norm, 77_norm });
almostEqualRanges(synth.getRegionView(3)->velocityRange, { 78_norm, 102_norm });
almostEqualRanges(synth.getRegionView(0)->velocityRange, { 1_norm, std::nextafter(27_norm, 0.0f) });
almostEqualRanges(synth.getRegionView(1)->velocityRange, { 27_norm, std::nextafter(53_norm, 0.0f) });
almostEqualRanges(synth.getRegionView(2)->velocityRange, { 53_norm, std::nextafter(78_norm, 0.0f) });
almostEqualRanges(synth.getRegionView(3)->velocityRange, { 78_norm, std::nextafter(103_norm, 0.0f) });
almostEqualRanges(synth.getRegionView(4)->velocityRange, { 103_norm, 127_norm });
}

View file

@ -599,8 +599,8 @@ TEST_CASE("[Values] Velocity range")
synth.dispatchMessage(client, 0, "/region3/vel_range", "", nullptr);
std::vector<std::string> expected {
"/region0/vel_range,ff : { 0, 1 }",
"/region1/vel_range,ff : { 0.267717, 0.472441 }",
"/region2/vel_range,ff : { -0.023622, 0.472441 }",
"/region1/vel_range,ff : { 0.267717, 0.480315 }",
"/region2/vel_range,ff : { -0.023622, 0.480315 }",
"/region3/vel_range,ff : { 0, -0.00787402 }",
};
REQUIRE(messageList == expected);
@ -914,10 +914,10 @@ TEST_CASE("[Values] Aftertouch range")
synth.dispatchMessage(client, 0, "/region4/chanaft_range", "", nullptr);
std::vector<std::string> expected {
"/region0/chanaft_range,ff : { 0, 1 }",
"/region1/chanaft_range,ff : { 0.267717, 0.472441 }",
"/region2/chanaft_range,ff : { -0.023622, 0.472441 }",
"/region1/chanaft_range,ff : { 0.267717, 0.480315 }",
"/region2/chanaft_range,ff : { -0.023622, 0.480315 }",
"/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);
}
@ -942,10 +942,10 @@ TEST_CASE("[Values] Polyaftertouch range")
synth.dispatchMessage(client, 0, "/region4/polyaft_range", "", nullptr);
std::vector<std::string> expected {
"/region0/polyaft_range,ff : { 0, 1 }",
"/region1/polyaft_range,ff : { 0.267717, 0.472441 }",
"/region2/polyaft_range,ff : { -0.023622, 0.472441 }",
"/region1/polyaft_range,ff : { 0.267717, 0.480315 }",
"/region2/polyaft_range,ff : { -0.023622, 0.480315 }",
"/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);
}
@ -1747,8 +1747,8 @@ TEST_CASE("[Values] Crossfade velocity range")
synth.dispatchMessage(client, 0, "/region3/xfin_vel_range", "", nullptr);
std::vector<std::string> expected {
"/region0/xfin_vel_range,ff : { 0, 0 }",
"/region1/xfin_vel_range,ff : { 0.0787402, 0.314961 }",
"/region2/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.322835 }",
"/region3/xfin_vel_range,ff : { 0.0787402, 1.10236 }",
};
REQUIRE(messageList == expected);
@ -1768,8 +1768,8 @@ TEST_CASE("[Values] Crossfade velocity range")
synth.dispatchMessage(client, 0, "/region3/xfout_vel_range", "", nullptr);
std::vector<std::string> expected {
"/region0/xfout_vel_range,ff : { 1, 1 }",
"/region1/xfout_vel_range,ff : { 0.0787402, 0.314961 }",
"/region2/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.322835 }",
"/region3/xfout_vel_range,ff : { 0.0787402, 1.10236 }",
};
REQUIRE(messageList == expected);
@ -1868,8 +1868,8 @@ TEST_CASE("[Values] Crossfade CC range")
synth.dispatchMessage(client, 0, "/region3/xfin_cc_range4", "", nullptr);
std::vector<std::string> expected {
"/region0/xfin_cc_range4,N : { }",
"/region1/xfin_cc_range4,ff : { 0.0787402, 0.314961 }",
"/region2/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.322835 }",
"/region3/xfin_cc_range4,ff : { 0.0787402, 1.10236 }",
};
REQUIRE(messageList == expected);
@ -1889,8 +1889,8 @@ TEST_CASE("[Values] Crossfade CC range")
synth.dispatchMessage(client, 0, "/region3/xfout_cc_range4", "", nullptr);
std::vector<std::string> expected {
"/region0/xfout_cc_range4,N : { }",
"/region1/xfout_cc_range4,ff : { 0.0787402, 0.314961 }",
"/region2/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.322835 }",
"/region3/xfout_cc_range4,ff : { 0.0787402, 1.10236 }",
};
REQUIRE(messageList == expected);