diff --git a/benchmarks/BM_ADSR.cpp b/benchmarks/BM_ADSR.cpp index 4b781070..e2d077c0 100644 --- a/benchmarks/BM_ADSR.cpp +++ b/benchmarks/BM_ADSR.cpp @@ -43,7 +43,7 @@ public: BENCHMARK_DEFINE_F(EnvelopeFixture, Scalar)(benchmark::State& state) { for (auto _ : state) { - envelope.reset(region, midiState, 0, 0, sampleRate); + envelope.reset(region.amplitudeEG, region, midiState, 0, 0, sampleRate); envelope.startRelease(releaseTime); for (int offset = 0; offset < envelopeSize; offset += static_cast(state.range(0))) for (auto& out: output) @@ -56,7 +56,7 @@ BENCHMARK_DEFINE_F(EnvelopeFixture, Scalar)(benchmark::State& state) BENCHMARK_DEFINE_F(EnvelopeFixture, Block)(benchmark::State& state) { for (auto _ : state) { - envelope.reset(region, midiState, 0, 0, sampleRate); + envelope.reset(region.amplitudeEG, region, midiState, 0, 0, sampleRate); envelope.startRelease(releaseTime); for (int offset = 0; offset < envelopeSize; offset += static_cast(state.range(0))) envelope.getBlock(absl::MakeSpan(output)); diff --git a/src/sfizz/ADSREnvelope.cpp b/src/sfizz/ADSREnvelope.cpp index 351b1267..c7f2952f 100644 --- a/src/sfizz/ADSREnvelope.cpp +++ b/src/sfizz/ADSREnvelope.cpp @@ -12,20 +12,20 @@ namespace sfz { template -void ADSREnvelope::reset(const Region& region, const MidiState& state, int delay, float velocity, float sampleRate) noexcept +void ADSREnvelope::reset(const EGDescription& desc, const Region& region, const MidiState& state, int delay, float velocity, float sampleRate) noexcept { auto secondsToSamples = [sampleRate](Type timeInSeconds) { return static_cast(timeInSeconds * sampleRate); }; - this->delay = delay + secondsToSamples(region.amplitudeEG.getDelay(state, velocity)); - this->attack = secondsToSamples(region.amplitudeEG.getAttack(state, velocity)); - this->decay = secondsToSamples(region.amplitudeEG.getDecay(state, velocity)); - this->release = secondsToSamples(region.amplitudeEG.getRelease(state, velocity)); - this->hold = secondsToSamples(region.amplitudeEG.getHold(state, velocity)); + this->delay = delay + secondsToSamples(desc.getDelay(state, velocity)); + this->attack = secondsToSamples(desc.getAttack(state, velocity)); + this->decay = secondsToSamples(desc.getDecay(state, velocity)); + this->release = secondsToSamples(desc.getRelease(state, velocity)); + this->hold = secondsToSamples(desc.getHold(state, velocity)); this->peak = 1.0; - this->sustain = normalizePercents(region.amplitudeEG.getSustain(state, velocity)); - this->start = this->peak * normalizePercents(region.amplitudeEG.getStart(state, velocity)); + this->sustain = normalizePercents(desc.getSustain(state, velocity)); + this->start = this->peak * normalizePercents(desc.getStart(state, velocity)); releaseDelay = 0; shouldRelease = false; @@ -204,6 +204,7 @@ void ADSREnvelope::getBlock(absl::Span output) noexcept } } } + template bool ADSREnvelope::isSmoothing() const noexcept { diff --git a/src/sfizz/ADSREnvelope.h b/src/sfizz/ADSREnvelope.h index 6a647d03..ce2b959d 100644 --- a/src/sfizz/ADSREnvelope.h +++ b/src/sfizz/ADSREnvelope.h @@ -24,12 +24,13 @@ public: * @brief Resets the ADSR envelope given a Region, the current midi state, and a delay and * trigger velocity * + * @param desc * @param region * @param state * @param delay * @param velocity */ - void reset(const Region& region, const MidiState& state, int delay, float velocity, float sampleRate) noexcept; + void reset(const EGDescription& desc, const Region& region, const MidiState& state, int delay, float velocity, float sampleRate) noexcept; /** * @brief Get the next value for the envelope * diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index 5da0f909..1bd5dbc5 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -101,7 +101,7 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value, initialDelay = delay + static_cast(region->getDelay() * sampleRate); baseFrequency = midiNoteFrequency(number); bendStepFactor = centsFactor(region->bendStep); - egEnvelope.reset(*region, resources.midiState, delay, value, sampleRate); + egEnvelope.reset(region->amplitudeEG, *region, resources.midiState, delay, value, sampleRate); } bool sfz::Voice::isFree() const noexcept diff --git a/tests/ADSREnvelopeT.cpp b/tests/ADSREnvelopeT.cpp index 0d344096..7def3ec9 100644 --- a/tests/ADSREnvelopeT.cpp +++ b/tests/ADSREnvelopeT.cpp @@ -49,14 +49,14 @@ TEST_CASE("[ADSREnvelope] Attack") sfz::Region region { state }; region.amplitudeEG.attack = 0.02f; - envelope.reset(region, state, 0, 0.0f, 100.0f); + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); std::array output; std::array expected { 0.0f, 0.5f, 1.0f, 1.0f, 1.0f }; for (auto& out : output) out = envelope.getNextValue(); REQUIRE(approxEqual(output, expected)); - envelope.reset(region, state, 0, 0.0f, 100.0f); + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); absl::c_fill(output, -1.0f); envelope.getBlock(absl::MakeSpan(output)); REQUIRE(approxEqual(output, expected)); @@ -69,14 +69,14 @@ TEST_CASE("[ADSREnvelope] Attack again") sfz::Region region { state }; region.amplitudeEG.attack = 0.03f; - envelope.reset(region, state, 0, 0.0f, 100.0f); + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); std::array output; std::array expected { 0.0f, 0.33333f, 0.66667f, 1.0f, 1.0f }; for (auto& out : output) out = envelope.getNextValue(); REQUIRE(approxEqual(output, expected)); - envelope.reset(region, state, 0, 0.0f, 100.0f); + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); absl::c_fill(output, -1.0f); envelope.getBlock(absl::MakeSpan(output)); REQUIRE(approxEqual(output, expected)); @@ -90,7 +90,7 @@ TEST_CASE("[ADSREnvelope] Release") region.amplitudeEG.attack = 0.02f; region.amplitudeEG.release = 0.04f; - envelope.reset(region, state, 0, 0.0f, 100.0f); + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); envelope.startRelease(2); std::array output; std::array expected { 0.0f, 0.5f, 1.0f, 0.08409f, 0.00707f, 0.000594604f, 0.00005f, 0.0f, 0.0f }; @@ -98,7 +98,7 @@ TEST_CASE("[ADSREnvelope] Release") out = envelope.getNextValue(); REQUIRE(approxEqual(output, expected)); - envelope.reset(region, state, 0, 0.0f, 100.0f); + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); envelope.startRelease(2); absl::c_fill(output, -1.0f); envelope.getBlock(absl::MakeSpan(output)); @@ -113,15 +113,15 @@ TEST_CASE("[ADSREnvelope] Delay") region.amplitudeEG.attack = 0.02f; region.amplitudeEG.release = 0.04f; region.amplitudeEG.delay = 0.02f; - std::array output; - envelope.reset(region, state, 0, 0.0f, 100.0f); + std::array output; + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); envelope.startRelease(4); std::array expected { 0.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.08409f, 0.00707f, 0.000594604f, 0.00005f, 0.0f, 0.0f }; for (auto& out : output) out = envelope.getNextValue(); REQUIRE(approxEqual(output, expected)); - envelope.reset(region, state, 0, 0.0f, 100.0f); + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); envelope.startRelease(4); absl::c_fill(output, -1.0f); envelope.getBlock(absl::MakeSpan(output)); @@ -137,14 +137,14 @@ TEST_CASE("[ADSREnvelope] Lower sustain") region.amplitudeEG.release = 0.04f; region.amplitudeEG.delay = 0.02f; region.amplitudeEG.sustain = 50.0f; - std::array output; - envelope.reset(region, state, 0, 0.0f, 100.0f); - std::array expected { 0.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f }; + std::array output; + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); + std::array expected { 0.0f, 0.0f, 0.5f, 1.0f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f }; for (auto& out : output) out = envelope.getNextValue(); REQUIRE(approxEqual(output, expected)); - envelope.reset(region, state, 0, 0.0f, 100.0f); + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); absl::c_fill(output, -1.0f); envelope.getBlock(absl::MakeSpan(output)); REQUIRE(approxEqual(output, expected)); @@ -160,14 +160,14 @@ TEST_CASE("[ADSREnvelope] Decay") region.amplitudeEG.delay = 0.02f; region.amplitudeEG.sustain = 50.0f; region.amplitudeEG.decay = 0.02f; - std::array output; - envelope.reset(region, state, 0, 0.0f, 100.0f); - std::array expected { 0.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.707107f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5 }; + std::array output; + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); + std::array expected { 0.0f, 0.0f, 0.5f, 1.0f, 0.707107f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5 }; for (auto& out : output) out = envelope.getNextValue(); REQUIRE(approxEqual(output, expected)); - envelope.reset(region, state, 0, 0.0f, 100.0f); + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); absl::c_fill(output, -1.0f); envelope.getBlock(absl::MakeSpan(output)); REQUIRE(approxEqual(output, expected)); @@ -184,14 +184,14 @@ TEST_CASE("[ADSREnvelope] Hold") region.amplitudeEG.sustain = 50.0f; region.amplitudeEG.decay = 0.02f; region.amplitudeEG.hold = 0.02f; - std::array output; - envelope.reset(region, state, 0, 0.0f, 100.0f); - std::array expected { 0.0f, 0.0f, 0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.707107f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f }; + std::array output; + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); + std::array expected { 0.0f, 0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.707107f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f }; for (auto& out : output) out = envelope.getNextValue(); REQUIRE(approxEqual(output, expected)); - envelope.reset(region, state, 0, 0.0f, 100.0f); + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); absl::c_fill(output, -1.0f); envelope.getBlock(absl::MakeSpan(output)); REQUIRE(approxEqual(output, expected)); @@ -208,7 +208,7 @@ TEST_CASE("[ADSREnvelope] Hold with release") region.amplitudeEG.sustain = 50.0f; region.amplitudeEG.decay = 0.02f; region.amplitudeEG.hold = 0.02f; - envelope.reset(region, state, 0, 0.0f, 100.0f); + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); envelope.startRelease(8); std::array output; std::array expected { 0.0f, 0.0f, 0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.707107f, 0.5f, 0.05f, 0.005f, 0.0005f, 0.00005f, 0.0f, 0.0f }; @@ -216,7 +216,7 @@ TEST_CASE("[ADSREnvelope] Hold with release") out = envelope.getNextValue(); REQUIRE(approxEqual(output, expected)); - envelope.reset(region, state, 0, 0.0f, 100.0f); + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); envelope.startRelease(8); absl::c_fill(output, -1.0f); envelope.getBlock(absl::MakeSpan(output)); @@ -234,14 +234,14 @@ TEST_CASE("[ADSREnvelope] Hold with release 2") region.amplitudeEG.sustain = 50.0f; region.amplitudeEG.decay = 0.02f; region.amplitudeEG.hold = 0.02f; - envelope.reset(region, state, 0, 0.0f, 100.0f); + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); envelope.startRelease(4); std::array output; std::array expected { 0.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.08409f, 0.00707f, 0.000594604f, 0.00005f, 0.0f, 0.0f, 0.0f, 0.0 }; for (auto& out : output) out = envelope.getNextValue(); REQUIRE(approxEqual(output, expected)); - envelope.reset(region, state, 0, 0.0f, 100.0f); + envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f); envelope.startRelease(4); absl::c_fill(output, -1.0f); envelope.getBlock(absl::MakeSpan(output));