Numbering of regions and voices

This commit is contained in:
Jean Pierre Cimalando 2020-05-17 21:42:57 +02:00
parent d9e49f7dc5
commit f0f4c34ad8
8 changed files with 51 additions and 30 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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