sfizz/tests/DirectRegionT.cpp

130 lines
5.1 KiB
C++
Raw Permalink Normal View History

2020-11-08 23:59:28 +01:00
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "TestHelpers.h"
#include "sfizz/MidiState.h"
#include "sfizz/Region.h"
2021-03-25 21:46:21 +01:00
#include "sfizz/Layer.h"
2020-11-08 23:59:28 +01:00
#include "sfizz/SfzHelpers.h"
#include "sfizz/modulations/ModId.h"
#include "sfizz/modulations/ModKey.h"
#include "catch2/catch.hpp"
#include <stdexcept>
using namespace Catch::literals;
using namespace sfz::literals;
using namespace sfz;
TEST_CASE("[Direct Region Tests] amp_velcurve")
{
2021-03-25 21:46:21 +01:00
Region region { 0 };
2020-11-08 23:59:28 +01:00
region.parseOpcode({ "amp_velcurve_6", "0.4" });
REQUIRE(region.velocityPoints.back() == std::pair<uint8_t, float>(6, 0.4f));
region.parseOpcode({ "amp_velcurve_127", "-1.0" });
2021-03-19 17:51:45 +01:00
REQUIRE(region.velocityPoints.back() == std::pair<uint8_t, float>(127, -1.0f));
2020-11-08 23:59:28 +01:00
region.parseOpcode({ "amp_velcurve_008", "0.3" });
REQUIRE(region.velocityPoints.back() == std::pair<uint8_t, float>(8, 0.3f));
region.parseOpcode({ "amp_velcurve_064", "0.9" });
REQUIRE(region.velocityPoints.back() == std::pair<uint8_t, float>(64, 0.9f));
}
TEST_CASE("[Direct Region Tests] Release and release key")
{
MidiState midiState;
2021-03-25 21:46:21 +01:00
Region region { 0 };
2020-11-08 23:59:28 +01:00
region.parseOpcode({ "lokey", "63" });
region.parseOpcode({ "hikey", "65" });
region.parseOpcode({ "sample", "*sine" });
SECTION("Release key without sustain")
{
region.parseOpcode({ "trigger", "release_key" });
2021-03-30 17:49:17 +02:00
Layer layer { region, midiState };
2021-03-25 21:46:21 +01:00
layer.delayedSustainReleases_.reserve(config::delayedReleaseVoices);
2020-11-08 23:59:28 +01:00
midiState.ccEvent(0, 64, 0.0f);
layer.updateCCState(64, 0.0f);
2021-03-25 21:46:21 +01:00
REQUIRE( !layer.registerNoteOn(63, 0.5f, 0.0f) );
REQUIRE( layer.registerNoteOff(63, 0.5f, 0.0f) );
2020-11-08 23:59:28 +01:00
}
SECTION("Release key with sustain")
{
region.parseOpcode({ "trigger", "release_key" });
2021-03-30 17:49:17 +02:00
Layer layer { region, midiState };
2021-03-25 21:46:21 +01:00
layer.delayedSustainReleases_.reserve(config::delayedReleaseVoices);
2020-11-08 23:59:28 +01:00
midiState.ccEvent(0, 64, 1.0f);
layer.updateCCState(64, 1.0f);
2021-03-25 21:46:21 +01:00
REQUIRE( !layer.registerNoteOn(63, 0.5f, 0.0f) );
REQUIRE( layer.registerNoteOff(63, 0.5f, 0.0f) );
2020-11-08 23:59:28 +01:00
}
SECTION("Release without sustain")
{
region.parseOpcode({ "trigger", "release" });
2021-03-30 17:49:17 +02:00
Layer layer { region, midiState };
2021-03-25 21:46:21 +01:00
layer.delayedSustainReleases_.reserve(config::delayedReleaseVoices);
2020-11-08 23:59:28 +01:00
midiState.ccEvent(0, 64, 0.0f);
layer.updateCCState(64, 0.0f);
2021-03-25 21:46:21 +01:00
REQUIRE( !layer.registerNoteOn(63, 0.5f, 0.0f) );
REQUIRE( layer.registerNoteOff(63, 0.5f, 0.0f) );
2020-11-08 23:59:28 +01:00
}
SECTION("Release with sustain")
{
region.parseOpcode({ "trigger", "release" });
2021-03-30 17:49:17 +02:00
Layer layer { region, midiState };
2021-03-25 21:46:21 +01:00
layer.delayedSustainReleases_.reserve(config::delayedReleaseVoices);
2020-11-08 23:59:28 +01:00
midiState.ccEvent(0, 64, 1.0f);
layer.updateCCState(64, 1.0f);
2020-11-08 23:59:28 +01:00
midiState.noteOnEvent(0, 63, 0.5f);
2021-03-25 21:46:21 +01:00
REQUIRE( !layer.registerNoteOn(63, 0.5f, 0.0f) );
REQUIRE( !layer.registerNoteOff(63, 0.5f, 0.0f) );
REQUIRE( layer.delayedSustainReleases_.size() == 1 );
2020-11-08 23:59:28 +01:00
std::vector<std::pair<int, float>> expected = {
{ 63, 0.5f }
};
2021-03-25 21:46:21 +01:00
REQUIRE( layer.delayedSustainReleases_ == expected );
2020-11-08 23:59:28 +01:00
}
SECTION("Release with sustain and 2 notes")
{
region.parseOpcode({ "trigger", "release" });
2021-03-30 17:49:17 +02:00
Layer layer { region, midiState };
2021-03-25 21:46:21 +01:00
layer.delayedSustainReleases_.reserve(config::delayedReleaseVoices);
2020-11-08 23:59:28 +01:00
midiState.ccEvent(0, 64, 1.0f);
layer.updateCCState(64, 1.0f);
2020-11-08 23:59:28 +01:00
midiState.noteOnEvent(0, 63, 0.5f);
2021-03-25 21:46:21 +01:00
REQUIRE( !layer.registerNoteOn(63, 0.5f, 0.0f) );
2020-11-08 23:59:28 +01:00
midiState.noteOnEvent(0, 64, 0.6f);
2021-03-25 21:46:21 +01:00
REQUIRE( !layer.registerNoteOn(64, 0.6f, 0.0f) );
REQUIRE( !layer.registerNoteOff(63, 0.0f, 0.0f) );
REQUIRE( !layer.registerNoteOff(64, 0.2f, 0.0f) );
REQUIRE( layer.delayedSustainReleases_.size() == 2 );
2020-11-08 23:59:28 +01:00
std::vector<std::pair<int, float>> expected = {
{ 63, 0.5f },
{ 64, 0.6f }
};
2021-03-25 21:46:21 +01:00
REQUIRE( layer.delayedSustainReleases_ == expected );
2020-11-08 23:59:28 +01:00
}
SECTION("Release with sustain and 2 notes but 1 outside")
{
region.parseOpcode({ "trigger", "release" });
2021-03-30 17:49:17 +02:00
Layer layer { region, midiState };
2021-03-25 21:46:21 +01:00
layer.delayedSustainReleases_.reserve(config::delayedReleaseVoices);
2020-11-08 23:59:28 +01:00
midiState.ccEvent(0, 64, 1.0f);
layer.updateCCState(64, 1.0f);
2020-11-08 23:59:28 +01:00
midiState.noteOnEvent(0, 63, 0.5f);
2021-03-25 21:46:21 +01:00
REQUIRE( !layer.registerNoteOn(63, 0.5f, 0.0f) );
2020-11-08 23:59:28 +01:00
midiState.noteOnEvent(0, 66, 0.6f);
2021-03-25 21:46:21 +01:00
REQUIRE( !layer.registerNoteOn(66, 0.6f, 0.0f) );
REQUIRE( !layer.registerNoteOff(63, 0.0f, 0.0f) );
REQUIRE( !layer.registerNoteOff(66, 0.2f, 0.0f) );
REQUIRE( layer.delayedSustainReleases_.size() == 1 );
2020-11-08 23:59:28 +01:00
std::vector<std::pair<int, float>> expected = {
{ 63, 0.5f }
};
2021-03-25 21:46:21 +01:00
REQUIRE( layer.delayedSustainReleases_ == expected );
2020-11-08 23:59:28 +01:00
}
}