Added sustain_sw; sostenuto_sw is parsed but not treated in code
This commit is contained in:
parent
965321166c
commit
ebd2b1906a
7 changed files with 60 additions and 6 deletions
|
|
@ -31,7 +31,8 @@ namespace config {
|
|||
constexpr int preloadSize { 8192 };
|
||||
constexpr int numChannels { 2 };
|
||||
constexpr int numVoices { 64 };
|
||||
constexpr int numLoadingThreads { 4 };
|
||||
constexpr int sustainCC { 64 };
|
||||
constexpr int halfCCThreshold { 64 };
|
||||
constexpr int centPerSemitone { 100 };
|
||||
constexpr float virtuallyZero { 0.00005f };
|
||||
constexpr float fastReleaseDuration { 0.01 };
|
||||
|
|
|
|||
|
|
@ -142,5 +142,9 @@ namespace Default
|
|||
inline constexpr Range<int> egDepthRange { -12000, 12000 };
|
||||
inline constexpr Range<float> egOnCCTimeRange { -100.0, 100.0 };
|
||||
inline constexpr Range<float> egOnCCPercentRange { -100.0, 100.0 };
|
||||
|
||||
// ***** SFZ v2 ********
|
||||
inline constexpr bool checkSustain { true }; // sustain_sw
|
||||
inline constexpr bool checkSostenuto { true }; // sostenuto_sw
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
#include "LeakDetector.h"
|
||||
#include "Range.h"
|
||||
#include "SfzHelpers.h"
|
||||
#include "StringViewHelpers.h"
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
|
||||
|
|
@ -48,8 +49,12 @@ inline std::optional<ValueType> readOpcode(std::string_view value, const Range<V
|
|||
{
|
||||
if constexpr (std::is_integral<ValueType>::value) {
|
||||
int64_t returnedValue;
|
||||
if (!absl::SimpleAtoi(value, &returnedValue))
|
||||
return {};
|
||||
if (!absl::SimpleAtoi(value, &returnedValue)) {
|
||||
float floatValue;
|
||||
if (!absl::SimpleAtof(value, &floatValue))
|
||||
return {};
|
||||
returnedValue = static_cast<int64_t>(floatValue);
|
||||
}
|
||||
|
||||
if (returnedValue > std::numeric_limits<ValueType>::max())
|
||||
returnedValue = std::numeric_limits<ValueType>::max();
|
||||
|
|
@ -66,6 +71,18 @@ inline std::optional<ValueType> readOpcode(std::string_view value, const Range<V
|
|||
}
|
||||
}
|
||||
|
||||
inline std::optional<bool> readBooleanFromOpcode(const Opcode& opcode)
|
||||
{
|
||||
switch (hash(opcode.value)) {
|
||||
case hash("off"):
|
||||
return false;
|
||||
case hash("on"):
|
||||
return true;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
template <class ValueType>
|
||||
inline void setValueFromOpcode(const Opcode& opcode, ValueType& target, const Range<ValueType>& validRange)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,8 +22,10 @@
|
|||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "Region.h"
|
||||
#include "Defaults.h"
|
||||
#include "MathHelpers.h"
|
||||
#include "Debug.h"
|
||||
#include "Opcode.h"
|
||||
#include "StringViewHelpers.h"
|
||||
#include "absl/strings/str_replace.h"
|
||||
#include <random>
|
||||
|
|
@ -183,6 +185,13 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
|
|||
DBG("Unknown velocity mode: " << std::string(opcode.value));
|
||||
}
|
||||
break;
|
||||
|
||||
case hash("sustain_sw"):
|
||||
checkSustain = readBooleanFromOpcode(opcode).value_or(Default::checkSustain);
|
||||
break;
|
||||
case hash("sostenuto_sw"):
|
||||
checkSostenuto = readBooleanFromOpcode(opcode).value_or(Default::checkSostenuto);
|
||||
break;
|
||||
// Region logic: internal conditions
|
||||
case hash("lochanaft"):
|
||||
setRangeStartFromOpcode(opcode, aftertouchRange, Default::aftertouchRange);
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@ struct Region {
|
|||
std::optional<uint8_t> keyswitchDown {}; // sw_down
|
||||
std::optional<uint8_t> previousNote {}; // sw_previous
|
||||
SfzVelocityOverride velocityOverride { Default::velocityOverride }; // sw_vel
|
||||
bool checkSustain { Default::checkSustain }; // sustain_sw
|
||||
bool checkSostenuto { Default::checkSostenuto }; // sostenuto_sw
|
||||
|
||||
// Region logic: internal conditions
|
||||
Range<uint8_t> aftertouchRange { Default::aftertouchRange }; // hichanaft and lochanaft
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "Voice.h"
|
||||
#include "AudioSpan.h"
|
||||
#include "Config.h"
|
||||
#include "Defaults.h"
|
||||
#include "MathHelpers.h"
|
||||
#include "SIMDHelpers.h"
|
||||
|
|
@ -94,6 +95,7 @@ void sfz::Voice::startVoice(Region* region, int delay, int channel, int number,
|
|||
|
||||
sourcePosition = region->getOffset();
|
||||
floatPosition = static_cast<float>(sourcePosition);
|
||||
DBG("Offset: " << floatPosition);
|
||||
initialDelay = delay + region->getDelay();
|
||||
baseFrequency = midiNoteFrequency(number) * pitchRatio;
|
||||
prepareEGEnvelope(delay, value);
|
||||
|
|
@ -151,9 +153,8 @@ void sfz::Voice::registerNoteOff(int delay, int channel, int noteNumber, uint8_t
|
|||
if (region->loopMode == SfzLoopMode::one_shot)
|
||||
return;
|
||||
|
||||
if (ccState[64] < 63) {
|
||||
if (!region->checkSustain || ccState[config::sustainCC] < config::halfCCThreshold)
|
||||
release(delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -162,7 +163,7 @@ void sfz::Voice::registerCC(int delay, int channel [[maybe_unused]], int ccNumbe
|
|||
if (region == nullptr)
|
||||
return;
|
||||
|
||||
if (ccNumber == 64 && noteIsOff && ccValue < 63)
|
||||
if (ccNumber == config::sustainCC && noteIsOff && ccValue < config::halfCCThreshold)
|
||||
release(delay);
|
||||
|
||||
if (region->amplitudeCC && ccNumber == region->amplitudeCC->first) {
|
||||
|
|
|
|||
|
|
@ -1011,6 +1011,26 @@ TEST_CASE("[Region] Parsing opcodes")
|
|||
REQUIRE(region.amplitudeEG.ccStart->second == -100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccSustain->second == -100.0f);
|
||||
}
|
||||
|
||||
SECTION("sustain_sw and sostenuto_sw")
|
||||
{
|
||||
REQUIRE(region.checkSustain);
|
||||
REQUIRE(region.checkSostenuto);
|
||||
region.parseOpcode({ "sustain_sw", "off" });
|
||||
REQUIRE(!region.checkSustain);
|
||||
region.parseOpcode({ "sustain_sw", "on" });
|
||||
REQUIRE(region.checkSustain);
|
||||
region.parseOpcode({ "sustain_sw", "off" });
|
||||
region.parseOpcode({ "sustain_sw", "obladi" });
|
||||
REQUIRE(region.checkSustain);
|
||||
region.parseOpcode({ "sostenuto_sw", "off" });
|
||||
REQUIRE(!region.checkSostenuto);
|
||||
region.parseOpcode({ "sostenuto_sw", "on" });
|
||||
REQUIRE(region.checkSostenuto);
|
||||
region.parseOpcode({ "sostenuto_sw", "off" });
|
||||
region.parseOpcode({ "sostenuto_sw", "obladi" });
|
||||
REQUIRE(region.checkSostenuto);
|
||||
}
|
||||
}
|
||||
|
||||
// Specific region bugs
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue