Formatting step
This commit is contained in:
parent
7e8cdff407
commit
5088bed9b0
16 changed files with 323 additions and 294 deletions
|
|
@ -39,8 +39,8 @@ BENCHMARK_DEFINE_F(EnvelopeFixture, Linear)(benchmark::State& state) {
|
|||
for (auto _ : state)
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{static_cast<int>(state.range(0) - 1), dist(gen)}
|
||||
{ 0, 0.0f },
|
||||
{ static_cast<int>(state.range(0) - 1), dist(gen) }
|
||||
};
|
||||
linearEnvelope(events, absl::MakeSpan(output), [](float x) { return x; });
|
||||
}
|
||||
|
|
@ -50,10 +50,11 @@ BENCHMARK_DEFINE_F(EnvelopeFixture, LinearQuantized)(benchmark::State& state) {
|
|||
for (auto _ : state)
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{static_cast<int>(state.range(0) - 1), dist(gen)}
|
||||
{ 0, 0.0f },
|
||||
{ static_cast<int>(state.range(0) - 1), dist(gen) }
|
||||
};
|
||||
linearEnvelope(events, absl::MakeSpan(output), [](float x) { return x; }, 0.5);
|
||||
linearEnvelope(
|
||||
events, absl::MakeSpan(output), [](float x) { return x; }, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -61,8 +62,8 @@ BENCHMARK_DEFINE_F(EnvelopeFixture, Multiplicative)(benchmark::State& state) {
|
|||
for (auto _ : state)
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 1.0f},
|
||||
{static_cast<int>(state.range(0) - 1), dist(gen)}
|
||||
{ 0, 1.0f },
|
||||
{ static_cast<int>(state.range(0) - 1), dist(gen) }
|
||||
};
|
||||
multiplicativeEnvelope(events, absl::MakeSpan(output), [](float x) { return x; });
|
||||
}
|
||||
|
|
@ -72,10 +73,11 @@ BENCHMARK_DEFINE_F(EnvelopeFixture, MultiplicativeQuantized)(benchmark::State& s
|
|||
for (auto _ : state)
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 1.0f},
|
||||
{static_cast<int>(state.range(0) - 1), dist(gen)}
|
||||
{ 0, 1.0f },
|
||||
{ static_cast<int>(state.range(0) - 1), dist(gen) }
|
||||
};
|
||||
multiplicativeEnvelope(events, absl::MakeSpan(output), [](float x) { return x; }, 2.0f);
|
||||
multiplicativeEnvelope(
|
||||
events, absl::MakeSpan(output), [](float x) { return x; }, 2.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ void ADSREnvelope<Type>::reset(const Region& region, const MidiState& state, int
|
|||
this->release = secondsToSamples(region.amplitudeEG.getRelease(state, velocity));
|
||||
this->hold = secondsToSamples(region.amplitudeEG.getHold(state, velocity));
|
||||
this->peak = 1.0;
|
||||
this->sustain = normalizePercents(region.amplitudeEG.getSustain(state, velocity));
|
||||
this->sustain = normalizePercents(region.amplitudeEG.getSustain(state, velocity));
|
||||
this->start = this->peak * normalizePercents(region.amplitudeEG.getStart(state, velocity));
|
||||
|
||||
releaseDelay = 0;
|
||||
|
|
|
|||
|
|
@ -14,15 +14,13 @@
|
|||
#include <functional>
|
||||
#include "absl/algorithm/container.h"
|
||||
#ifndef NDEBUG
|
||||
#include "MathHelpers.h"
|
||||
#include "MathHelpers.h"
|
||||
#endif
|
||||
|
||||
namespace sfz
|
||||
{
|
||||
namespace sfz {
|
||||
|
||||
template<class T>
|
||||
class SpanHolder
|
||||
{
|
||||
template <class T>
|
||||
class SpanHolder {
|
||||
public:
|
||||
SpanHolder() {}
|
||||
SpanHolder(const SpanHolder<T>&) = delete;
|
||||
|
|
@ -40,7 +38,10 @@ public:
|
|||
other.available = nullptr;
|
||||
}
|
||||
SpanHolder(T&& value, int* available)
|
||||
: value(std::forward<T>(value)), available(available) {}
|
||||
: value(std::forward<T>(value))
|
||||
, available(available)
|
||||
{
|
||||
}
|
||||
T& operator*() { return value; }
|
||||
T* operator->() { return &value; }
|
||||
explicit operator bool() const { return available != nullptr; }
|
||||
|
|
@ -49,13 +50,13 @@ public:
|
|||
if (available)
|
||||
*available += 1;
|
||||
}
|
||||
|
||||
private:
|
||||
T value {};
|
||||
int* available { nullptr };
|
||||
};
|
||||
|
||||
class BufferPool
|
||||
{
|
||||
class BufferPool {
|
||||
public:
|
||||
BufferPool()
|
||||
{
|
||||
|
|
@ -148,7 +149,6 @@ public:
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
private:
|
||||
void _setBufferSize(unsigned bufferSize)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ namespace Default
|
|||
// common defaults
|
||||
constexpr Range<uint8_t> midi7Range { 0, 127 };
|
||||
constexpr Range<float> normalizedRange { 0.0f, 1.0f };
|
||||
constexpr Range<float> symmetricNormalizedRange { -1.0, 1.0 };
|
||||
constexpr Range<float> symmetricNormalizedRange { -1.0, 1.0 };
|
||||
constexpr float zeroModifier { 0.0f };
|
||||
|
||||
// Wavetable oscillator
|
||||
|
|
@ -68,21 +68,21 @@ namespace Default
|
|||
constexpr uint32_t group { 0 };
|
||||
constexpr Range<uint32_t> groupRange { 0, std::numeric_limits<uint32_t>::max() };
|
||||
constexpr SfzOffMode offMode { SfzOffMode::fast };
|
||||
constexpr Range<uint32_t> polyphonyRange { 0, config::maxVoices };
|
||||
constexpr SfzSelfMask selfMask { SfzSelfMask::mask };
|
||||
constexpr Range<uint32_t> polyphonyRange { 0, config::maxVoices };
|
||||
constexpr SfzSelfMask selfMask { SfzSelfMask::mask };
|
||||
|
||||
// Region logic: key mapping
|
||||
// Region logic: key mapping
|
||||
constexpr Range<uint8_t> keyRange { 0, 127 };
|
||||
constexpr auto velocityRange = normalizedRange;
|
||||
constexpr auto velocityRange = normalizedRange;
|
||||
|
||||
// Region logic: MIDI conditions
|
||||
// Region logic: MIDI conditions
|
||||
constexpr Range<uint8_t> channelRange { 1, 16 };
|
||||
constexpr Range<uint8_t> midiChannelRange { 0, 15 };
|
||||
constexpr Range<uint16_t> ccNumberRange { 0, config::numCCs };
|
||||
constexpr auto ccValueRange = normalizedRange;
|
||||
constexpr Range<int> bendRange = { -8192, 8192 };
|
||||
constexpr Range<float> bendValueRange = symmetricNormalizedRange;
|
||||
constexpr int bend { 0 };
|
||||
constexpr Range<uint16_t> ccNumberRange { 0, config::numCCs };
|
||||
constexpr auto ccValueRange = normalizedRange;
|
||||
constexpr Range<int> bendRange = { -8192, 8192 };
|
||||
constexpr Range<float> bendValueRange = symmetricNormalizedRange;
|
||||
constexpr int bend { 0 };
|
||||
constexpr SfzVelocityOverride velocityOverride { SfzVelocityOverride::current };
|
||||
|
||||
// Region logic: internal conditions
|
||||
|
|
@ -97,9 +97,9 @@ namespace Default
|
|||
|
||||
// Region logic: Triggers
|
||||
constexpr SfzTrigger trigger { SfzTrigger::attack };
|
||||
constexpr Range<float> ccTriggerValueRange = normalizedRange;
|
||||
constexpr Range<float> ccTriggerValueRange = normalizedRange;
|
||||
|
||||
// Performance parameters: amplifier
|
||||
// Performance parameters: amplifier
|
||||
constexpr float globalVolume { -7.35f };
|
||||
constexpr float volume { 0.0f };
|
||||
constexpr Range<float> volumeRange { -144.0, 6.0 };
|
||||
|
|
@ -125,11 +125,11 @@ namespace Default
|
|||
constexpr Range<float> ampRandomRange { 0.0, 24.0 };
|
||||
constexpr Range<uint8_t> crossfadeKeyInRange { 0, 0 };
|
||||
constexpr Range<uint8_t> crossfadeKeyOutRange { 127, 127 };
|
||||
constexpr Range<float> crossfadeVelInRange { 0.0f, 0.0f };
|
||||
constexpr Range<float> crossfadeVelOutRange { 1.0f, 1.0f };
|
||||
constexpr Range<float> crossfadeCCInRange { 0.0f, 0.0f };
|
||||
constexpr Range<float> crossfadeCCOutRange { 1.0f, 1.0f };
|
||||
constexpr SfzCrossfadeCurve crossfadeKeyCurve { SfzCrossfadeCurve::power };
|
||||
constexpr Range<float> crossfadeVelInRange { 0.0f, 0.0f };
|
||||
constexpr Range<float> crossfadeVelOutRange { 1.0f, 1.0f };
|
||||
constexpr Range<float> crossfadeCCInRange { 0.0f, 0.0f };
|
||||
constexpr Range<float> crossfadeCCOutRange { 1.0f, 1.0f };
|
||||
constexpr SfzCrossfadeCurve crossfadeKeyCurve { SfzCrossfadeCurve::power };
|
||||
constexpr SfzCrossfadeCurve crossfadeVelCurve { SfzCrossfadeCurve::power };
|
||||
constexpr SfzCrossfadeCurve crossfadeCCCurve { SfzCrossfadeCurve::power };
|
||||
constexpr float rtDecay { 0.0f };
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ void sfz::MidiState::setSampleRate(float sampleRate) noexcept
|
|||
void sfz::MidiState::advanceTime(int numSamples) noexcept
|
||||
{
|
||||
internalClock += numSamples;
|
||||
for (auto& ccEvents: cc) {
|
||||
for (auto& ccEvents : cc) {
|
||||
ASSERT(!ccEvents.empty()); // CC event vectors should never be empty
|
||||
ccEvents.front().value = ccEvents.back().value;
|
||||
ccEvents.front().delay = 0;
|
||||
|
|
@ -66,7 +66,7 @@ void sfz::MidiState::advanceTime(int numSamples) noexcept
|
|||
void sfz::MidiState::setSamplesPerBlock(int samplesPerBlock) noexcept
|
||||
{
|
||||
this->samplesPerBlock = samplesPerBlock;
|
||||
for (auto& ccEvents: cc) {
|
||||
for (auto& ccEvents : cc) {
|
||||
ccEvents.shrink_to_fit();
|
||||
ccEvents.reserve(samplesPerBlock);
|
||||
}
|
||||
|
|
@ -92,12 +92,11 @@ float sfz::MidiState::getNoteVelocity(int noteNumber) const noexcept
|
|||
return lastNoteVelocities[noteNumber];
|
||||
}
|
||||
|
||||
|
||||
void sfz::MidiState::pitchBendEvent(int delay, float pitchBendValue) noexcept
|
||||
{
|
||||
ASSERT(pitchBendValue >= -1.0f && pitchBendValue <= 1.0f);
|
||||
|
||||
const auto insertionPoint = absl::c_upper_bound(pitchEvents, delay, MidiEventDelayComparator{});
|
||||
const auto insertionPoint = absl::c_upper_bound(pitchEvents, delay, MidiEventDelayComparator {});
|
||||
if (insertionPoint == pitchEvents.end() || insertionPoint->delay != delay)
|
||||
pitchEvents.insert(insertionPoint, { delay, pitchBendValue });
|
||||
else
|
||||
|
|
@ -113,7 +112,7 @@ float sfz::MidiState::getPitchBend() const noexcept
|
|||
void sfz::MidiState::ccEvent(int delay, int ccNumber, float ccValue) noexcept
|
||||
{
|
||||
ASSERT(ccValue >= 0.0 && ccValue <= 1.0);
|
||||
const auto insertionPoint = absl::c_upper_bound(cc[ccNumber], delay, MidiEventDelayComparator{});
|
||||
const auto insertionPoint = absl::c_upper_bound(cc[ccNumber], delay, MidiEventDelayComparator {});
|
||||
if (insertionPoint == cc[ccNumber].end() || insertionPoint->delay != delay)
|
||||
cc[ccNumber].insert(insertionPoint, { delay, ccValue });
|
||||
else
|
||||
|
|
@ -132,7 +131,7 @@ void sfz::MidiState::reset() noexcept
|
|||
for (auto& velocity: lastNoteVelocities)
|
||||
velocity = 0;
|
||||
|
||||
for (auto& ccEvents: cc) {
|
||||
for (auto& ccEvents : cc) {
|
||||
ccEvents.clear();
|
||||
ccEvents.push_back({ 0, 0.0f });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public:
|
|||
* @param noteNumber
|
||||
* @param velocity
|
||||
*/
|
||||
void noteOnEvent(int delay, int noteNumber, float velocity) noexcept;
|
||||
void noteOnEvent(int delay, int noteNumber, float velocity) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Update the state after a note off event
|
||||
|
|
@ -36,7 +36,7 @@ public:
|
|||
* @param noteNumber
|
||||
* @param velocity
|
||||
*/
|
||||
void noteOffEvent(int delay, int noteNumber, float velocity) noexcept;
|
||||
void noteOffEvent(int delay, int noteNumber, float velocity) noexcept;
|
||||
|
||||
int getActiveNotes() const noexcept { return activeNotes; }
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ public:
|
|||
* @param delay
|
||||
* @return float
|
||||
*/
|
||||
float getNoteDuration(int noteNumber, int delay = 0) const;
|
||||
float getNoteDuration(int noteNumber, int delay = 0) const;
|
||||
|
||||
/**
|
||||
* @brief Set the maximum size of the blocks for the callback. The actual
|
||||
|
|
@ -70,7 +70,7 @@ public:
|
|||
* @param noteNumber
|
||||
* @return float
|
||||
*/
|
||||
float getNoteVelocity(int noteNumber) const noexcept;
|
||||
float getNoteVelocity(int noteNumber) const noexcept;
|
||||
|
||||
/**
|
||||
* @brief Register a pitch bend event
|
||||
|
|
@ -125,35 +125,42 @@ public:
|
|||
const EventVector& getPitchEvents() const noexcept;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
int activeNotes { 0 };
|
||||
int activeNotes { 0 };
|
||||
|
||||
/**
|
||||
* @brief Stores the note on times.
|
||||
*
|
||||
*/
|
||||
MidiNoteArray<unsigned> noteOnTimes {{}};
|
||||
MidiNoteArray<unsigned> noteOnTimes { {} };
|
||||
|
||||
/**
|
||||
* @brief Stores the note off times.
|
||||
*
|
||||
*/
|
||||
MidiNoteArray<unsigned> noteOffTimes {{}};
|
||||
|
||||
MidiNoteArray<unsigned> noteOffTimes { {} };
|
||||
|
||||
/**
|
||||
* @brief Stores the velocity of the note ons for currently
|
||||
* depressed notes.
|
||||
*
|
||||
*/
|
||||
MidiNoteArray<float> lastNoteVelocities;
|
||||
MidiNoteArray<float> lastNoteVelocities;
|
||||
|
||||
/**
|
||||
* @brief Current known values for the CCs.
|
||||
*
|
||||
*/
|
||||
std::array<EventVector, config::numCCs> cc;
|
||||
std::array<EventVector, config::numCCs> cc;
|
||||
|
||||
const EventVector nullEvent {{0, 0.0f}};
|
||||
/**
|
||||
* Pitch bend status
|
||||
* @brief Null event
|
||||
*
|
||||
*/
|
||||
const EventVector nullEvent { { 0, 0.0f } };
|
||||
|
||||
/**
|
||||
* @brief Pitch bend status
|
||||
*/
|
||||
EventVector pitchEvents;
|
||||
float sampleRate { config::defaultSampleRate };
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace sfz
|
|||
{
|
||||
|
||||
using CCNamePair = std::pair<uint16_t, std::string>;
|
||||
template<class T>
|
||||
template <class T>
|
||||
using MidiNoteArray = std::array<T, 128>;
|
||||
template<class ValueType>
|
||||
struct CCValuePair {
|
||||
|
|
@ -193,17 +193,15 @@ constexpr float normalizeBend(float bendValue)
|
|||
return clamp(bendValue, -8191.0f, 8191.0f) / 8191.0f;
|
||||
}
|
||||
|
||||
namespace literals
|
||||
{
|
||||
inline float operator ""_norm(unsigned long long int value)
|
||||
{
|
||||
if (value > 127)
|
||||
value = 127;
|
||||
namespace literals {
|
||||
inline float operator""_norm(unsigned long long int value)
|
||||
{
|
||||
if (value > 127)
|
||||
value = 127;
|
||||
|
||||
return normalize7Bits(value);
|
||||
return normalize7Bits(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convert a note in string to its equivalent midi note number
|
||||
|
|
@ -275,7 +273,6 @@ bool findDefine(absl::string_view line, absl::string_view& variable, absl::strin
|
|||
*/
|
||||
bool findInclude(absl::string_view line, std::string& path);
|
||||
|
||||
|
||||
/**
|
||||
* @brief multiply a value by a factor, in cents. To be used for pitch variations.
|
||||
*
|
||||
|
|
@ -284,20 +281,19 @@ bool findInclude(absl::string_view line, std::string& path);
|
|||
*/
|
||||
inline CXX14_CONSTEXPR float multiplyByCentsModifier(int modifier, float base)
|
||||
{
|
||||
return base * centsFactor(modifier);
|
||||
return base * centsFactor(modifier);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
template <class T>
|
||||
inline CXX14_CONSTEXPR float gainModifier(T modifier, float value)
|
||||
{
|
||||
return value * modifier;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Compute a crossfade in value with respect to a crossfade range (note, velocity, cc, ...)
|
||||
*/
|
||||
template<class T, class U>
|
||||
template <class T, class U>
|
||||
float crossfadeIn(const sfz::Range<T>& crossfadeRange, U value, SfzCrossfadeCurve curve)
|
||||
{
|
||||
if (value < crossfadeRange.getStart())
|
||||
|
|
@ -318,11 +314,10 @@ float crossfadeIn(const sfz::Range<T>& crossfadeRange, U value, SfzCrossfadeCurv
|
|||
return 1.0f;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Compute a crossfade out value with respect to a crossfade range (note, velocity, cc, ...)
|
||||
*/
|
||||
template<class T, class U>
|
||||
template <class T, class U>
|
||||
float crossfadeOut(const sfz::Range<T>& crossfadeRange, U value, SfzCrossfadeCurve curve)
|
||||
{
|
||||
if (value > crossfadeRange.getEnd())
|
||||
|
|
@ -343,7 +338,7 @@ float crossfadeOut(const sfz::Range<T>& crossfadeRange, U value, SfzCrossfadeCur
|
|||
return 1.0f;
|
||||
}
|
||||
|
||||
template<class F>
|
||||
template <class F>
|
||||
void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda)
|
||||
{
|
||||
ASSERT(events.size() > 0);
|
||||
|
|
@ -355,16 +350,16 @@ void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& l
|
|||
|
||||
auto lastValue = lambda(events[0].value);
|
||||
auto lastDelay = events[0].delay;
|
||||
for (unsigned i = 1; i < events.size() && lastDelay < maxDelay; ++ i) {
|
||||
for (unsigned i = 1; i < events.size() && lastDelay < maxDelay; ++i) {
|
||||
const auto length = min(events[i].delay, maxDelay) - lastDelay;
|
||||
const auto step = (lambda(events[i].value) - lastValue)/ length;
|
||||
const auto step = (lambda(events[i].value) - lastValue) / length;
|
||||
lastValue = linearRamp<float>(envelope.subspan(lastDelay, length), lastValue, step);
|
||||
lastDelay += length;
|
||||
}
|
||||
fill<float>(envelope.subspan(lastDelay), lastValue);
|
||||
}
|
||||
|
||||
template<class F>
|
||||
template <class F>
|
||||
void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda, float step)
|
||||
{
|
||||
ASSERT(events.size() > 0);
|
||||
|
|
@ -381,7 +376,7 @@ void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& l
|
|||
|
||||
auto lastValue = quantize(lambda(events[0].value));
|
||||
auto lastDelay = events[0].delay;
|
||||
for (unsigned i = 1; i < events.size() && lastDelay < maxDelay; ++ i) {
|
||||
for (unsigned i = 1; i < events.size() && lastDelay < maxDelay; ++i) {
|
||||
const auto nextValue = quantize(lambda(events[i].value));
|
||||
const auto difference = std::abs(nextValue - lastValue);
|
||||
const auto length = min(events[i].delay, maxDelay) - lastDelay;
|
||||
|
|
@ -404,7 +399,7 @@ void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& l
|
|||
fill<float>(envelope.subspan(lastDelay), lastValue);
|
||||
}
|
||||
|
||||
template<class F>
|
||||
template <class F>
|
||||
void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda)
|
||||
{
|
||||
ASSERT(events.size() > 0);
|
||||
|
|
@ -416,7 +411,7 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelop
|
|||
|
||||
auto lastValue = lambda(events[0].value);
|
||||
auto lastDelay = events[0].delay;
|
||||
for (unsigned i = 1; i < events.size() && lastDelay < maxDelay; ++ i) {
|
||||
for (unsigned i = 1; i < events.size() && lastDelay < maxDelay; ++i) {
|
||||
const auto length = min(events[i].delay, maxDelay) - lastDelay;
|
||||
const auto nextValue = lambda(events[i].value);
|
||||
const auto step = std::exp((std::log(nextValue) - std::log(lastValue)) / length);
|
||||
|
|
@ -427,7 +422,7 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelop
|
|||
fill<float>(envelope.subspan(lastDelay), lastValue);
|
||||
}
|
||||
|
||||
template<class F>
|
||||
template <class F>
|
||||
void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda, float step)
|
||||
{
|
||||
ASSERT(events.size() > 0);
|
||||
|
|
@ -445,12 +440,12 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelop
|
|||
// log q log q
|
||||
// and log(b)\log(q) is between 0 and 1.
|
||||
auto quantize = [logStep](float value) -> float {
|
||||
return std::exp(logStep * std::round(std::log(value)/logStep));
|
||||
return std::exp(logStep * std::round(std::log(value) / logStep));
|
||||
};
|
||||
|
||||
auto lastValue = quantize(lambda(events[0].value));
|
||||
auto lastDelay = events[0].delay;
|
||||
for (unsigned i = 1; i < events.size() && lastDelay < maxDelay; ++ i) {
|
||||
for (unsigned i = 1; i < events.size() && lastDelay < maxDelay; ++i) {
|
||||
const auto length = min(events[i].delay, maxDelay) - lastDelay;
|
||||
const auto nextValue = quantize(lambda(events[i].value));
|
||||
const auto difference = nextValue > lastValue ? nextValue / lastValue : lastValue / nextValue;
|
||||
|
|
|
|||
|
|
@ -705,16 +705,16 @@ void sfz::Synth::noteOnDispatch(int delay, int noteNumber, float velocity) noexc
|
|||
if (voice->getTriggerNumber() == noteNumber && voice->getTriggerType() == Voice::TriggerType::NoteOn) {
|
||||
activeNotes += 1;
|
||||
switch (region->selfMask) {
|
||||
case SfzSelfMask::mask:
|
||||
if (voice->getTriggerValue() < velocity) {
|
||||
if (!selfMaskCandidate || selfMaskCandidate->getTriggerValue() > voice->getTriggerValue())
|
||||
selfMaskCandidate = voice.get();
|
||||
}
|
||||
break;
|
||||
case SfzSelfMask::dontMask:
|
||||
if (!selfMaskCandidate || selfMaskCandidate->getSourcePosition() < voice->getSourcePosition())
|
||||
case SfzSelfMask::mask:
|
||||
if (voice->getTriggerValue() < velocity) {
|
||||
if (!selfMaskCandidate || selfMaskCandidate->getTriggerValue() > voice->getTriggerValue())
|
||||
selfMaskCandidate = voice.get();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SfzSelfMask::dontMask:
|
||||
if (!selfMaskCandidate || selfMaskCandidate->getSourcePosition() < voice->getSourcePosition())
|
||||
selfMaskCandidate = voice.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -410,11 +410,11 @@ void sfz::Voice::filterStageMono(AudioSpan<float> buffer) noexcept
|
|||
const auto leftBuffer = buffer.getSpan(0);
|
||||
const float* inputChannel[1] { leftBuffer.data() };
|
||||
float* outputChannel[1] { leftBuffer.data() };
|
||||
for (auto& filter: filters) {
|
||||
for (auto& filter : filters) {
|
||||
filter->process(inputChannel, outputChannel, numSamples);
|
||||
}
|
||||
|
||||
for (auto& eq: equalizers) {
|
||||
for (auto& eq : equalizers) {
|
||||
eq->process(inputChannel, outputChannel, numSamples);
|
||||
}
|
||||
}
|
||||
|
|
@ -429,11 +429,11 @@ void sfz::Voice::filterStageStereo(AudioSpan<float> buffer) noexcept
|
|||
const float* inputChannels[2] { leftBuffer.data(), rightBuffer.data() };
|
||||
float* outputChannels[2] { leftBuffer.data(), rightBuffer.data() };
|
||||
|
||||
for (auto& filter: filters) {
|
||||
for (auto& filter : filters) {
|
||||
filter->process(inputChannels, outputChannels, numSamples);
|
||||
}
|
||||
|
||||
for (auto& eq: equalizers) {
|
||||
for (auto& eq : equalizers) {
|
||||
eq->process(inputChannels, outputChannels, numSamples);
|
||||
}
|
||||
}
|
||||
|
|
@ -462,7 +462,7 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
|
|||
fill<float>(*jumps, pitchRatio * speedRatio);
|
||||
|
||||
const auto events = resources.midiState.getPitchEvents();
|
||||
const auto bendLambda = [this](float bend){
|
||||
const auto bendLambda = [this](float bend) {
|
||||
const auto bendInCents = bend > 0.0f ? bend * static_cast<float>(region->bendUp) : -bend * static_cast<float>(region->bendDown);
|
||||
return centsFactor(bendInCents);
|
||||
};
|
||||
|
|
@ -545,7 +545,6 @@ void sfz::Voice::fillWithGenerator(AudioSpan<float> buffer) noexcept
|
|||
const auto leftSpan = buffer.getSpan(0);
|
||||
const auto rightSpan = buffer.getSpan(1);
|
||||
|
||||
|
||||
if (region->sample == "*noise") {
|
||||
absl::c_generate(leftSpan, [&](){ return noiseDist(Random::randomGenerator); });
|
||||
absl::c_generate(rightSpan, [&](){ return noiseDist(Random::randomGenerator); });
|
||||
|
|
@ -560,7 +559,7 @@ void sfz::Voice::fillWithGenerator(AudioSpan<float> buffer) noexcept
|
|||
fill<float>(*frequencies, pitchRatio * keycenterFrequency);
|
||||
|
||||
const auto events = resources.midiState.getPitchEvents();
|
||||
const auto bendLambda = [this](float bend){
|
||||
const auto bendLambda = [this](float bend) {
|
||||
const auto bendInCents = bend > 0.0f ? bend * static_cast<float>(region->bendUp) : -bend * static_cast<float>(region->bendDown);
|
||||
return centsFactor(bendInCents);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@ TEST_CASE("[EGDescription] Attack range")
|
|||
eg.attack = 1;
|
||||
eg.vel2attack = -1.27f;
|
||||
eg.ccAttack = { 63, 1.27f };
|
||||
REQUIRE( eg.getAttack(state, 0_norm) == 1.0f );
|
||||
REQUIRE( eg.getAttack(state, 127_norm) == 0.0f );
|
||||
REQUIRE(eg.getAttack(state, 0_norm) == 1.0f);
|
||||
REQUIRE(eg.getAttack(state, 127_norm) == 0.0f);
|
||||
state.ccEvent(0, 63, 127_norm);
|
||||
REQUIRE( eg.getAttack(state, 127_norm) == 1.0f );
|
||||
REQUIRE( eg.getAttack(state, 0_norm) == 2.27f );
|
||||
REQUIRE(eg.getAttack(state, 127_norm) == 1.0f);
|
||||
REQUIRE(eg.getAttack(state, 0_norm) == 2.27f);
|
||||
eg.ccAttack = { 63, 127.0f };
|
||||
REQUIRE( eg.getAttack(state, 0_norm) == 100.0f );
|
||||
REQUIRE(eg.getAttack(state, 0_norm) == 100.0f);
|
||||
}
|
||||
|
||||
TEST_CASE("[EGDescription] Delay range")
|
||||
|
|
@ -34,13 +34,13 @@ TEST_CASE("[EGDescription] Delay range")
|
|||
eg.delay = 1;
|
||||
eg.vel2delay = -1.27f;
|
||||
eg.ccDelay = { 63, 1.27f };
|
||||
REQUIRE( eg.getDelay(state, 0_norm) == 1.0f );
|
||||
REQUIRE( eg.getDelay(state, 127_norm) == 0.0f );
|
||||
REQUIRE(eg.getDelay(state, 0_norm) == 1.0f);
|
||||
REQUIRE(eg.getDelay(state, 127_norm) == 0.0f);
|
||||
state.ccEvent(0, 63, 127_norm);
|
||||
REQUIRE( eg.getDelay(state, 127_norm) == 1.0f );
|
||||
REQUIRE( eg.getDelay(state, 0_norm) == 2.27f );
|
||||
REQUIRE(eg.getDelay(state, 127_norm) == 1.0f);
|
||||
REQUIRE(eg.getDelay(state, 0_norm) == 2.27f);
|
||||
eg.ccDelay = { 63, 127.0f };
|
||||
REQUIRE( eg.getDelay(state, 0_norm) == 100.0f );
|
||||
REQUIRE(eg.getDelay(state, 0_norm) == 100.0f);
|
||||
}
|
||||
|
||||
TEST_CASE("[EGDescription] Decay range")
|
||||
|
|
@ -50,13 +50,13 @@ TEST_CASE("[EGDescription] Decay range")
|
|||
eg.decay = 1.0f;
|
||||
eg.vel2decay = -1.27f;
|
||||
eg.ccDecay = { 63, 1.27f };
|
||||
REQUIRE( eg.getDecay(state, 0_norm) == 1.0f );
|
||||
REQUIRE( eg.getDecay(state, 127_norm) == 0.0f );
|
||||
REQUIRE(eg.getDecay(state, 0_norm) == 1.0f);
|
||||
REQUIRE(eg.getDecay(state, 127_norm) == 0.0f);
|
||||
state.ccEvent(0, 63, 127_norm);
|
||||
REQUIRE( eg.getDecay(state, 127_norm) == 1.0f );
|
||||
REQUIRE( eg.getDecay(state, 0_norm) == 2.27f );
|
||||
REQUIRE(eg.getDecay(state, 127_norm) == 1.0f);
|
||||
REQUIRE(eg.getDecay(state, 0_norm) == 2.27f);
|
||||
eg.ccDecay = { 63, 127.0f };
|
||||
REQUIRE( eg.getDecay(state, 0_norm) == 100.0f );
|
||||
REQUIRE(eg.getDecay(state, 0_norm) == 100.0f);
|
||||
}
|
||||
|
||||
TEST_CASE("[EGDescription] Release range")
|
||||
|
|
@ -66,13 +66,13 @@ TEST_CASE("[EGDescription] Release range")
|
|||
eg.release = 1;
|
||||
eg.vel2release = -1.27f;
|
||||
eg.ccRelease = { 63, 1.27f };
|
||||
REQUIRE( eg.getRelease(state, 0_norm) == 1.0f );
|
||||
REQUIRE( eg.getRelease(state, 127_norm) == 0.0f );
|
||||
REQUIRE(eg.getRelease(state, 0_norm) == 1.0f);
|
||||
REQUIRE(eg.getRelease(state, 127_norm) == 0.0f);
|
||||
state.ccEvent(0, 63, 127_norm);
|
||||
REQUIRE( eg.getRelease(state, 127_norm) == 1.0f );
|
||||
REQUIRE( eg.getRelease(state, 0_norm) == 2.27f );
|
||||
REQUIRE(eg.getRelease(state, 127_norm) == 1.0f);
|
||||
REQUIRE(eg.getRelease(state, 0_norm) == 2.27f);
|
||||
eg.ccRelease = { 63, 127.0f };
|
||||
REQUIRE( eg.getRelease(state, 0_norm) == 100.0f );
|
||||
REQUIRE(eg.getRelease(state, 0_norm) == 100.0f);
|
||||
}
|
||||
|
||||
TEST_CASE("[EGDescription] Hold range")
|
||||
|
|
@ -82,13 +82,13 @@ TEST_CASE("[EGDescription] Hold range")
|
|||
eg.hold = 1;
|
||||
eg.vel2hold = -1.27f;
|
||||
eg.ccHold = { 63, 1.27f };
|
||||
REQUIRE( eg.getHold(state, 0_norm) == 1.0f );
|
||||
REQUIRE( eg.getHold(state, 127_norm) == 0.0f );
|
||||
REQUIRE(eg.getHold(state, 0_norm) == 1.0f);
|
||||
REQUIRE(eg.getHold(state, 127_norm) == 0.0f);
|
||||
state.ccEvent(0, 63, 127_norm);
|
||||
REQUIRE( eg.getHold(state, 127_norm) == 1.0f );
|
||||
REQUIRE( eg.getHold(state, 0_norm) == 2.27f );
|
||||
REQUIRE(eg.getHold(state, 127_norm) == 1.0f);
|
||||
REQUIRE(eg.getHold(state, 0_norm) == 2.27f);
|
||||
eg.ccHold = { 63, 127.0f };
|
||||
REQUIRE( eg.getHold(state, 0_norm) == 100.0f );
|
||||
REQUIRE(eg.getHold(state, 0_norm) == 100.0f);
|
||||
}
|
||||
|
||||
TEST_CASE("[EGDescription] Sustain level")
|
||||
|
|
@ -98,12 +98,12 @@ TEST_CASE("[EGDescription] Sustain level")
|
|||
eg.sustain = 50;
|
||||
eg.vel2sustain = -100;
|
||||
eg.ccSustain = { 63, 100.0f };
|
||||
REQUIRE( eg.getSustain(state, 0_norm) == 50.0f );
|
||||
REQUIRE( eg.getSustain(state, 127_norm) == 0.0f );
|
||||
REQUIRE(eg.getSustain(state, 0_norm) == 50.0f);
|
||||
REQUIRE(eg.getSustain(state, 127_norm) == 0.0f);
|
||||
state.ccEvent(0, 63, 127_norm);
|
||||
REQUIRE( eg.getSustain(state, 127_norm) == 50.0f );
|
||||
REQUIRE(eg.getSustain(state, 127_norm) == 50.0f);
|
||||
eg.ccSustain = { 63, 200.0f };
|
||||
REQUIRE( eg.getSustain(state, 0_norm) == 100.0f );
|
||||
REQUIRE(eg.getSustain(state, 0_norm) == 100.0f);
|
||||
}
|
||||
|
||||
TEST_CASE("[EGDescription] Start level")
|
||||
|
|
@ -112,10 +112,10 @@ TEST_CASE("[EGDescription] Start level")
|
|||
sfz::MidiState state;
|
||||
eg.start = 0;
|
||||
eg.ccStart = { 63, 127.0f };
|
||||
REQUIRE( eg.getStart(state, 0_norm) == 0.0f );
|
||||
REQUIRE( eg.getStart(state, 127_norm) == 0.0f );
|
||||
REQUIRE(eg.getStart(state, 0_norm) == 0.0f);
|
||||
REQUIRE(eg.getStart(state, 127_norm) == 0.0f);
|
||||
state.ccEvent(0, 63, 127_norm);
|
||||
REQUIRE( eg.getStart(state, 0_norm) == 100.0f );
|
||||
REQUIRE(eg.getStart(state, 0_norm) == 100.0f);
|
||||
eg.ccStart = { 63, -127.0f };
|
||||
REQUIRE( eg.getStart(state, 0_norm) == 0.0f );
|
||||
REQUIRE(eg.getStart(state, 0_norm) == 0.0f);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,14 +29,14 @@ inline bool approxEqual(absl::Span<const Type> lhs, absl::Span<const Type> rhs,
|
|||
return true;
|
||||
}
|
||||
|
||||
const auto idModifier = [] (float x) { return x; };
|
||||
const auto twiceModifier = [] (float x) { return 2 * x; };
|
||||
const auto expModifier = [] (float x) { return std::exp(x); };
|
||||
const auto idModifier = [](float x) { return x; };
|
||||
const auto twiceModifier = [](float x) { return 2 * x; };
|
||||
const auto expModifier = [](float x) { return std::exp(x); };
|
||||
|
||||
TEST_CASE("[Envelopes] Empty")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f}
|
||||
{ 0, 0.0f }
|
||||
};
|
||||
std::array<float, 5> output;
|
||||
std::array<float, 5> expected { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
|
@ -54,8 +54,8 @@ TEST_CASE("[Envelopes] Empty")
|
|||
TEST_CASE("[Envelopes] Linear basic")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{4, 1.0f}
|
||||
{ 0, 0.0f },
|
||||
{ 4, 1.0f }
|
||||
};
|
||||
std::array<float, 9> output;
|
||||
std::array<float, 9> expected { 0.0f, 0.25f, 0.5f, 0.75f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
|
|
@ -66,9 +66,9 @@ TEST_CASE("[Envelopes] Linear basic")
|
|||
TEST_CASE("[LinearEnvelope] 2 events, close")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{4, 1.0f},
|
||||
{5, 2.0f}
|
||||
{ 0, 0.0f },
|
||||
{ 4, 1.0f },
|
||||
{ 5, 2.0f }
|
||||
};
|
||||
std::array<float, 9> output;
|
||||
std::array<float, 9> expected { 0.0f, 0.25f, 0.5f, 0.75f, 1.0f, 2.0f, 2.0f, 2.0f, 2.0f };
|
||||
|
|
@ -76,13 +76,12 @@ TEST_CASE("[LinearEnvelope] 2 events, close")
|
|||
REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("[LinearEnvelope] 2 events, far")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{2, 1.0f},
|
||||
{6, 2.0f}
|
||||
{ 0, 0.0f },
|
||||
{ 2, 1.0f },
|
||||
{ 6, 2.0f }
|
||||
};
|
||||
std::array<float, 9> output;
|
||||
std::array<float, 9> expected { 0.0f, 0.5f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f, 2.0f, 2.0f };
|
||||
|
|
@ -93,10 +92,10 @@ TEST_CASE("[LinearEnvelope] 2 events, far")
|
|||
TEST_CASE("[LinearEnvelope] 3 events, out of block")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{2, 1.0f},
|
||||
{6, 2.0f},
|
||||
{10, 3.0f}
|
||||
{ 0, 0.0f },
|
||||
{ 2, 1.0f },
|
||||
{ 6, 2.0f },
|
||||
{ 10, 3.0f }
|
||||
};
|
||||
std::array<float, 9> output;
|
||||
std::array<float, 9> expected { 0.0f, 0.5f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f, 2.5f, 3.0f };
|
||||
|
|
@ -107,9 +106,9 @@ TEST_CASE("[LinearEnvelope] 3 events, out of block")
|
|||
TEST_CASE("[LinearEnvelope] 2 events, function")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{2, 1.0f},
|
||||
{6, 2.0f}
|
||||
{ 0, 0.0f },
|
||||
{ 2, 1.0f },
|
||||
{ 6, 2.0f }
|
||||
};
|
||||
std::array<float, 9> output;
|
||||
std::array<float, 9> expected { 0.0f, 1.0f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 4.0f, 4.0f };
|
||||
|
|
@ -120,9 +119,9 @@ TEST_CASE("[LinearEnvelope] 2 events, function")
|
|||
TEST_CASE("[LinearEnvelope] Get quantized")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{2, 1.0f},
|
||||
{6, 2.0f}
|
||||
{ 0, 0.0f },
|
||||
{ 2, 1.0f },
|
||||
{ 6, 2.0f }
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f };
|
||||
|
|
@ -133,9 +132,9 @@ TEST_CASE("[LinearEnvelope] Get quantized")
|
|||
TEST_CASE("[LinearEnvelope] Get quantized with unquantized targets")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{2, 1.1f},
|
||||
{6, 1.9f}
|
||||
{ 0, 0.0f },
|
||||
{ 2, 1.1f },
|
||||
{ 6, 1.9f }
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f };
|
||||
|
|
@ -146,9 +145,9 @@ TEST_CASE("[LinearEnvelope] Get quantized with unquantized targets")
|
|||
TEST_CASE("[LinearEnvelope] Get quantized with 2 steps")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{2, 1.0f},
|
||||
{6, 3.0f}
|
||||
{ 0, 0.0f },
|
||||
{ 2, 1.0f },
|
||||
{ 6, 3.0f }
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.0f, 0.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f };
|
||||
|
|
@ -159,10 +158,10 @@ TEST_CASE("[LinearEnvelope] Get quantized with 2 steps")
|
|||
TEST_CASE("[LinearEnvelope] Get quantized with 2 steps and an unquantized out of block step")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 0.0f},
|
||||
{2, 1.0f},
|
||||
{6, 3.0f},
|
||||
{10, 4.2f},
|
||||
{ 0, 0.0f },
|
||||
{ 2, 1.0f },
|
||||
{ 6, 3.0f },
|
||||
{ 10, 4.2f },
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 0.0f, 0.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 4.0f };
|
||||
|
|
@ -174,9 +173,9 @@ TEST_CASE("[LinearEnvelope] Get quantized with 2 steps and an unquantized out of
|
|||
TEST_CASE("[LinearEnvelope] Going down quantized with 2 steps")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 3.0f},
|
||||
{2, 2.0f},
|
||||
{6, 0.0f}
|
||||
{ 0, 3.0f },
|
||||
{ 2, 2.0f },
|
||||
{ 6, 0.0f }
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 3.0f, 3.0f, 2.0f, 2.0f, 1.0f, 1.0f, 0.0f, 0.0f };
|
||||
|
|
@ -187,8 +186,8 @@ TEST_CASE("[LinearEnvelope] Going down quantized with 2 steps")
|
|||
TEST_CASE("[MultiplicativeEnvelope] Basic event")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 1.0f},
|
||||
{4, 2.0f}
|
||||
{ 0, 1.0f },
|
||||
{ 4, 2.0f }
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 1.0f, 1.1892f, 1.4142f, 1.68176f, 2.0f, 2.0f, 2.0f, 2.0f };
|
||||
|
|
@ -199,12 +198,12 @@ TEST_CASE("[MultiplicativeEnvelope] Basic event")
|
|||
TEST_CASE("[MultiplicativeEnvelope] 2 events")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 1.0f},
|
||||
{4, 2.0f},
|
||||
{5, 4.0f}
|
||||
{ 0, 1.0f },
|
||||
{ 4, 2.0f },
|
||||
{ 5, 4.0f }
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 1.0f, 1.1892f, 1.4142f, 1.68176f, 2.0f, 4.0f, 4.0f, 4.0f};
|
||||
std::array<float, 8> expected { 1.0f, 1.1892f, 1.4142f, 1.68176f, 2.0f, 4.0f, 4.0f, 4.0f };
|
||||
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier);
|
||||
REQUIRE(approxEqual<float>(output, expected));
|
||||
}
|
||||
|
|
@ -212,12 +211,12 @@ TEST_CASE("[MultiplicativeEnvelope] 2 events")
|
|||
TEST_CASE("[MultiplicativeEnvelope] 2 events, far")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 1.0f},
|
||||
{2, 2.0f},
|
||||
{6, 4.0f}
|
||||
{ 0, 1.0f },
|
||||
{ 2, 2.0f },
|
||||
{ 6, 4.0f }
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 1.0f, 1.4142f, 2.0f, 2.37841f, 2.82843f, 3.36358f, 4.0f, 4.0f};
|
||||
std::array<float, 8> expected { 1.0f, 1.4142f, 2.0f, 2.37841f, 2.82843f, 3.36358f, 4.0f, 4.0f };
|
||||
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier);
|
||||
REQUIRE(approxEqual<float>(output, expected));
|
||||
}
|
||||
|
|
@ -225,12 +224,12 @@ TEST_CASE("[MultiplicativeEnvelope] 2 events, far")
|
|||
TEST_CASE("[MultiplicativeEnvelope] Get quantized with 2 steps")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 1.0f},
|
||||
{2, 2.0f},
|
||||
{6, 4.0f}
|
||||
{ 0, 1.0f },
|
||||
{ 2, 2.0f },
|
||||
{ 6, 4.0f }
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 2.0f, 4.0f, 4.0f};
|
||||
std::array<float, 8> expected { 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 2.0f, 4.0f, 4.0f };
|
||||
multiplicativeEnvelope(events, absl::MakeSpan(output), idModifier, 2.0f);
|
||||
REQUIRE(output == expected);
|
||||
}
|
||||
|
|
@ -238,10 +237,10 @@ TEST_CASE("[MultiplicativeEnvelope] Get quantized with 2 steps")
|
|||
TEST_CASE("[MultiplicativeEnvelope] Get quantized with an unquantized out of range step")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 1.0f},
|
||||
{2, 2.0f},
|
||||
{6, 4.0f},
|
||||
{10, 8.2f}
|
||||
{ 0, 1.0f },
|
||||
{ 2, 2.0f },
|
||||
{ 6, 4.0f },
|
||||
{ 10, 8.2f }
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 2.0f, 4.0f, 8.0f };
|
||||
|
|
@ -252,9 +251,9 @@ TEST_CASE("[MultiplicativeEnvelope] Get quantized with an unquantized out of ran
|
|||
TEST_CASE("[MultiplicativeEnvelope] Going down quantized with 2 steps")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 4.0f},
|
||||
{2, 2.0f},
|
||||
{6, 0.5f}
|
||||
{ 0, 4.0f },
|
||||
{ 2, 2.0f },
|
||||
{ 6, 0.5f }
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 4.0f, 4.0f, 2.0f, 2.0f, 1.0f, 1.0f, 0.5f, 0.5f };
|
||||
|
|
@ -265,9 +264,9 @@ TEST_CASE("[MultiplicativeEnvelope] Going down quantized with 2 steps")
|
|||
TEST_CASE("[MultiplicativeEnvelope] Get quantized with unclean events")
|
||||
{
|
||||
sfz::EventVector events {
|
||||
{0, 1.0f},
|
||||
{2, 1.2f},
|
||||
{6, 2.5f}
|
||||
{ 0, 1.0f },
|
||||
{ 2, 1.2f },
|
||||
{ 6, 2.5f }
|
||||
};
|
||||
std::array<float, 8> output;
|
||||
std::array<float, 8> expected { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f };
|
||||
|
|
|
|||
|
|
@ -309,9 +309,9 @@ TEST_CASE("[Files] wrong (overlapping) replacement for defines")
|
|||
REQUIRE( synth.getRegionView(0)->keyRange.getEnd() == 52 );
|
||||
REQUIRE( synth.getRegionView(1)->keyRange.getStart() == 57 );
|
||||
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.empty());
|
||||
REQUIRE(synth.getRegionView(2)->amplitudeCC.contains(10));
|
||||
REQUIRE(synth.getRegionView(2)->amplitudeCC.getWithDefault(10) == 0.34f);
|
||||
}
|
||||
|
||||
TEST_CASE("[Files] Specific bug: relative path with backslashes")
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ TEST_CASE("[MidiState] Initial values")
|
|||
{
|
||||
sfz::MidiState state;
|
||||
for (unsigned cc = 0; cc < sfz::config::numCCs; cc++)
|
||||
REQUIRE( state.getCCValue(cc) == 0_norm );
|
||||
REQUIRE(state.getCCValue(cc) == 0_norm);
|
||||
REQUIRE( state.getPitchBend() == 0 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1434,13 +1434,13 @@ TEST_CASE("[Region] Parsing opcodes")
|
|||
|
||||
SECTION("amplitude")
|
||||
{
|
||||
REQUIRE(region.amplitude == 1.0_a );
|
||||
REQUIRE(region.amplitude == 1.0_a);
|
||||
region.parseOpcode({ "amplitude", "40" });
|
||||
REQUIRE(region.amplitude == 0.4_a );
|
||||
REQUIRE(region.amplitude == 0.4_a);
|
||||
region.parseOpcode({ "amplitude", "-40" });
|
||||
REQUIRE(region.amplitude == 0_a );
|
||||
REQUIRE(region.amplitude == 0_a);
|
||||
region.parseOpcode({ "amplitude", "140" });
|
||||
REQUIRE(region.amplitude == 1.0_a );
|
||||
REQUIRE(region.amplitude == 1.0_a);
|
||||
}
|
||||
|
||||
SECTION("amplitude_cc")
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ TEST_CASE("[Region] Crossfade in on key")
|
|||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfin_lokey", "1" });
|
||||
region.parseOpcode({ "xfin_hikey", "3" });
|
||||
REQUIRE( region.getNoteGain(2, 127_norm) == 0.70711_a );
|
||||
REQUIRE( region.getNoteGain(1, 127_norm) == 0.0_a );
|
||||
REQUIRE( region.getNoteGain(3, 127_norm) == 1.0_a );
|
||||
REQUIRE(region.getNoteGain(2, 127_norm) == 0.70711_a);
|
||||
REQUIRE(region.getNoteGain(1, 127_norm) == 0.0_a);
|
||||
REQUIRE(region.getNoteGain(3, 127_norm) == 1.0_a);
|
||||
}
|
||||
|
||||
TEST_CASE("[Region] Crossfade in on key - 2")
|
||||
|
|
@ -33,12 +33,12 @@ TEST_CASE("[Region] Crossfade in on key - 2")
|
|||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfin_lokey", "1" });
|
||||
region.parseOpcode({ "xfin_hikey", "5" });
|
||||
REQUIRE( region.getNoteGain(1, 127_norm) == 0.0_a );
|
||||
REQUIRE( region.getNoteGain(2, 127_norm) == 0.5_a );
|
||||
REQUIRE( region.getNoteGain(3, 127_norm) == 0.70711_a );
|
||||
REQUIRE( region.getNoteGain(4, 127_norm) == 0.86603_a );
|
||||
REQUIRE( region.getNoteGain(5, 127_norm) == 1.0_a );
|
||||
REQUIRE( region.getNoteGain(6, 127_norm) == 1.0_a );
|
||||
REQUIRE(region.getNoteGain(1, 127_norm) == 0.0_a);
|
||||
REQUIRE(region.getNoteGain(2, 127_norm) == 0.5_a);
|
||||
REQUIRE(region.getNoteGain(3, 127_norm) == 0.70711_a);
|
||||
REQUIRE(region.getNoteGain(4, 127_norm) == 0.86603_a);
|
||||
REQUIRE(region.getNoteGain(5, 127_norm) == 1.0_a);
|
||||
REQUIRE(region.getNoteGain(6, 127_norm) == 1.0_a);
|
||||
}
|
||||
|
||||
TEST_CASE("[Region] Crossfade in on key - gain")
|
||||
|
|
@ -49,11 +49,11 @@ TEST_CASE("[Region] Crossfade in on key - gain")
|
|||
region.parseOpcode({ "xfin_lokey", "1" });
|
||||
region.parseOpcode({ "xfin_hikey", "5" });
|
||||
region.parseOpcode({ "xf_keycurve", "gain" });
|
||||
REQUIRE( region.getNoteGain(1, 127_norm) == 0.0_a );
|
||||
REQUIRE( region.getNoteGain(2, 127_norm) == 0.25_a );
|
||||
REQUIRE( region.getNoteGain(3, 127_norm) == 0.5_a );
|
||||
REQUIRE( region.getNoteGain(4, 127_norm) == 0.75_a );
|
||||
REQUIRE( region.getNoteGain(5, 127_norm) == 1.0_a );
|
||||
REQUIRE(region.getNoteGain(1, 127_norm) == 0.0_a);
|
||||
REQUIRE(region.getNoteGain(2, 127_norm) == 0.25_a);
|
||||
REQUIRE(region.getNoteGain(3, 127_norm) == 0.5_a);
|
||||
REQUIRE(region.getNoteGain(4, 127_norm) == 0.75_a);
|
||||
REQUIRE(region.getNoteGain(5, 127_norm) == 1.0_a);
|
||||
}
|
||||
|
||||
TEST_CASE("[Region] Crossfade out on key")
|
||||
|
|
@ -63,13 +63,13 @@ TEST_CASE("[Region] Crossfade out on key")
|
|||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfout_lokey", "51" });
|
||||
region.parseOpcode({ "xfout_hikey", "55" });
|
||||
REQUIRE( region.getNoteGain(50, 127_norm) == 1.0_a );
|
||||
REQUIRE( region.getNoteGain(51, 127_norm) == 1.0_a );
|
||||
REQUIRE( region.getNoteGain(52, 127_norm) == 0.86603_a );
|
||||
REQUIRE( region.getNoteGain(53, 127_norm) == 0.70711_a );
|
||||
REQUIRE( region.getNoteGain(54, 127_norm) == 0.5_a );
|
||||
REQUIRE( region.getNoteGain(55, 127_norm) == 0.0_a );
|
||||
REQUIRE( region.getNoteGain(56, 127_norm) == 0.0_a );
|
||||
REQUIRE(region.getNoteGain(50, 127_norm) == 1.0_a);
|
||||
REQUIRE(region.getNoteGain(51, 127_norm) == 1.0_a);
|
||||
REQUIRE(region.getNoteGain(52, 127_norm) == 0.86603_a);
|
||||
REQUIRE(region.getNoteGain(53, 127_norm) == 0.70711_a);
|
||||
REQUIRE(region.getNoteGain(54, 127_norm) == 0.5_a);
|
||||
REQUIRE(region.getNoteGain(55, 127_norm) == 0.0_a);
|
||||
REQUIRE(region.getNoteGain(56, 127_norm) == 0.0_a);
|
||||
}
|
||||
|
||||
TEST_CASE("[Region] Crossfade out on key - gain")
|
||||
|
|
@ -80,13 +80,13 @@ TEST_CASE("[Region] Crossfade out on key - gain")
|
|||
region.parseOpcode({ "xfout_lokey", "51" });
|
||||
region.parseOpcode({ "xfout_hikey", "55" });
|
||||
region.parseOpcode({ "xf_keycurve", "gain" });
|
||||
REQUIRE( region.getNoteGain(50, 127_norm) == 1.0_a );
|
||||
REQUIRE( region.getNoteGain(51, 127_norm) == 1.0_a );
|
||||
REQUIRE( region.getNoteGain(52, 127_norm) == 0.75_a );
|
||||
REQUIRE( region.getNoteGain(53, 127_norm) == 0.5_a );
|
||||
REQUIRE( region.getNoteGain(54, 127_norm) == 0.25_a );
|
||||
REQUIRE( region.getNoteGain(55, 127_norm) == 0.0_a );
|
||||
REQUIRE( region.getNoteGain(56, 127_norm) == 0.0_a );
|
||||
REQUIRE(region.getNoteGain(50, 127_norm) == 1.0_a);
|
||||
REQUIRE(region.getNoteGain(51, 127_norm) == 1.0_a);
|
||||
REQUIRE(region.getNoteGain(52, 127_norm) == 0.75_a);
|
||||
REQUIRE(region.getNoteGain(53, 127_norm) == 0.5_a);
|
||||
REQUIRE(region.getNoteGain(54, 127_norm) == 0.25_a);
|
||||
REQUIRE(region.getNoteGain(55, 127_norm) == 0.0_a);
|
||||
REQUIRE(region.getNoteGain(56, 127_norm) == 0.0_a);
|
||||
}
|
||||
|
||||
TEST_CASE("[Region] Crossfade in on velocity")
|
||||
|
|
@ -97,13 +97,13 @@ TEST_CASE("[Region] Crossfade in on velocity")
|
|||
region.parseOpcode({ "xfin_lovel", "20" });
|
||||
region.parseOpcode({ "xfin_hivel", "24" });
|
||||
region.parseOpcode({ "amp_veltrack", "0" });
|
||||
REQUIRE( region.getNoteGain(1, 19_norm) == 0.0_a );
|
||||
REQUIRE( region.getNoteGain(1, 20_norm) == 0.0_a );
|
||||
REQUIRE( region.getNoteGain(2, 21_norm) == 0.5_a );
|
||||
REQUIRE( region.getNoteGain(3, 22_norm) == 0.70711_a );
|
||||
REQUIRE( region.getNoteGain(4, 23_norm) == 0.86603_a );
|
||||
REQUIRE( region.getNoteGain(5, 24_norm) == 1.0_a );
|
||||
REQUIRE( region.getNoteGain(6, 25_norm) == 1.0_a );
|
||||
REQUIRE(region.getNoteGain(1, 19_norm) == 0.0_a);
|
||||
REQUIRE(region.getNoteGain(1, 20_norm) == 0.0_a);
|
||||
REQUIRE(region.getNoteGain(2, 21_norm) == 0.5_a);
|
||||
REQUIRE(region.getNoteGain(3, 22_norm) == 0.70711_a);
|
||||
REQUIRE(region.getNoteGain(4, 23_norm) == 0.86603_a);
|
||||
REQUIRE(region.getNoteGain(5, 24_norm) == 1.0_a);
|
||||
REQUIRE(region.getNoteGain(6, 25_norm) == 1.0_a);
|
||||
}
|
||||
|
||||
TEST_CASE("[Region] Crossfade in on vel - gain")
|
||||
|
|
@ -115,13 +115,13 @@ TEST_CASE("[Region] Crossfade in on vel - gain")
|
|||
region.parseOpcode({ "xfin_hivel", "24" });
|
||||
region.parseOpcode({ "xf_velcurve", "gain" });
|
||||
region.parseOpcode({ "amp_veltrack", "0" });
|
||||
REQUIRE( region.getNoteGain(1, 19_norm) == 0.0_a );
|
||||
REQUIRE( region.getNoteGain(1, 20_norm) == 0.0_a );
|
||||
REQUIRE( region.getNoteGain(2, 21_norm) == 0.25_a );
|
||||
REQUIRE( region.getNoteGain(3, 22_norm) == 0.5_a );
|
||||
REQUIRE( region.getNoteGain(4, 23_norm) == 0.75_a );
|
||||
REQUIRE( region.getNoteGain(5, 24_norm) == 1.0_a );
|
||||
REQUIRE( region.getNoteGain(5, 25_norm) == 1.0_a );
|
||||
REQUIRE(region.getNoteGain(1, 19_norm) == 0.0_a);
|
||||
REQUIRE(region.getNoteGain(1, 20_norm) == 0.0_a);
|
||||
REQUIRE(region.getNoteGain(2, 21_norm) == 0.25_a);
|
||||
REQUIRE(region.getNoteGain(3, 22_norm) == 0.5_a);
|
||||
REQUIRE(region.getNoteGain(4, 23_norm) == 0.75_a);
|
||||
REQUIRE(region.getNoteGain(5, 24_norm) == 1.0_a);
|
||||
REQUIRE(region.getNoteGain(5, 25_norm) == 1.0_a);
|
||||
}
|
||||
|
||||
TEST_CASE("[Region] Crossfade out on vel")
|
||||
|
|
@ -132,13 +132,13 @@ TEST_CASE("[Region] Crossfade out on vel")
|
|||
region.parseOpcode({ "xfout_lovel", "51" });
|
||||
region.parseOpcode({ "xfout_hivel", "55" });
|
||||
region.parseOpcode({ "amp_veltrack", "0" });
|
||||
REQUIRE( region.getNoteGain(5, 50_norm) == 1.0_a );
|
||||
REQUIRE( region.getNoteGain(5, 51_norm) == 1.0_a );
|
||||
REQUIRE( region.getNoteGain(5, 52_norm) == 0.86603_a );
|
||||
REQUIRE( region.getNoteGain(5, 53_norm) == 0.70711_a );
|
||||
REQUIRE( region.getNoteGain(5, 54_norm) == 0.5_a );
|
||||
REQUIRE( region.getNoteGain(5, 55_norm) == 0.0_a );
|
||||
REQUIRE( region.getNoteGain(5, 56_norm) == 0.0_a );
|
||||
REQUIRE(region.getNoteGain(5, 50_norm) == 1.0_a);
|
||||
REQUIRE(region.getNoteGain(5, 51_norm) == 1.0_a);
|
||||
REQUIRE(region.getNoteGain(5, 52_norm) == 0.86603_a);
|
||||
REQUIRE(region.getNoteGain(5, 53_norm) == 0.70711_a);
|
||||
REQUIRE(region.getNoteGain(5, 54_norm) == 0.5_a);
|
||||
REQUIRE(region.getNoteGain(5, 55_norm) == 0.0_a);
|
||||
REQUIRE(region.getNoteGain(5, 56_norm) == 0.0_a);
|
||||
}
|
||||
|
||||
TEST_CASE("[Region] Crossfade out on vel - gain")
|
||||
|
|
@ -150,13 +150,13 @@ TEST_CASE("[Region] Crossfade out on vel - gain")
|
|||
region.parseOpcode({ "xfout_hivel", "55" });
|
||||
region.parseOpcode({ "xf_velcurve", "gain" });
|
||||
region.parseOpcode({ "amp_veltrack", "0" });
|
||||
REQUIRE( region.getNoteGain(56, 50_norm) == 1.0_a );
|
||||
REQUIRE( region.getNoteGain(56, 51_norm) == 1.0_a );
|
||||
REQUIRE( region.getNoteGain(56, 52_norm) == 0.75_a );
|
||||
REQUIRE( region.getNoteGain(56, 53_norm) == 0.5_a );
|
||||
REQUIRE( region.getNoteGain(56, 54_norm) == 0.25_a );
|
||||
REQUIRE( region.getNoteGain(56, 55_norm) == 0.0_a );
|
||||
REQUIRE( region.getNoteGain(56, 56_norm) == 0.0_a );
|
||||
REQUIRE(region.getNoteGain(56, 50_norm) == 1.0_a);
|
||||
REQUIRE(region.getNoteGain(56, 51_norm) == 1.0_a);
|
||||
REQUIRE(region.getNoteGain(56, 52_norm) == 0.75_a);
|
||||
REQUIRE(region.getNoteGain(56, 53_norm) == 0.5_a);
|
||||
REQUIRE(region.getNoteGain(56, 54_norm) == 0.25_a);
|
||||
REQUIRE(region.getNoteGain(56, 55_norm) == 0.0_a);
|
||||
REQUIRE(region.getNoteGain(56, 56_norm) == 0.0_a);
|
||||
}
|
||||
|
||||
TEST_CASE("[Region] Crossfade in on CC")
|
||||
|
|
@ -167,13 +167,20 @@ TEST_CASE("[Region] Crossfade in on CC")
|
|||
region.parseOpcode({ "xfin_locc24", "20" });
|
||||
region.parseOpcode({ "xfin_hicc24", "24" });
|
||||
region.parseOpcode({ "amp_veltrack", "0" });
|
||||
midiState.ccEvent(0, 24, 19_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||
midiState.ccEvent(0, 24, 20_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||
midiState.ccEvent(0, 24, 21_norm); REQUIRE( region.getCrossfadeGain() == 0.5_a );
|
||||
midiState.ccEvent(0, 24, 22_norm); REQUIRE( region.getCrossfadeGain() == 0.70711_a );
|
||||
midiState.ccEvent(0, 24, 23_norm); REQUIRE( region.getCrossfadeGain() == 0.86603_a );
|
||||
midiState.ccEvent(0, 24, 24_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||
midiState.ccEvent(0, 24, 25_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||
midiState.ccEvent(0, 24, 19_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.0_a);
|
||||
midiState.ccEvent(0, 24, 20_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.0_a);
|
||||
midiState.ccEvent(0, 24, 21_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.5_a);
|
||||
midiState.ccEvent(0, 24, 22_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.70711_a);
|
||||
midiState.ccEvent(0, 24, 23_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.86603_a);
|
||||
midiState.ccEvent(0, 24, 24_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 1.0_a);
|
||||
midiState.ccEvent(0, 24, 25_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 1.0_a);
|
||||
}
|
||||
|
||||
TEST_CASE("[Region] Crossfade in on CC - gain")
|
||||
|
|
@ -185,13 +192,20 @@ TEST_CASE("[Region] Crossfade in on CC - gain")
|
|||
region.parseOpcode({ "xfin_hicc24", "24" });
|
||||
region.parseOpcode({ "amp_veltrack", "0" });
|
||||
region.parseOpcode({ "xf_cccurve", "gain" });
|
||||
midiState.ccEvent(0, 24, 19_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||
midiState.ccEvent(0, 24, 20_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||
midiState.ccEvent(0, 24, 21_norm); REQUIRE( region.getCrossfadeGain() == 0.25_a );
|
||||
midiState.ccEvent(0, 24, 22_norm); REQUIRE( region.getCrossfadeGain() == 0.5_a );
|
||||
midiState.ccEvent(0, 24, 23_norm); REQUIRE( region.getCrossfadeGain() == 0.75_a );
|
||||
midiState.ccEvent(0, 24, 24_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||
midiState.ccEvent(0, 24, 25_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||
midiState.ccEvent(0, 24, 19_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.0_a);
|
||||
midiState.ccEvent(0, 24, 20_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.0_a);
|
||||
midiState.ccEvent(0, 24, 21_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.25_a);
|
||||
midiState.ccEvent(0, 24, 22_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.5_a);
|
||||
midiState.ccEvent(0, 24, 23_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.75_a);
|
||||
midiState.ccEvent(0, 24, 24_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 1.0_a);
|
||||
midiState.ccEvent(0, 24, 25_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 1.0_a);
|
||||
}
|
||||
TEST_CASE("[Region] Crossfade out on CC")
|
||||
{
|
||||
|
|
@ -201,13 +215,20 @@ TEST_CASE("[Region] Crossfade out on CC")
|
|||
region.parseOpcode({ "xfout_locc24", "20" });
|
||||
region.parseOpcode({ "xfout_hicc24", "24" });
|
||||
region.parseOpcode({ "amp_veltrack", "0" });
|
||||
midiState.ccEvent(0, 24, 19_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||
midiState.ccEvent(0, 24, 20_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||
midiState.ccEvent(0, 24, 21_norm); REQUIRE( region.getCrossfadeGain() == 0.86603_a );
|
||||
midiState.ccEvent(0, 24, 22_norm); REQUIRE( region.getCrossfadeGain() == 0.70711_a );
|
||||
midiState.ccEvent(0, 24, 23_norm); REQUIRE( region.getCrossfadeGain() == 0.5_a );
|
||||
midiState.ccEvent(0, 24, 24_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||
midiState.ccEvent(0, 24, 25_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||
midiState.ccEvent(0, 24, 19_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 1.0_a);
|
||||
midiState.ccEvent(0, 24, 20_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 1.0_a);
|
||||
midiState.ccEvent(0, 24, 21_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.86603_a);
|
||||
midiState.ccEvent(0, 24, 22_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.70711_a);
|
||||
midiState.ccEvent(0, 24, 23_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.5_a);
|
||||
midiState.ccEvent(0, 24, 24_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.0_a);
|
||||
midiState.ccEvent(0, 24, 25_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.0_a);
|
||||
}
|
||||
|
||||
TEST_CASE("[Region] Crossfade out on CC - gain")
|
||||
|
|
@ -219,13 +240,20 @@ TEST_CASE("[Region] Crossfade out on CC - gain")
|
|||
region.parseOpcode({ "xfout_hicc24", "24" });
|
||||
region.parseOpcode({ "amp_veltrack", "0" });
|
||||
region.parseOpcode({ "xf_cccurve", "gain" });
|
||||
midiState.ccEvent(0, 24, 19_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||
midiState.ccEvent(0, 24, 20_norm); REQUIRE( region.getCrossfadeGain() == 1.0_a );
|
||||
midiState.ccEvent(0, 24, 21_norm); REQUIRE( region.getCrossfadeGain() == 0.75_a );
|
||||
midiState.ccEvent(0, 24, 22_norm); REQUIRE( region.getCrossfadeGain() == 0.5_a );
|
||||
midiState.ccEvent(0, 24, 23_norm); REQUIRE( region.getCrossfadeGain() == 0.25_a );
|
||||
midiState.ccEvent(0, 24, 24_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||
midiState.ccEvent(0, 24, 25_norm); REQUIRE( region.getCrossfadeGain() == 0.0_a );
|
||||
midiState.ccEvent(0, 24, 19_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 1.0_a);
|
||||
midiState.ccEvent(0, 24, 20_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 1.0_a);
|
||||
midiState.ccEvent(0, 24, 21_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.75_a);
|
||||
midiState.ccEvent(0, 24, 22_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.5_a);
|
||||
midiState.ccEvent(0, 24, 23_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.25_a);
|
||||
midiState.ccEvent(0, 24, 24_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.0_a);
|
||||
midiState.ccEvent(0, 24, 25_norm);
|
||||
REQUIRE(region.getCrossfadeGain() == 0.0_a);
|
||||
}
|
||||
|
||||
TEST_CASE("[Region] Velocity bug for extreme values - veltrack at 0")
|
||||
|
|
@ -234,8 +262,8 @@ TEST_CASE("[Region] Velocity bug for extreme values - veltrack at 0")
|
|||
sfz::Region region { midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "amp_veltrack", "0" });
|
||||
REQUIRE( region.getNoteGain(64, 127_norm) == 1.0_a );
|
||||
REQUIRE( region.getNoteGain(64, 0_norm) == 1.0_a );
|
||||
REQUIRE(region.getNoteGain(64, 127_norm) == 1.0_a);
|
||||
REQUIRE(region.getNoteGain(64, 0_norm) == 1.0_a);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -245,8 +273,8 @@ TEST_CASE("[Region] Velocity bug for extreme values - positive veltrack")
|
|||
sfz::Region region { midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "amp_veltrack", "100" });
|
||||
REQUIRE( region.getNoteGain(64, 127_norm) == 1.0_a );
|
||||
REQUIRE( region.getNoteGain(64, 0_norm) == Approx(0.0).margin(0.0001) );
|
||||
REQUIRE(region.getNoteGain(64, 127_norm) == 1.0_a);
|
||||
REQUIRE(region.getNoteGain(64, 0_norm) == Approx(0.0).margin(0.0001));
|
||||
}
|
||||
|
||||
TEST_CASE("[Region] Velocity bug for extreme values - negative veltrack")
|
||||
|
|
@ -255,8 +283,8 @@ TEST_CASE("[Region] Velocity bug for extreme values - negative veltrack")
|
|||
sfz::Region region { midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "amp_veltrack", "-100" });
|
||||
REQUIRE( region.getNoteGain(64, 127_norm) == Approx(0.0).margin(0.0001) );
|
||||
REQUIRE( region.getNoteGain(64, 0_norm) == 1.0_a );
|
||||
REQUIRE(region.getNoteGain(64, 127_norm) == Approx(0.0).margin(0.0001));
|
||||
REQUIRE(region.getNoteGain(64, 0_norm) == 1.0_a);
|
||||
}
|
||||
|
||||
TEST_CASE("[Region] rt_decay")
|
||||
|
|
|
|||
|
|
@ -141,9 +141,9 @@ TEST_CASE("[Synth] Reset all controllers")
|
|||
{
|
||||
sfz::Synth synth;
|
||||
synth.cc(0, 12, 64);
|
||||
REQUIRE( synth.getMidiState().getCCValue(12) == 64_norm );
|
||||
REQUIRE(synth.getMidiState().getCCValue(12) == 64_norm);
|
||||
synth.cc(0, 121, 64);
|
||||
REQUIRE( synth.getMidiState().getCCValue(12) == 0_norm );
|
||||
REQUIRE(synth.getMidiState().getCCValue(12) == 0_norm);
|
||||
}
|
||||
|
||||
TEST_CASE("[Synth] Releasing before the EG started smoothing (initial delay) kills the voice")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue