Formatting step

This commit is contained in:
Paul Fd 2020-03-31 10:46:12 +02:00
parent 7e8cdff407
commit 5088bed9b0
16 changed files with 323 additions and 294 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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