Numbering of regions and voices
This commit is contained in:
parent
d9e49f7dc5
commit
f0f4c34ad8
8 changed files with 51 additions and 30 deletions
|
|
@ -35,8 +35,8 @@ namespace sfz {
|
|||
*
|
||||
*/
|
||||
struct Region {
|
||||
Region(const MidiState& midiState, absl::string_view defaultPath = "")
|
||||
: midiState(midiState), defaultPath(std::move(defaultPath))
|
||||
Region(int regionNumber, const MidiState& midiState, absl::string_view defaultPath = "")
|
||||
: regionNumber(regionNumber), midiState(midiState), defaultPath(std::move(defaultPath))
|
||||
{
|
||||
ccSwitched.set();
|
||||
|
||||
|
|
@ -46,6 +46,14 @@ struct Region {
|
|||
Region(const Region&) = default;
|
||||
~Region() = default;
|
||||
|
||||
/**
|
||||
* @brief Get the number which identifies this region, also its index
|
||||
*/
|
||||
int getIdNumber() const noexcept
|
||||
{
|
||||
return regionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Triggers on release?
|
||||
*
|
||||
|
|
@ -238,6 +246,8 @@ struct Region {
|
|||
*/
|
||||
float getGainToEffectBus(unsigned number) const noexcept;
|
||||
|
||||
const int regionNumber {};
|
||||
|
||||
// Sound source: sample playback
|
||||
FileId sampleId {}; // Sample
|
||||
int sampleQuality { Default::sampleQuality };
|
||||
|
|
|
|||
|
|
@ -95,7 +95,8 @@ void sfz::Synth::onParseWarning(const SourceRange& range, const std::string& mes
|
|||
|
||||
void sfz::Synth::buildRegion(const std::vector<Opcode>& regionOpcodes)
|
||||
{
|
||||
auto lastRegion = absl::make_unique<Region>(resources.midiState, defaultPath);
|
||||
int regionNumber = static_cast<int>(regions.size());
|
||||
auto lastRegion = absl::make_unique<Region>(regionNumber, resources.midiState, defaultPath);
|
||||
|
||||
auto parseOpcodes = [&](const std::vector<Opcode>& opcodes) {
|
||||
for (auto& opcode : opcodes) {
|
||||
|
|
@ -1094,7 +1095,7 @@ void sfz::Synth::resetVoices(int numVoices)
|
|||
voices.reserve(numVoices);
|
||||
|
||||
for (int i = 0; i < numVoices; ++i)
|
||||
voices.push_back(absl::make_unique<Voice>(resources));
|
||||
voices.push_back(absl::make_unique<Voice>(i, resources));
|
||||
|
||||
voiceViewArray.clear();
|
||||
voiceViewArray.reserve(numVoices);
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@
|
|||
#include "Interpolators.h"
|
||||
#include "absl/algorithm/container.h"
|
||||
|
||||
sfz::Voice::Voice(sfz::Resources& resources)
|
||||
: resources(resources)
|
||||
sfz::Voice::Voice(int voiceNumber, sfz::Resources& resources)
|
||||
: voiceNumber(voiceNumber), resources(resources)
|
||||
{
|
||||
filters.reserve(config::filtersPerVoice);
|
||||
equalizers.reserve(config::eqsPerVoice);
|
||||
|
|
|
|||
|
|
@ -32,14 +32,22 @@ public:
|
|||
/**
|
||||
* @brief Construct a new voice with the midistate singleton
|
||||
*
|
||||
* @param voiceNumber
|
||||
* @param midiState
|
||||
*/
|
||||
Voice(Resources& resources);
|
||||
Voice(int voiceNumber, Resources& resources);
|
||||
enum class TriggerType {
|
||||
NoteOn,
|
||||
NoteOff,
|
||||
CC
|
||||
};
|
||||
/**
|
||||
* @brief Get the number which identifies this voice, its index
|
||||
*/
|
||||
int getIdNumber() const noexcept
|
||||
{
|
||||
return voiceNumber;
|
||||
}
|
||||
/**
|
||||
* @brief Change the sample rate of the voice. This is used to compute all
|
||||
* pitch related transformations so it needs to be propagated from the synth
|
||||
|
|
@ -270,6 +278,8 @@ private:
|
|||
void setupOscillatorUnison();
|
||||
void updateChannelPowers(AudioSpan<float> buffer);
|
||||
|
||||
const int voiceNumber {};
|
||||
|
||||
Region* region { nullptr };
|
||||
|
||||
enum class State {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ using namespace sfz::literals;
|
|||
TEST_CASE("Region activation", "Region tests")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
SECTION("Basic state")
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ using namespace sfz::literals;
|
|||
TEST_CASE("[Region] Parsing opcodes")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
|
||||
SECTION("sample")
|
||||
{
|
||||
|
|
@ -1672,7 +1672,7 @@ TEST_CASE("[Region] Parsing opcodes")
|
|||
TEST_CASE("[Region] Non-conforming floating point values in integer opcodes")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "offset", "2014.5" });
|
||||
REQUIRE(region.offset == 2014);
|
||||
region.parseOpcode({ "pitch_keytrack", "-2.1" });
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ using namespace sfz::literals;
|
|||
TEST_CASE("Basic triggers", "Region triggers")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
SECTION("key")
|
||||
|
|
@ -130,7 +130,7 @@ TEST_CASE("Basic triggers", "Region triggers")
|
|||
TEST_CASE("Legato triggers", "Region triggers")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
SECTION("First note playing")
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ constexpr int numRandomTests { 64 };
|
|||
TEST_CASE("[Region] Crossfade in on key")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfin_lokey", "1" });
|
||||
region.parseOpcode({ "xfin_hikey", "3" });
|
||||
|
|
@ -29,7 +29,7 @@ TEST_CASE("[Region] Crossfade in on key")
|
|||
TEST_CASE("[Region] Crossfade in on key - 2")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfin_lokey", "1" });
|
||||
region.parseOpcode({ "xfin_hikey", "5" });
|
||||
|
|
@ -44,7 +44,7 @@ TEST_CASE("[Region] Crossfade in on key - 2")
|
|||
TEST_CASE("[Region] Crossfade in on key - gain")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfin_lokey", "1" });
|
||||
region.parseOpcode({ "xfin_hikey", "5" });
|
||||
|
|
@ -59,7 +59,7 @@ TEST_CASE("[Region] Crossfade in on key - gain")
|
|||
TEST_CASE("[Region] Crossfade out on key")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfout_lokey", "51" });
|
||||
region.parseOpcode({ "xfout_hikey", "55" });
|
||||
|
|
@ -75,7 +75,7 @@ TEST_CASE("[Region] Crossfade out on key")
|
|||
TEST_CASE("[Region] Crossfade out on key - gain")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfout_lokey", "51" });
|
||||
region.parseOpcode({ "xfout_hikey", "55" });
|
||||
|
|
@ -92,7 +92,7 @@ TEST_CASE("[Region] Crossfade out on key - gain")
|
|||
TEST_CASE("[Region] Crossfade in on velocity")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfin_lovel", "20" });
|
||||
region.parseOpcode({ "xfin_hivel", "24" });
|
||||
|
|
@ -109,7 +109,7 @@ TEST_CASE("[Region] Crossfade in on velocity")
|
|||
TEST_CASE("[Region] Crossfade in on vel - gain")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfin_lovel", "20" });
|
||||
region.parseOpcode({ "xfin_hivel", "24" });
|
||||
|
|
@ -127,7 +127,7 @@ TEST_CASE("[Region] Crossfade in on vel - gain")
|
|||
TEST_CASE("[Region] Crossfade out on vel")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfout_lovel", "51" });
|
||||
region.parseOpcode({ "xfout_hivel", "55" });
|
||||
|
|
@ -144,7 +144,7 @@ TEST_CASE("[Region] Crossfade out on vel")
|
|||
TEST_CASE("[Region] Crossfade out on vel - gain")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfout_lovel", "51" });
|
||||
region.parseOpcode({ "xfout_hivel", "55" });
|
||||
|
|
@ -162,7 +162,7 @@ TEST_CASE("[Region] Crossfade out on vel - gain")
|
|||
TEST_CASE("[Region] Crossfade in on CC")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfin_locc24", "20" });
|
||||
region.parseOpcode({ "xfin_hicc24", "24" });
|
||||
|
|
@ -186,7 +186,7 @@ TEST_CASE("[Region] Crossfade in on CC")
|
|||
TEST_CASE("[Region] Crossfade in on CC - gain")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfin_locc24", "20" });
|
||||
region.parseOpcode({ "xfin_hicc24", "24" });
|
||||
|
|
@ -210,7 +210,7 @@ TEST_CASE("[Region] Crossfade in on CC - gain")
|
|||
TEST_CASE("[Region] Crossfade out on CC")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfout_locc24", "20" });
|
||||
region.parseOpcode({ "xfout_hicc24", "24" });
|
||||
|
|
@ -234,7 +234,7 @@ TEST_CASE("[Region] Crossfade out on CC")
|
|||
TEST_CASE("[Region] Crossfade out on CC - gain")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "xfout_locc24", "20" });
|
||||
region.parseOpcode({ "xfout_hicc24", "24" });
|
||||
|
|
@ -259,7 +259,7 @@ TEST_CASE("[Region] Crossfade out on CC - gain")
|
|||
TEST_CASE("[Region] Velocity bug for extreme values - veltrack at 0")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "amp_veltrack", "0" });
|
||||
REQUIRE(region.getNoteGain(64, 127_norm) == 1.0_a);
|
||||
|
|
@ -270,7 +270,7 @@ TEST_CASE("[Region] Velocity bug for extreme values - veltrack at 0")
|
|||
TEST_CASE("[Region] Velocity bug for extreme values - positive veltrack")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "amp_veltrack", "100" });
|
||||
REQUIRE(region.getNoteGain(64, 127_norm) == 1.0_a);
|
||||
|
|
@ -280,7 +280,7 @@ TEST_CASE("[Region] Velocity bug for extreme values - positive veltrack")
|
|||
TEST_CASE("[Region] Velocity bug for extreme values - negative veltrack")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "amp_veltrack", "-100" });
|
||||
REQUIRE(region.getNoteGain(64, 127_norm) == Approx(0.0).margin(0.0001));
|
||||
|
|
@ -291,7 +291,7 @@ TEST_CASE("[Region] rt_decay")
|
|||
{
|
||||
sfz::MidiState midiState;
|
||||
midiState.setSampleRate(1000);
|
||||
sfz::Region region { midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "trigger", "release" });
|
||||
region.parseOpcode({ "rt_decay", "10" });
|
||||
|
|
@ -311,7 +311,7 @@ TEST_CASE("[Region] rt_decay")
|
|||
TEST_CASE("[Region] Base delay")
|
||||
{
|
||||
sfz::MidiState midiState;
|
||||
sfz::Region region{ midiState };
|
||||
sfz::Region region { 0, midiState };
|
||||
region.parseOpcode({ "sample", "*sine" });
|
||||
region.parseOpcode({ "delay", "10" });
|
||||
REQUIRE( region.getDelay() == 10.0f );
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue