Add a modifier structure and rename the ccvalue pair
This commit is contained in:
parent
0fd1c235de
commit
61d1c568a8
12 changed files with 108 additions and 118 deletions
|
|
@ -44,11 +44,11 @@ public:
|
|||
*/
|
||||
const ValueType& getWithDefault(int index) const noexcept
|
||||
{
|
||||
auto it = absl::c_lower_bound(container, index, CCValuePairComparator<ValueType>{});
|
||||
auto it = absl::c_lower_bound(container, index, CCDataComparator<ValueType>{});
|
||||
if (it == container.end() || it->cc != index) {
|
||||
return defaultValue;
|
||||
} else {
|
||||
return it->value;
|
||||
return it->data;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -60,12 +60,12 @@ public:
|
|||
*/
|
||||
ValueType& operator[](const int& index) noexcept
|
||||
{
|
||||
auto it = absl::c_lower_bound(container, index, CCValuePairComparator<ValueType>{});
|
||||
auto it = absl::c_lower_bound(container, index, CCDataComparator<ValueType>{});
|
||||
if (it == container.end() || it->cc != index) {
|
||||
auto inserted = container.insert(it, { index, defaultValue });
|
||||
return inserted->value;
|
||||
return inserted->data;
|
||||
} else {
|
||||
return it->value;
|
||||
return it->data;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,16 +85,16 @@ public:
|
|||
*/
|
||||
bool contains(int index) const noexcept
|
||||
{
|
||||
return absl::c_binary_search(container, index, CCValuePairComparator<ValueType>{});
|
||||
return absl::c_binary_search(container, index, CCDataComparator<ValueType>{});
|
||||
}
|
||||
typename std::vector<CCValuePair<ValueType>>::const_iterator begin() const { return container.cbegin(); }
|
||||
typename std::vector<CCValuePair<ValueType>>::const_iterator end() const { return container.cend(); }
|
||||
typename std::vector<CCData<ValueType>>::const_iterator begin() const { return container.cbegin(); }
|
||||
typename std::vector<CCData<ValueType>>::const_iterator end() const { return container.cend(); }
|
||||
private:
|
||||
// typename std::vector<std::pair<int, ValueType>>::iterator begin() { return container.begin(); }
|
||||
// typename std::vector<std::pair<int, ValueType>>::iterator end() { return container.end(); }
|
||||
|
||||
const ValueType defaultValue;
|
||||
std::vector<CCValuePair<ValueType>> container;
|
||||
std::vector<CCData<ValueType>> container;
|
||||
LEAK_DETECTOR(CCMap);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ namespace Default
|
|||
constexpr Range<uint8_t> midi7Range { 0, 127 };
|
||||
constexpr Range<float> normalizedRange { 0.0f, 1.0f };
|
||||
constexpr Range<float> symmetricNormalizedRange { -1.0, 1.0 };
|
||||
constexpr float zeroModifier { 0.0f };
|
||||
|
||||
// Wavetable oscillator
|
||||
constexpr float oscillatorPhase { 0.0 };
|
||||
|
|
|
|||
|
|
@ -50,10 +50,10 @@ namespace sfz {
|
|||
* @param value
|
||||
* @return float
|
||||
*/
|
||||
inline float ccSwitchedValue(const MidiState& state, const absl::optional<CCValuePair<float>>& ccSwitch, float value) noexcept
|
||||
inline float ccSwitchedValue(const MidiState& state, const absl::optional<CCData<float>>& ccSwitch, float value) noexcept
|
||||
{
|
||||
if (ccSwitch)
|
||||
return value + ccSwitch->value * state.getCCValue(ccSwitch->cc);
|
||||
return value + ccSwitch->data * state.getCCValue(ccSwitch->cc);
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
|
@ -80,13 +80,13 @@ struct EGDescription {
|
|||
float vel2sustain { Default::vel2sustain };
|
||||
int vel2depth { Default::depth };
|
||||
|
||||
absl::optional<CCValuePair<float>> ccAttack;
|
||||
absl::optional<CCValuePair<float>> ccDecay;
|
||||
absl::optional<CCValuePair<float>> ccDelay;
|
||||
absl::optional<CCValuePair<float>> ccHold;
|
||||
absl::optional<CCValuePair<float>> ccRelease;
|
||||
absl::optional<CCValuePair<float>> ccStart;
|
||||
absl::optional<CCValuePair<float>> ccSustain;
|
||||
absl::optional<CCData<float>> ccAttack;
|
||||
absl::optional<CCData<float>> ccDecay;
|
||||
absl::optional<CCData<float>> ccDelay;
|
||||
absl::optional<CCData<float>> ccHold;
|
||||
absl::optional<CCData<float>> ccRelease;
|
||||
absl::optional<CCData<float>> ccStart;
|
||||
absl::optional<CCData<float>> ccSustain;
|
||||
|
||||
/**
|
||||
* @brief Get the attack with possibly a CC modifier and a velocity modifier
|
||||
|
|
|
|||
|
|
@ -29,17 +29,17 @@ void sfz::EQHolder::setup(const EQDescription& description, unsigned numChannels
|
|||
// Setup the modulated values
|
||||
lastFrequency = baseFrequency;
|
||||
for (const auto& mod : description.frequencyCC)
|
||||
lastFrequency += midiState.getCCValue(mod.cc) * mod.value;
|
||||
lastFrequency += midiState.getCCValue(mod.cc) * mod.data;
|
||||
lastFrequency = Default::eqFrequencyRange.clamp(lastFrequency);
|
||||
|
||||
lastBandwidth = baseBandwidth;
|
||||
for (const auto& mod : description.bandwidthCC)
|
||||
lastBandwidth += midiState.getCCValue(mod.cc) * mod.value;
|
||||
lastBandwidth += midiState.getCCValue(mod.cc) * mod.data;
|
||||
lastBandwidth = Default::eqBandwidthRange.clamp(lastBandwidth);
|
||||
|
||||
lastGain = baseGain;
|
||||
for (const auto& mod : description.gainCC)
|
||||
lastGain += midiState.getCCValue(mod.cc) * mod.value;
|
||||
lastGain += midiState.getCCValue(mod.cc) * mod.data;
|
||||
lastGain = Default::filterGainRange.clamp(lastGain);
|
||||
|
||||
// Initialize the EQ
|
||||
|
|
@ -62,17 +62,17 @@ void sfz::EQHolder::process(const float** inputs, float** outputs, unsigned numF
|
|||
// For now we take the last value
|
||||
lastFrequency = baseFrequency;
|
||||
for (const auto& mod : description->frequencyCC)
|
||||
lastFrequency += midiState.getCCValue(mod.cc) * mod.value;
|
||||
lastFrequency += midiState.getCCValue(mod.cc) * mod.data;
|
||||
lastFrequency = Default::eqFrequencyRange.clamp(lastFrequency);
|
||||
|
||||
lastBandwidth = baseBandwidth;
|
||||
for (const auto& mod : description->bandwidthCC)
|
||||
lastBandwidth += midiState.getCCValue(mod.cc) * mod.value;
|
||||
lastBandwidth += midiState.getCCValue(mod.cc) * mod.data;
|
||||
lastBandwidth = Default::eqBandwidthRange.clamp(lastBandwidth);
|
||||
|
||||
lastGain = baseGain;
|
||||
for (const auto& mod : description->gainCC)
|
||||
lastGain += midiState.getCCValue(mod.cc) * mod.value;
|
||||
lastGain += midiState.getCCValue(mod.cc) * mod.data;
|
||||
lastGain = Default::filterGainRange.clamp(lastGain);
|
||||
|
||||
if (lastGain == 0.0f) {
|
||||
|
|
|
|||
|
|
@ -41,17 +41,17 @@ void sfz::FilterHolder::setup(const FilterDescription& description, unsigned num
|
|||
// Setup the modulated values
|
||||
lastCutoff = baseCutoff;
|
||||
for (const auto& mod : description.cutoffCC)
|
||||
lastCutoff *= centsFactor(midiState.getCCValue(mod.cc) * mod.value);
|
||||
lastCutoff *= centsFactor(midiState.getCCValue(mod.cc) * mod.data);
|
||||
lastCutoff = Default::filterCutoffRange.clamp(lastCutoff);
|
||||
|
||||
lastResonance = baseResonance;
|
||||
for (const auto& mod : description.resonanceCC)
|
||||
lastResonance += midiState.getCCValue(mod.cc) * mod.value;
|
||||
lastResonance += midiState.getCCValue(mod.cc) * mod.data;
|
||||
lastResonance = Default::filterResonanceRange.clamp(lastResonance);
|
||||
|
||||
lastGain = baseGain;
|
||||
for (const auto& mod : description.gainCC)
|
||||
lastGain += midiState.getCCValue(mod.cc) * mod.value;
|
||||
lastGain += midiState.getCCValue(mod.cc) * mod.data;
|
||||
lastGain = Default::filterGainRange.clamp(lastGain);
|
||||
|
||||
// Initialize the filter
|
||||
|
|
@ -71,17 +71,17 @@ void sfz::FilterHolder::process(const float** inputs, float** outputs, unsigned
|
|||
// TODO: the template deduction could be automatic here?
|
||||
lastCutoff = baseCutoff;
|
||||
for (const auto& mod : description->cutoffCC)
|
||||
lastCutoff *= centsFactor(midiState.getCCValue(mod.cc) * mod.value);
|
||||
lastCutoff *= centsFactor(midiState.getCCValue(mod.cc) * mod.data);
|
||||
lastCutoff = Default::filterCutoffRange.clamp(lastCutoff);
|
||||
|
||||
lastResonance = baseResonance;
|
||||
for (const auto& mod : description->resonanceCC)
|
||||
lastResonance += midiState.getCCValue(mod.cc) * mod.value;
|
||||
lastResonance += midiState.getCCValue(mod.cc) * mod.data;
|
||||
lastResonance = Default::filterResonanceRange.clamp(lastResonance);
|
||||
|
||||
lastGain = baseGain;
|
||||
for (const auto& mod : description->gainCC)
|
||||
lastGain += midiState.getCCValue(mod.cc) * mod.value;
|
||||
lastGain += midiState.getCCValue(mod.cc) * mod.data;
|
||||
lastGain = Default::filterGainRange.clamp(lastGain);
|
||||
|
||||
filter.process(inputs, outputs, lastCutoff, lastResonance, lastGain, numFrames);
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ inline void setRangeStartFromOpcode(const Opcode& opcode, Range<ValueType>& targ
|
|||
* @param validRange the range of admitted values used to clamp the opcode
|
||||
*/
|
||||
template <class ValueType>
|
||||
inline void setCCPairFromOpcode(const Opcode& opcode, absl::optional<CCValuePair<ValueType>>& target, const Range<ValueType>& validRange)
|
||||
inline void setCCPairFromOpcode(const Opcode& opcode, absl::optional<CCData<ValueType>>& target, const Range<ValueType>& validRange)
|
||||
{
|
||||
auto value = readOpcode(opcode.value, validRange);
|
||||
if (value && Default::ccNumberRange.containsWithEnd(opcode.parameters.back()))
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
|
|||
if (opcode.parameters.back() > config::numCCs)
|
||||
return false;
|
||||
if (auto value = readOpcode(opcode.value, Default::volumeCCRange))
|
||||
volumeCC[opcode.parameters.back()] = *value;
|
||||
volumeCC[opcode.parameters.back()].value = *value;
|
||||
break;
|
||||
case hash("amplitude"):
|
||||
if (auto value = readOpcode(opcode.value, Default::amplitudeRange))
|
||||
|
|
@ -314,7 +314,7 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
|
|||
if (opcode.parameters.back() > config::numCCs)
|
||||
return false;
|
||||
if (auto value = readOpcode(opcode.value, Default::amplitudeRange))
|
||||
amplitudeCC[opcode.parameters.back()] = normalizePercents(*value);
|
||||
amplitudeCC[opcode.parameters.back()].value = normalizePercents(*value);
|
||||
break;
|
||||
case hash("pan"):
|
||||
if (auto value = readOpcode(opcode.value, Default::panRange))
|
||||
|
|
@ -325,7 +325,7 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
|
|||
if (opcode.parameters.back() > config::numCCs)
|
||||
return false;
|
||||
if (auto value = readOpcode(opcode.value, Default::panCCRange))
|
||||
panCC[opcode.parameters.back()] = normalizePercents(*value);
|
||||
panCC[opcode.parameters.back()].value = normalizePercents(*value);
|
||||
break;
|
||||
case hash("position"):
|
||||
if (auto value = readOpcode(opcode.value, Default::positionRange))
|
||||
|
|
@ -335,7 +335,7 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
|
|||
if (opcode.parameters.back() > config::numCCs)
|
||||
return false;
|
||||
if (auto value = readOpcode(opcode.value, Default::positionCCRange))
|
||||
positionCC[opcode.parameters.back()] = normalizePercents(*value);
|
||||
positionCC[opcode.parameters.back()].value = normalizePercents(*value);
|
||||
break;
|
||||
case hash("width"):
|
||||
if (auto value = readOpcode(opcode.value, Default::widthRange))
|
||||
|
|
@ -345,7 +345,7 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
|
|||
if (opcode.parameters.back() > config::numCCs)
|
||||
return false;
|
||||
if (auto value = readOpcode(opcode.value, Default::widthCCRange))
|
||||
widthCC[opcode.parameters.back()] = normalizePercents(*value);
|
||||
widthCC[opcode.parameters.back()].value = normalizePercents(*value);
|
||||
break;
|
||||
case hash("amp_keycenter"):
|
||||
setValueFromOpcode(opcode, ampKeycenter, Default::keyRange);
|
||||
|
|
@ -733,7 +733,7 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
|
|||
if (opcode.parameters.back() > config::numCCs)
|
||||
return false;
|
||||
if (auto value = readOpcode(opcode.value, Default::tuneCCRange))
|
||||
tuneCC[opcode.parameters.back()] = *value;
|
||||
tuneCC[opcode.parameters.back()].value = *value;
|
||||
break;
|
||||
case hash("bend_up"):
|
||||
setValueFromOpcode(opcode, bendUp, Default::bendBoundRange);
|
||||
|
|
@ -1078,15 +1078,15 @@ float sfz::Region::getCrossfadeGain() const noexcept
|
|||
float gain { 1.0f };
|
||||
|
||||
// Crossfades due to CC states
|
||||
for (const auto& valuePair : crossfadeCCInRange) {
|
||||
const auto ccValue = midiState.getCCValue(valuePair.cc);
|
||||
const auto crossfadeRange = valuePair.value;
|
||||
for (const auto& ccData : crossfadeCCInRange) {
|
||||
const auto ccValue = midiState.getCCValue(ccData.cc);
|
||||
const auto crossfadeRange = ccData.data;
|
||||
gain *= crossfadeIn(crossfadeRange, ccValue, crossfadeCCCurve);
|
||||
}
|
||||
|
||||
for (const auto& valuePair : crossfadeCCOutRange) {
|
||||
const auto ccValue = midiState.getCCValue(valuePair.cc);
|
||||
const auto crossfadeRange = valuePair.value;
|
||||
for (const auto& ccData : crossfadeCCOutRange) {
|
||||
const auto ccValue = midiState.getCCValue(ccData.cc);
|
||||
const auto crossfadeRange = ccData.data;
|
||||
gain *= crossfadeOut(crossfadeRange, ccValue, crossfadeCCCurve);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -285,11 +285,11 @@ struct Region {
|
|||
float pan { normalizePercents(Default::pan) }; // pan
|
||||
float width { normalizePercents(Default::width) }; // width
|
||||
float position { normalizePercents(Default::position) }; // position
|
||||
CCMap<float> volumeCC { Default::zeroModifier }; // volume_oncc
|
||||
CCMap<float> amplitudeCC { Default::zeroModifier }; // amplitude_oncc
|
||||
CCMap<float> panCC { Default::zeroModifier }; // pan_oncc
|
||||
CCMap<float> widthCC { Default::zeroModifier }; // width_oncc
|
||||
CCMap<float> positionCC { Default::zeroModifier }; // position_oncc
|
||||
CCMap<Modifier> volumeCC { {} }; // volume_oncc
|
||||
CCMap<Modifier> amplitudeCC { {} }; // amplitude_oncc
|
||||
CCMap<Modifier> panCC { {} }; // pan_oncc
|
||||
CCMap<Modifier> widthCC { {} }; // width_oncc
|
||||
CCMap<Modifier> positionCC { {} }; // position_oncc
|
||||
uint8_t ampKeycenter { Default::ampKeycenter }; // amp_keycenter
|
||||
float ampKeytrack { Default::ampKeytrack }; // amp_keytrack
|
||||
float ampVeltrack { Default::ampVeltrack }; // amp_keytrack
|
||||
|
|
@ -317,7 +317,7 @@ struct Region {
|
|||
int pitchVeltrack { Default::pitchVeltrack }; // pitch_veltrack
|
||||
int transpose { Default::transpose }; // transpose
|
||||
int tune { Default::tune }; // tune
|
||||
CCMap<int> tuneCC { Default::tune };
|
||||
CCMap<Modifier> tuneCC { {} };
|
||||
int bendUp { Default::bendUp };
|
||||
int bendDown { Default::bendDown };
|
||||
int bendStep { Default::bendStep };
|
||||
|
|
|
|||
|
|
@ -24,44 +24,35 @@ using CCNamePair = std::pair<uint16_t, std::string>;
|
|||
template <class T>
|
||||
using MidiNoteArray = std::array<T, 128>;
|
||||
template<class ValueType>
|
||||
struct CCValuePair {
|
||||
struct CCData {
|
||||
int cc;
|
||||
ValueType value;
|
||||
ValueType data;
|
||||
static_assert(config::numCCs - 1 < std::numeric_limits<decltype(cc)>::max());
|
||||
};
|
||||
|
||||
template<class ValueType, bool CompareValue = false>
|
||||
struct CCValuePairComparator {
|
||||
bool operator()(const CCValuePair<ValueType>& valuePair, const int& cc)
|
||||
{
|
||||
return (valuePair.cc < cc);
|
||||
}
|
||||
|
||||
bool operator()(const int& cc, const CCValuePair<ValueType>& valuePair)
|
||||
{
|
||||
return (cc < valuePair.cc);
|
||||
}
|
||||
|
||||
bool operator()(const CCValuePair<ValueType>& lhs, const CCValuePair<ValueType>& rhs)
|
||||
{
|
||||
return (lhs.cc < rhs.cc);
|
||||
}
|
||||
struct Modifier {
|
||||
float value { 0.0f };
|
||||
uint8_t curve { 0 };
|
||||
uint8_t steps { 0 };
|
||||
uint8_t smooth { 0 };
|
||||
static_assert(config::maxCurves - 1 <= std::numeric_limits<decltype(curve)>::max());
|
||||
};
|
||||
|
||||
template<class ValueType>
|
||||
struct CCValuePairComparator<ValueType, true> {
|
||||
bool operator()(const CCValuePair<ValueType>& valuePair, const ValueType& value)
|
||||
struct CCDataComparator {
|
||||
bool operator()(const CCData<ValueType>& ccData, const int& cc)
|
||||
{
|
||||
return (valuePair.value < value);
|
||||
return (ccData.cc < cc);
|
||||
}
|
||||
|
||||
bool operator()(const ValueType& value, const CCValuePair<ValueType>& valuePair)
|
||||
bool operator()(const int& cc, const CCData<ValueType>& ccData)
|
||||
{
|
||||
return (value < valuePair.value);
|
||||
return (cc < ccData.cc);
|
||||
}
|
||||
|
||||
bool operator()(const CCValuePair<ValueType>& lhs, const CCValuePair<ValueType>& rhs)
|
||||
bool operator()(const CCData<ValueType>& lhs, const CCData<ValueType>& rhs)
|
||||
{
|
||||
return (lhs.value < rhs.value);
|
||||
return (lhs.cc < rhs.cc);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -265,19 +265,19 @@ void sfz::Voice::amplitudeEnvelope(absl::Span<float> modulationSpan) noexcept
|
|||
applyGain<float>(baseGain, modulationSpan);
|
||||
for (const auto& mod : region->amplitudeCC) {
|
||||
const auto events = resources.midiState.getCCEvents(mod.cc);
|
||||
linearEnvelope(events, *tempSpan, [&mod](float x) { return x * mod.value; });
|
||||
linearEnvelope(events, *tempSpan, [&mod](float x) { return x * mod.data.value; });
|
||||
applyGain<float>(*tempSpan, modulationSpan);
|
||||
}
|
||||
|
||||
// Crossfade envelopes
|
||||
for (const auto& mod : region->crossfadeCCInRange) {
|
||||
const auto events = resources.midiState.getCCEvents(mod.cc);
|
||||
linearEnvelope(events, *tempSpan, [&](float x) { return crossfadeIn(mod.value, x, xfCurve); });
|
||||
linearEnvelope(events, *tempSpan, [&](float x) { return crossfadeIn(mod.data, x, xfCurve); });
|
||||
applyGain<float>(*tempSpan, modulationSpan);
|
||||
}
|
||||
for (const auto& mod : region->crossfadeCCOutRange) {
|
||||
const auto events = resources.midiState.getCCEvents(mod.cc);
|
||||
linearEnvelope(events, *tempSpan, [&](float x) { return crossfadeOut(mod.value, x, xfCurve); });
|
||||
linearEnvelope(events, *tempSpan, [&](float x) { return crossfadeOut(mod.data, x, xfCurve); });
|
||||
applyGain<float>(*tempSpan, modulationSpan);
|
||||
}
|
||||
|
||||
|
|
@ -285,7 +285,7 @@ void sfz::Voice::amplitudeEnvelope(absl::Span<float> modulationSpan) noexcept
|
|||
applyGain<float>(db2mag(baseVolumedB), modulationSpan);
|
||||
for (const auto& mod : region->volumeCC) {
|
||||
const auto events = resources.midiState.getCCEvents(mod.cc);
|
||||
multiplicativeEnvelope(events, *tempSpan, [&](float x) { return db2mag(x * mod.value); });
|
||||
multiplicativeEnvelope(events, *tempSpan, [&](float x) { return db2mag(x * mod.data.value); });
|
||||
applyGain<float>(*tempSpan, modulationSpan);
|
||||
}
|
||||
}
|
||||
|
|
@ -338,7 +338,7 @@ void sfz::Voice::panStageMono(AudioSpan<float> buffer) noexcept
|
|||
fill<float>(*modulationSpan, region->pan);
|
||||
for (const auto& mod : region->panCC) {
|
||||
const auto events = resources.midiState.getCCEvents(mod.cc);
|
||||
linearEnvelope(events, *tempSpan, [&mod](float x) { return x * mod.value; });
|
||||
linearEnvelope(events, *tempSpan, [&mod](float x) { return x * mod.data.value; });
|
||||
add<float>(*tempSpan, *modulationSpan);
|
||||
}
|
||||
pan<float>(*modulationSpan, leftBuffer, rightBuffer);
|
||||
|
|
@ -361,7 +361,7 @@ void sfz::Voice::panStageStereo(AudioSpan<float> buffer) noexcept
|
|||
fill<float>(*modulationSpan, region->pan);
|
||||
for (const auto& mod : region->panCC) {
|
||||
const auto events = resources.midiState.getCCEvents(mod.cc);
|
||||
linearEnvelope(events, *tempSpan, [&mod](float x) { return x * mod.value; });
|
||||
linearEnvelope(events, *tempSpan, [&mod](float x) { return x * mod.data.value; });
|
||||
add<float>(*tempSpan, *modulationSpan);
|
||||
}
|
||||
pan<float>(*modulationSpan, leftBuffer, rightBuffer);
|
||||
|
|
@ -371,7 +371,7 @@ void sfz::Voice::panStageStereo(AudioSpan<float> buffer) noexcept
|
|||
fill<float>(*modulationSpan, region->width);
|
||||
for (const auto& mod : region->widthCC) {
|
||||
const auto events = resources.midiState.getCCEvents(mod.cc);
|
||||
linearEnvelope(events, *tempSpan, [&mod](float x) { return x * mod.value; });
|
||||
linearEnvelope(events, *tempSpan, [&mod](float x) { return x * mod.data.value; });
|
||||
add<float>(*tempSpan, *modulationSpan);
|
||||
}
|
||||
width<float>(*modulationSpan, leftBuffer, rightBuffer);
|
||||
|
|
@ -380,7 +380,7 @@ void sfz::Voice::panStageStereo(AudioSpan<float> buffer) noexcept
|
|||
fill<float>(*modulationSpan, region->position);
|
||||
for (const auto& mod : region->positionCC) {
|
||||
const auto events = resources.midiState.getCCEvents(mod.cc);
|
||||
linearEnvelope(events, *tempSpan, [&mod](float x) { return x * mod.value; });
|
||||
linearEnvelope(events, *tempSpan, [&mod](float x) { return x * mod.data.value; });
|
||||
add<float>(*tempSpan, *modulationSpan);
|
||||
}
|
||||
pan<float>(*modulationSpan, leftBuffer, rightBuffer);
|
||||
|
|
@ -458,7 +458,7 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
|
|||
|
||||
for (const auto& mod : region->tuneCC) {
|
||||
const auto events = resources.midiState.getCCEvents(mod.cc);
|
||||
multiplicativeEnvelope(events, *bends, [&](float x) { return centsFactor(x * mod.value); });
|
||||
multiplicativeEnvelope(events, *bends, [&](float x) { return centsFactor(x * mod.data.value); });
|
||||
applyGain<float>(*bends, *jumps);
|
||||
}
|
||||
|
||||
|
|
@ -562,7 +562,7 @@ void sfz::Voice::fillWithGenerator(AudioSpan<float> buffer) noexcept
|
|||
|
||||
for (const auto& mod : region->tuneCC) {
|
||||
const auto events = resources.midiState.getCCEvents(mod.cc);
|
||||
multiplicativeEnvelope(events, *bends, [&](float x) { return centsFactor(x * mod.value); });
|
||||
multiplicativeEnvelope(events, *bends, [&](float x) { return centsFactor(x * mod.data.value); });
|
||||
applyGain<float>(*bends, *frequencies);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -351,7 +351,7 @@ TEST_CASE("[Files] wrong (overlapping) replacement for defines")
|
|||
REQUIRE( synth.getRegionView(1)->keyRange.getEnd() == 57 );
|
||||
REQUIRE(!synth.getRegionView(2)->amplitudeCC.empty());
|
||||
REQUIRE(synth.getRegionView(2)->amplitudeCC.contains(10));
|
||||
REQUIRE(synth.getRegionView(2)->amplitudeCC.getWithDefault(10) == 0.34f);
|
||||
REQUIRE(synth.getRegionView(2)->amplitudeCC.getWithDefault(10).value == 0.34f);
|
||||
}
|
||||
|
||||
TEST_CASE("[Files] Specific bug: relative path with backslashes")
|
||||
|
|
|
|||
|
|
@ -470,7 +470,7 @@ TEST_CASE("[Region] Parsing opcodes")
|
|||
REQUIRE(region.panCC.empty());
|
||||
region.parseOpcode({ "pan_oncc45", "4.2" });
|
||||
REQUIRE(region.panCC.contains(45));
|
||||
REQUIRE(region.panCC[45] == 0.042_a);
|
||||
REQUIRE(region.panCC[45].value == 0.042_a);
|
||||
}
|
||||
|
||||
SECTION("width")
|
||||
|
|
@ -491,7 +491,7 @@ TEST_CASE("[Region] Parsing opcodes")
|
|||
REQUIRE(region.widthCC.empty());
|
||||
region.parseOpcode({ "width_oncc45", "4.2" });
|
||||
REQUIRE(region.widthCC.contains(45));
|
||||
REQUIRE(region.widthCC[45] == 0.042_a);
|
||||
REQUIRE(region.widthCC[45].value == 0.042_a);
|
||||
}
|
||||
|
||||
SECTION("position")
|
||||
|
|
@ -512,7 +512,7 @@ TEST_CASE("[Region] Parsing opcodes")
|
|||
REQUIRE(region.positionCC.empty());
|
||||
region.parseOpcode({ "position_oncc45", "4.2" });
|
||||
REQUIRE(region.positionCC.contains(45));
|
||||
REQUIRE(region.positionCC[45] == 0.042_a);
|
||||
REQUIRE(region.positionCC[45].value == 0.042_a);
|
||||
}
|
||||
|
||||
SECTION("amp_keycenter")
|
||||
|
|
@ -974,13 +974,13 @@ TEST_CASE("[Region] Parsing opcodes")
|
|||
REQUIRE(region.amplitudeEG.ccRelease->cc == 5);
|
||||
REQUIRE(region.amplitudeEG.ccStart->cc == 6);
|
||||
REQUIRE(region.amplitudeEG.ccSustain->cc == 7);
|
||||
REQUIRE(region.amplitudeEG.ccAttack->value == 1.0f);
|
||||
REQUIRE(region.amplitudeEG.ccDecay->value == 2.0f);
|
||||
REQUIRE(region.amplitudeEG.ccDelay->value == 3.0f);
|
||||
REQUIRE(region.amplitudeEG.ccHold->value == 4.0f);
|
||||
REQUIRE(region.amplitudeEG.ccRelease->value == 5.0f);
|
||||
REQUIRE(region.amplitudeEG.ccStart->value == 6.0f);
|
||||
REQUIRE(region.amplitudeEG.ccSustain->value == 7.0f);
|
||||
REQUIRE(region.amplitudeEG.ccAttack->data == 1.0f);
|
||||
REQUIRE(region.amplitudeEG.ccDecay->data == 2.0f);
|
||||
REQUIRE(region.amplitudeEG.ccDelay->data == 3.0f);
|
||||
REQUIRE(region.amplitudeEG.ccHold->data == 4.0f);
|
||||
REQUIRE(region.amplitudeEG.ccRelease->data == 5.0f);
|
||||
REQUIRE(region.amplitudeEG.ccStart->data == 6.0f);
|
||||
REQUIRE(region.amplitudeEG.ccSustain->data == 7.0f);
|
||||
//
|
||||
region.parseOpcode({ "ampeg_attack_oncc1", "101" });
|
||||
region.parseOpcode({ "ampeg_decay_oncc2", "101" });
|
||||
|
|
@ -989,13 +989,13 @@ TEST_CASE("[Region] Parsing opcodes")
|
|||
region.parseOpcode({ "ampeg_release_oncc5", "101" });
|
||||
region.parseOpcode({ "ampeg_start_oncc6", "101" });
|
||||
region.parseOpcode({ "ampeg_sustain_oncc7", "101" });
|
||||
REQUIRE(region.amplitudeEG.ccAttack->value == 100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccDecay->value == 100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccDelay->value == 100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccHold->value == 100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccRelease->value == 100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccStart->value == 100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccSustain->value == 100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccAttack->data == 100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccDecay->data == 100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccDelay->data == 100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccHold->data == 100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccRelease->data == 100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccStart->data == 100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccSustain->data == 100.0f);
|
||||
//
|
||||
region.parseOpcode({ "ampeg_attack_oncc1", "-101" });
|
||||
region.parseOpcode({ "ampeg_decay_oncc2", "-101" });
|
||||
|
|
@ -1004,13 +1004,13 @@ TEST_CASE("[Region] Parsing opcodes")
|
|||
region.parseOpcode({ "ampeg_release_oncc5", "-101" });
|
||||
region.parseOpcode({ "ampeg_start_oncc6", "-101" });
|
||||
region.parseOpcode({ "ampeg_sustain_oncc7", "-101" });
|
||||
REQUIRE(region.amplitudeEG.ccAttack->value == -100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccDecay->value == -100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccDelay->value == -100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccHold->value == -100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccRelease->value == -100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccStart->value == -100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccSustain->value == -100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccAttack->data == -100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccDecay->data == -100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccDelay->data == -100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccHold->data == -100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccRelease->data == -100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccStart->data == -100.0f);
|
||||
REQUIRE(region.amplitudeEG.ccSustain->data == -100.0f);
|
||||
}
|
||||
|
||||
SECTION("sustain_sw and sostenuto_sw")
|
||||
|
|
@ -1448,10 +1448,10 @@ TEST_CASE("[Region] Parsing opcodes")
|
|||
REQUIRE(region.amplitudeCC.empty());
|
||||
region.parseOpcode({ "amplitude_cc1", "40" });
|
||||
REQUIRE(region.amplitudeCC.contains(1));
|
||||
REQUIRE(region.amplitudeCC[1] == 0.40_a);
|
||||
REQUIRE(region.amplitudeCC[1].value == 0.40_a);
|
||||
region.parseOpcode({ "amplitude_oncc2", "30" });
|
||||
REQUIRE(region.amplitudeCC.contains(2));
|
||||
REQUIRE(region.amplitudeCC[2] == 0.30_a);
|
||||
REQUIRE(region.amplitudeCC[2].value == 0.30_a);
|
||||
}
|
||||
|
||||
SECTION("volume_oncc/gain_cc")
|
||||
|
|
@ -1459,13 +1459,13 @@ TEST_CASE("[Region] Parsing opcodes")
|
|||
REQUIRE(region.volumeCC.empty());
|
||||
region.parseOpcode({ "gain_cc1", "40" });
|
||||
REQUIRE(region.volumeCC.contains(1));
|
||||
REQUIRE(region.volumeCC[1] == 40_a);
|
||||
REQUIRE(region.volumeCC[1].value == 40_a);
|
||||
region.parseOpcode({ "volume_oncc2", "-76" });
|
||||
REQUIRE(region.volumeCC.contains(2));
|
||||
REQUIRE(region.volumeCC[2] == -76.0_a);
|
||||
REQUIRE(region.volumeCC[2].value == -76.0_a);
|
||||
region.parseOpcode({ "gain_oncc4", "-1" });
|
||||
REQUIRE(region.volumeCC.contains(4));
|
||||
REQUIRE(region.volumeCC[4] == -1.0_a);
|
||||
REQUIRE(region.volumeCC[4].value == -1.0_a);
|
||||
}
|
||||
|
||||
SECTION("tune_cc/pitch_cc")
|
||||
|
|
@ -1473,13 +1473,13 @@ TEST_CASE("[Region] Parsing opcodes")
|
|||
REQUIRE(region.tuneCC.empty());
|
||||
region.parseOpcode({ "pitch_cc1", "40" });
|
||||
REQUIRE(region.tuneCC.contains(1));
|
||||
REQUIRE(region.tuneCC[1] == 40);
|
||||
REQUIRE(region.tuneCC[1].value == 40.0);
|
||||
region.parseOpcode({ "tune_oncc2", "-76" });
|
||||
REQUIRE(region.tuneCC.contains(2));
|
||||
REQUIRE(region.tuneCC[2] == -76.0);
|
||||
REQUIRE(region.tuneCC[2].value == -76.0);
|
||||
region.parseOpcode({ "pitch_oncc4", "-1" });
|
||||
REQUIRE(region.tuneCC.contains(4));
|
||||
REQUIRE(region.tuneCC[4] == -1.0);
|
||||
REQUIRE(region.tuneCC[4].value == -1.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue