Merge pull request #720 from jpcima/opcodes-misc
Opcode support for permissive bounds
This commit is contained in:
commit
09222d62bd
15 changed files with 75 additions and 50 deletions
|
|
@ -56,8 +56,8 @@ namespace config {
|
||||||
constexpr int numVoices { 64 };
|
constexpr int numVoices { 64 };
|
||||||
constexpr unsigned maxVoices { 256 };
|
constexpr unsigned maxVoices { 256 };
|
||||||
constexpr unsigned smoothingSteps { 512 };
|
constexpr unsigned smoothingSteps { 512 };
|
||||||
constexpr uint8_t xfadeSmoothing { 5 };
|
constexpr uint16_t xfadeSmoothing { 5 };
|
||||||
constexpr uint8_t gainSmoothing { 0 };
|
constexpr uint16_t gainSmoothing { 0 };
|
||||||
constexpr unsigned powerTableSizeExponent { 11 };
|
constexpr unsigned powerTableSizeExponent { 11 };
|
||||||
constexpr int maxFilePromises { maxVoices };
|
constexpr int maxFilePromises { maxVoices };
|
||||||
constexpr int allSoundOffCC { 120 };
|
constexpr int allSoundOffCC { 120 };
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@ FloatSpec loCC { 0, {0.0f, 127.0f}, kNormalizeMidi };
|
||||||
FloatSpec hiCC { 127, {0.0f, 127.0f}, kNormalizeMidi };
|
FloatSpec hiCC { 127, {0.0f, 127.0f}, kNormalizeMidi };
|
||||||
FloatSpec loVel { 0, {0.0f, 127.0f}, kNormalizeMidi };
|
FloatSpec loVel { 0, {0.0f, 127.0f}, kNormalizeMidi };
|
||||||
FloatSpec hiVel { 127, {0.0f, 127.0f}, kNormalizeMidi };
|
FloatSpec hiVel { 127, {0.0f, 127.0f}, kNormalizeMidi };
|
||||||
UInt8Spec loChannelAftertouch { 0, {0, 127}, 0 };
|
FloatSpec loChannelAftertouch { 0, {0, 127}, kNormalizeMidi };
|
||||||
UInt8Spec hiChannelAftertouch { 127, {0, 127}, 0 };
|
FloatSpec hiChannelAftertouch { 127, {0, 127}, kNormalizeMidi };
|
||||||
FloatSpec loBend { -8192, {-8192.0f, 8192.0f}, kNormalizeBend };
|
FloatSpec loBend { -8192, {-8192.0f, 8192.0f}, kNormalizeBend };
|
||||||
FloatSpec hiBend { 8192, {-8192.0f, 8192.0f}, kNormalizeBend };
|
FloatSpec hiBend { 8192, {-8192.0f, 8192.0f}, kNormalizeBend };
|
||||||
FloatSpec loNormalized { 0.0f, {0.0f, 1.0f}, 0 };
|
FloatSpec loNormalized { 0.0f, {0.0f, 1.0f}, 0 };
|
||||||
|
|
@ -58,7 +58,7 @@ FloatSpec hiNormalized { 1.0f, {0.0f, 1.0f}, 0 };
|
||||||
FloatSpec loBipolar { -1.0f, {-1.0f, 1.0f}, 0 };
|
FloatSpec loBipolar { -1.0f, {-1.0f, 1.0f}, 0 };
|
||||||
FloatSpec hiBipolar { 1.0f, {-1.0f, 1.0f}, 0 };
|
FloatSpec hiBipolar { 1.0f, {-1.0f, 1.0f}, 0 };
|
||||||
UInt16Spec ccNumber { 0, {0, config::numCCs}, 0 };
|
UInt16Spec ccNumber { 0, {0, config::numCCs}, 0 };
|
||||||
UInt8Spec smoothCC { 0, {0, 100}, 0 };
|
UInt16Spec smoothCC { 0, {0, 100}, kPermissiveUpperBound };
|
||||||
UInt8Spec curveCC { 0, {0, 255}, 0 };
|
UInt8Spec curveCC { 0, {0, 255}, 0 };
|
||||||
UInt8Spec sustainCC { 64, {0, 127}, 0 };
|
UInt8Spec sustainCC { 64, {0, 127}, 0 };
|
||||||
FloatSpec sustainThreshold { 1.0f, {0.0f, 127.0f}, kNormalizeMidi };
|
FloatSpec sustainThreshold { 1.0f, {0.0f, 127.0f}, kNormalizeMidi };
|
||||||
|
|
|
||||||
|
|
@ -50,11 +50,15 @@ enum OpcodeFlags : int {
|
||||||
kCanBeNote = 1,
|
kCanBeNote = 1,
|
||||||
kEnforceLowerBound = 1 << 1,
|
kEnforceLowerBound = 1 << 1,
|
||||||
kEnforceUpperBound = 1 << 2,
|
kEnforceUpperBound = 1 << 2,
|
||||||
kNormalizePercent = 1 << 3,
|
kEnforceBounds = kEnforceLowerBound|kEnforceUpperBound,
|
||||||
kNormalizeMidi = 1 << 4,
|
kPermissiveLowerBound = 1 << 3,
|
||||||
kNormalizeBend = 1 << 5,
|
kPermissiveUpperBound = 1 << 4,
|
||||||
kWrapPhase = 1 << 6,
|
kPermissiveBounds = kPermissiveLowerBound|kPermissiveUpperBound,
|
||||||
kDb2Mag = 1 << 7,
|
kNormalizePercent = 1 << 5,
|
||||||
|
kNormalizeMidi = 1 << 6,
|
||||||
|
kNormalizeBend = 1 << 7,
|
||||||
|
kWrapPhase = 1 << 8,
|
||||||
|
kDb2Mag = 1 << 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|
@ -151,11 +155,11 @@ namespace Default
|
||||||
extern const OpcodeSpec<float> hiNormalized;
|
extern const OpcodeSpec<float> hiNormalized;
|
||||||
extern const OpcodeSpec<float> loBipolar;
|
extern const OpcodeSpec<float> loBipolar;
|
||||||
extern const OpcodeSpec<float> hiBipolar;
|
extern const OpcodeSpec<float> hiBipolar;
|
||||||
extern const OpcodeSpec<uint8_t> loChannelAftertouch;
|
extern const OpcodeSpec<float> loChannelAftertouch;
|
||||||
extern const OpcodeSpec<uint8_t> hiChannelAftertouch;
|
extern const OpcodeSpec<float> hiChannelAftertouch;
|
||||||
extern const OpcodeSpec<uint16_t> ccNumber;
|
extern const OpcodeSpec<uint16_t> ccNumber;
|
||||||
extern const OpcodeSpec<uint8_t> curveCC;
|
extern const OpcodeSpec<uint8_t> curveCC;
|
||||||
extern const OpcodeSpec<uint8_t> smoothCC;
|
extern const OpcodeSpec<uint16_t> smoothCC;
|
||||||
extern const OpcodeSpec<uint8_t> sustainCC;
|
extern const OpcodeSpec<uint8_t> sustainCC;
|
||||||
extern const OpcodeSpec<bool> checkSustain;
|
extern const OpcodeSpec<bool> checkSustain;
|
||||||
extern const OpcodeSpec<bool> checkSostenuto;
|
extern const OpcodeSpec<bool> checkSostenuto;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "absl/strings/ascii.h"
|
#include "absl/strings/ascii.h"
|
||||||
#include "absl/strings/match.h"
|
#include "absl/strings/match.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
|
#include <limits>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
@ -144,6 +145,8 @@ OpcodeCategory Opcode::identifyCategory(absl::string_view name)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
absl::optional<T> readInt_(OpcodeSpec<T> spec, absl::string_view v)
|
absl::optional<T> readInt_(OpcodeSpec<T> spec, absl::string_view v)
|
||||||
{
|
{
|
||||||
|
using Limits = std::numeric_limits<T>;
|
||||||
|
|
||||||
size_t numberEnd = 0;
|
size_t numberEnd = 0;
|
||||||
|
|
||||||
if (numberEnd < v.size() && (v[numberEnd] == '+' || v[numberEnd] == '-'))
|
if (numberEnd < v.size() && (v[numberEnd] == '+' || v[numberEnd] == '-'))
|
||||||
|
|
@ -164,15 +167,18 @@ absl::optional<T> readInt_(OpcodeSpec<T> spec, absl::string_view v)
|
||||||
if (returnedValue > static_cast<int64_t>(spec.bounds.getEnd())) {
|
if (returnedValue > static_cast<int64_t>(spec.bounds.getEnd())) {
|
||||||
if (spec.flags & kEnforceUpperBound)
|
if (spec.flags & kEnforceUpperBound)
|
||||||
return spec.bounds.getEnd();
|
return spec.bounds.getEnd();
|
||||||
|
else if (!(spec.flags & kPermissiveUpperBound))
|
||||||
return absl::nullopt;
|
return absl::nullopt;
|
||||||
} else if (returnedValue < static_cast<int64_t>(spec.bounds.getStart())) {
|
} else if (returnedValue < static_cast<int64_t>(spec.bounds.getStart())) {
|
||||||
if (spec.flags & kEnforceLowerBound)
|
if (spec.flags & kEnforceLowerBound)
|
||||||
return spec.bounds.getStart();
|
return spec.bounds.getStart();
|
||||||
|
else if (!(spec.flags & kPermissiveLowerBound))
|
||||||
return absl::nullopt;
|
return absl::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
returnedValue = std::max<int64_t>(returnedValue, Limits::min());
|
||||||
|
returnedValue = std::min<int64_t>(returnedValue, Limits::max());
|
||||||
|
|
||||||
return static_cast<T>(returnedValue);
|
return static_cast<T>(returnedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -219,16 +225,18 @@ absl::optional<T> readFloat_(OpcodeSpec<T> spec, absl::string_view v)
|
||||||
else if (returnedValue > static_cast<int64_t>(spec.bounds.getEnd())) {
|
else if (returnedValue > static_cast<int64_t>(spec.bounds.getEnd())) {
|
||||||
if (spec.flags & kEnforceUpperBound)
|
if (spec.flags & kEnforceUpperBound)
|
||||||
return spec.bounds.getEnd();
|
return spec.bounds.getEnd();
|
||||||
|
else if (!(spec.flags & kPermissiveUpperBound))
|
||||||
return absl::nullopt;
|
return absl::nullopt;
|
||||||
} else if (returnedValue < static_cast<int64_t>(spec.bounds.getStart())) {
|
} else if (returnedValue < static_cast<int64_t>(spec.bounds.getStart())) {
|
||||||
if (spec.flags & kEnforceLowerBound)
|
if (spec.flags & kEnforceLowerBound)
|
||||||
return spec.bounds.getStart();
|
return spec.bounds.getStart();
|
||||||
|
else if (!(spec.flags & kPermissiveLowerBound))
|
||||||
return absl::nullopt;
|
return absl::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return spec.normalizeInput(returnedValue);
|
returnedValue = spec.normalizeInput(returnedValue);
|
||||||
|
|
||||||
|
return returnedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INSTANTIATE_FOR_FLOATING_POINT(T) \
|
#define INSTANTIATE_FOR_FLOATING_POINT(T) \
|
||||||
|
|
|
||||||
|
|
@ -1565,7 +1565,7 @@ void sfz::Region::registerPitchWheel(float pitch) noexcept
|
||||||
pitchSwitched = false;
|
pitchSwitched = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Region::registerAftertouch(uint8_t aftertouch) noexcept
|
void sfz::Region::registerAftertouch(float aftertouch) noexcept
|
||||||
{
|
{
|
||||||
if (aftertouchRange.containsWithEnd(aftertouch))
|
if (aftertouchRange.containsWithEnd(aftertouch))
|
||||||
aftertouchSwitched = true;
|
aftertouchSwitched = true;
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ struct Region {
|
||||||
*
|
*
|
||||||
* @param aftertouch
|
* @param aftertouch
|
||||||
*/
|
*/
|
||||||
void registerAftertouch(uint8_t aftertouch) noexcept;
|
void registerAftertouch(float aftertouch) noexcept;
|
||||||
/**
|
/**
|
||||||
* @brief Register tempo
|
* @brief Register tempo
|
||||||
*
|
*
|
||||||
|
|
@ -409,7 +409,7 @@ struct Region {
|
||||||
float sustainThreshold { Default::sustainThreshold }; // sustain_cc
|
float sustainThreshold { Default::sustainThreshold }; // sustain_cc
|
||||||
|
|
||||||
// Region logic: internal conditions
|
// Region logic: internal conditions
|
||||||
Range<uint8_t> aftertouchRange { Default::loChannelAftertouch, Default::hiChannelAftertouch }; // hichanaft and lochanaft
|
Range<float> aftertouchRange { Default::loChannelAftertouch, Default::hiChannelAftertouch }; // hichanaft and lochanaft
|
||||||
Range<float> bpmRange { Default::loBPM, Default::hiBPM }; // hibpm and lobpm
|
Range<float> bpmRange { Default::loBPM, Default::hiBPM }; // hibpm and lobpm
|
||||||
Range<float> randRange { Default::loNormalized, Default::hiNormalized }; // hirand and lorand
|
Range<float> randRange { Default::loNormalized, Default::hiNormalized }; // hirand and lorand
|
||||||
uint8_t sequenceLength { Default::sequence }; // seq_length
|
uint8_t sequenceLength { Default::sequence }; // seq_length
|
||||||
|
|
@ -464,7 +464,7 @@ struct Region {
|
||||||
float bendUp { Default::bendUp };
|
float bendUp { Default::bendUp };
|
||||||
float bendDown { Default::bendDown };
|
float bendDown { Default::bendDown };
|
||||||
float bendStep { Default::bendStep };
|
float bendStep { Default::bendStep };
|
||||||
uint8_t bendSmooth { Default::smoothCC };
|
uint16_t bendSmooth { Default::smoothCC };
|
||||||
|
|
||||||
// Envelopes
|
// Envelopes
|
||||||
EGDescription amplitudeEG;
|
EGDescription amplitudeEG;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ OnePoleSmoother::OnePoleSmoother()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnePoleSmoother::setSmoothing(uint8_t smoothValue, float sampleRate)
|
void OnePoleSmoother::setSmoothing(unsigned smoothValue, float sampleRate)
|
||||||
{
|
{
|
||||||
smoothing = (smoothValue > 0);
|
smoothing = (smoothValue > 0);
|
||||||
if (smoothing) {
|
if (smoothing) {
|
||||||
|
|
@ -62,7 +62,7 @@ LinearSmoother::LinearSmoother()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinearSmoother::setSmoothing(uint8_t smoothValue, float sampleRate)
|
void LinearSmoother::setSmoothing(unsigned smoothValue, float sampleRate)
|
||||||
{
|
{
|
||||||
const float smoothTime = 1e-3f * smoothValue;
|
const float smoothTime = 1e-3f * smoothValue;
|
||||||
smoothFrames_ = static_cast<int32_t>(smoothTime * sampleRate);
|
smoothFrames_ = static_cast<int32_t>(smoothTime * sampleRate);
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ public:
|
||||||
* @param smoothValue
|
* @param smoothValue
|
||||||
* @param sampleRate
|
* @param sampleRate
|
||||||
*/
|
*/
|
||||||
void setSmoothing(uint8_t smoothValue, float sampleRate);
|
void setSmoothing(unsigned smoothValue, float sampleRate);
|
||||||
/**
|
/**
|
||||||
* @brief Reset the filter state to a given value
|
* @brief Reset the filter state to a given value
|
||||||
*
|
*
|
||||||
|
|
@ -63,7 +63,7 @@ public:
|
||||||
* @param smoothValue
|
* @param smoothValue
|
||||||
* @param sampleRate
|
* @param sampleRate
|
||||||
*/
|
*/
|
||||||
void setSmoothing(uint8_t smoothValue, float sampleRate);
|
void setSmoothing(unsigned smoothValue, float sampleRate);
|
||||||
/**
|
/**
|
||||||
* @brief Reset the filter state to a given value
|
* @brief Reset the filter state to a given value
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1257,22 +1257,27 @@ void Synth::pitchWheel(int delay, int pitch) noexcept
|
||||||
}
|
}
|
||||||
|
|
||||||
void Synth::aftertouch(int delay, uint8_t aftertouch) noexcept
|
void Synth::aftertouch(int delay, uint8_t aftertouch) noexcept
|
||||||
|
{
|
||||||
|
const float normalizedAftertouch = normalize7Bits(aftertouch);
|
||||||
|
hdAftertouch(delay, normalizedAftertouch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Synth::hdAftertouch(int delay, float normAftertouch) noexcept
|
||||||
{
|
{
|
||||||
Impl& impl = *impl_;
|
Impl& impl = *impl_;
|
||||||
ScopedTiming logger { impl.dispatchDuration_, ScopedTiming::Operation::addToDuration };
|
ScopedTiming logger { impl.dispatchDuration_, ScopedTiming::Operation::addToDuration };
|
||||||
|
|
||||||
const auto normalizedAftertouch = normalize7Bits(aftertouch);
|
impl.resources_.midiState.channelAftertouchEvent(delay, normAftertouch);
|
||||||
impl.resources_.midiState.channelAftertouchEvent(delay, normalizedAftertouch);
|
|
||||||
|
|
||||||
for (auto& region : impl.regions_) {
|
for (auto& region : impl.regions_) {
|
||||||
region->registerAftertouch(aftertouch);
|
region->registerAftertouch(normAftertouch);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& voice : impl.voiceManager_) {
|
for (auto& voice : impl.voiceManager_) {
|
||||||
voice.registerAftertouch(delay, aftertouch);
|
voice.registerAftertouch(delay, normAftertouch);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl.performHdcc(delay, ExtendedCCs::channelAftertouch, normalizedAftertouch, false);
|
impl.performHdcc(delay, ExtendedCCs::channelAftertouch, normAftertouch, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Synth::tempo(int delay, float secondsPerBeat) noexcept
|
void Synth::tempo(int delay, float secondsPerBeat) noexcept
|
||||||
|
|
|
||||||
|
|
@ -389,6 +389,14 @@ public:
|
||||||
* @param aftertouch the aftertouch value
|
* @param aftertouch the aftertouch value
|
||||||
*/
|
*/
|
||||||
void aftertouch(int delay, uint8_t aftertouch) noexcept;
|
void aftertouch(int delay, uint8_t aftertouch) noexcept;
|
||||||
|
/**
|
||||||
|
* @brief Send a high precision aftertouch event to the synth
|
||||||
|
*
|
||||||
|
* @param delay the delay at which the event occurs; this should be lower than the size of
|
||||||
|
* the block in the next call to renderBlock().
|
||||||
|
* @param normAftertouch the normalized aftertouch value, in domain 0 to 1
|
||||||
|
*/
|
||||||
|
void hdAftertouch(int delay, float normAftertouch) noexcept;
|
||||||
/**
|
/**
|
||||||
* @brief Send a tempo event to the synth
|
* @brief Send a tempo event to the synth
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -374,9 +374,9 @@ void sfz::Synth::dispatchMessage(Client& client, int delay, const char* path, co
|
||||||
MATCH("/region&/chanaft_range", "") {
|
MATCH("/region&/chanaft_range", "") {
|
||||||
GET_REGION_OR_BREAK(indices[0])
|
GET_REGION_OR_BREAK(indices[0])
|
||||||
sfizz_arg_t args[2];
|
sfizz_arg_t args[2];
|
||||||
args[0].i = region.aftertouchRange.getStart();
|
args[0].f = region.aftertouchRange.getStart();
|
||||||
args[1].i = region.aftertouchRange.getEnd();
|
args[1].f = region.aftertouchRange.getEnd();
|
||||||
client.receive(delay, path, "ii", args);
|
client.receive(delay, path, "ff", args);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
MATCH("/region&/bpm_range", "") {
|
MATCH("/region&/bpm_range", "") {
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ ModKey::Parameters& ModKey::Parameters::operator=(Parameters&& other) noexcept
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModKey ModKey::createCC(uint16_t cc, uint8_t curve, uint8_t smooth, float step)
|
ModKey ModKey::createCC(uint16_t cc, uint8_t curve, uint16_t smooth, float step)
|
||||||
{
|
{
|
||||||
ModKey::Parameters p;
|
ModKey::Parameters p;
|
||||||
p.cc = cc;
|
p.cc = cc;
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ public:
|
||||||
explicit ModKey(ModId id, NumericId<Region> region = {}, Parameters params = {})
|
explicit ModKey(ModId id, NumericId<Region> region = {}, Parameters params = {})
|
||||||
: id_(id), region_(region), params_(params), flags_(ModIds::flags(id_)) {}
|
: id_(id), region_(region), params_(params), flags_(ModIds::flags(id_)) {}
|
||||||
|
|
||||||
static ModKey createCC(uint16_t cc, uint8_t curve, uint8_t smooth, float step);
|
static ModKey createCC(uint16_t cc, uint8_t curve, uint16_t smooth, float step);
|
||||||
static ModKey createNXYZ(ModId id, NumericId<Region> region = {}, uint8_t N = 0, uint8_t X = 0, uint8_t Y = 0, uint8_t Z = 0);
|
static ModKey createNXYZ(ModId id, NumericId<Region> region = {}, uint8_t N = 0, uint8_t X = 0, uint8_t Y = 0, uint8_t Z = 0);
|
||||||
|
|
||||||
explicit operator bool() const noexcept { return id_ != ModId(); }
|
explicit operator bool() const noexcept { return id_ != ModId(); }
|
||||||
|
|
@ -45,7 +45,7 @@ public:
|
||||||
struct RawParameters {
|
struct RawParameters {
|
||||||
union {
|
union {
|
||||||
//! Parameters if this key identifies a CC source
|
//! Parameters if this key identifies a CC source
|
||||||
struct { uint16_t cc; uint8_t curve, smooth; float step; };
|
struct { uint16_t cc; uint8_t curve; uint16_t smooth; float step; };
|
||||||
//! Parameters otherwise, based on the related opcode
|
//! Parameters otherwise, based on the related opcode
|
||||||
// eg. `N` in `lfoN`, `N, X` in `lfoN_eqX`
|
// eg. `N` in `lfoN`, `N, X` in `lfoN_eqX`
|
||||||
struct { uint8_t N, X, Y, Z; };
|
struct { uint8_t N, X, Y, Z; };
|
||||||
|
|
|
||||||
|
|
@ -90,13 +90,13 @@ TEST_CASE("Region activation", "Region tests")
|
||||||
{
|
{
|
||||||
region.parseOpcode({ "lochanaft", "56" });
|
region.parseOpcode({ "lochanaft", "56" });
|
||||||
region.parseOpcode({ "hichanaft", "68" });
|
region.parseOpcode({ "hichanaft", "68" });
|
||||||
region.registerAftertouch(0);
|
region.registerAftertouch(sfz::normalize7Bits(0));
|
||||||
REQUIRE(!region.isSwitchedOn());
|
REQUIRE(!region.isSwitchedOn());
|
||||||
region.registerAftertouch(56);
|
region.registerAftertouch(sfz::normalize7Bits(56));
|
||||||
REQUIRE(region.isSwitchedOn());
|
REQUIRE(region.isSwitchedOn());
|
||||||
region.registerAftertouch(68);
|
region.registerAftertouch(sfz::normalize7Bits(68));
|
||||||
REQUIRE(region.isSwitchedOn());
|
REQUIRE(region.isSwitchedOn());
|
||||||
region.registerAftertouch(98);
|
region.registerAftertouch(sfz::normalize7Bits(98));
|
||||||
REQUIRE(!region.isSwitchedOn());
|
REQUIRE(!region.isSwitchedOn());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -869,11 +869,11 @@ TEST_CASE("[Values] Aftertouch range")
|
||||||
synth.dispatchMessage(client, 0, "/region3/chanaft_range", "", nullptr);
|
synth.dispatchMessage(client, 0, "/region3/chanaft_range", "", nullptr);
|
||||||
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,ii : { 0, 127 }",
|
"/region0/chanaft_range,ff : { 0, 1 }",
|
||||||
"/region1/chanaft_range,ii : { 34, 60 }",
|
"/region1/chanaft_range,ff : { 0.267717, 0.472441 }",
|
||||||
"/region2/chanaft_range,ii : { 0, 60 }",
|
"/region2/chanaft_range,ff : { 0, 0.472441 }",
|
||||||
"/region3/chanaft_range,ii : { 20, 127 }",
|
"/region3/chanaft_range,ff : { 0.15748, 1 }",
|
||||||
"/region4/chanaft_range,ii : { 10, 10 }",
|
"/region4/chanaft_range,ff : { 0.0787402, 0.0787402 }",
|
||||||
};
|
};
|
||||||
REQUIRE(messageList == expected);
|
REQUIRE(messageList == expected);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue