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 }; 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 };

View file

@ -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;

View file

@ -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)

View file

@ -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"):

View file

@ -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 });
} }

View file

@ -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);