Allow EG reset to accept other parameters than ampeg

This commit is contained in:
Jean Pierre Cimalando 2020-03-20 13:03:26 +01:00 committed by Paul Fd
parent bf7d90f3d4
commit d6adebf8f4
5 changed files with 39 additions and 37 deletions

View file

@ -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<int>(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<int>(state.range(0)))
envelope.getBlock(absl::MakeSpan(output));

View file

@ -12,20 +12,20 @@
namespace sfz {
template <class Type>
void ADSREnvelope<Type>::reset(const Region& region, const MidiState& state, int delay, float velocity, float sampleRate) noexcept
void ADSREnvelope<Type>::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<int>(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<Type>::getBlock(absl::Span<Type> output) noexcept
}
}
}
template <class Type>
bool ADSREnvelope<Type>::isSmoothing() const noexcept
{

View file

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

View file

@ -101,7 +101,7 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value,
initialDelay = delay + static_cast<int>(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

View file

@ -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<float, 5> output;
std::array<float, 5> expected { 0.0f, 0.5f, 1.0f, 1.0f, 1.0f };
for (auto& out : output)
out = envelope.getNextValue();
REQUIRE(approxEqual<float>(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<float>(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<float, 5> output;
std::array<float, 5> expected { 0.0f, 0.33333f, 0.66667f, 1.0f, 1.0f };
for (auto& out : output)
out = envelope.getNextValue();
REQUIRE(approxEqual<float>(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<float>(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<float, 9> output;
std::array<float, 9> 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<float>(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<float, 11> output;
envelope.reset(region, state, 0, 0.0f, 100.0f);
std::array<float, 10> output;
envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f);
envelope.startRelease(4);
std::array<float, 11> 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<float>(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<float, 11> output;
envelope.reset(region, state, 0, 0.0f, 100.0f);
std::array<float, 11> 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<float, 10> output;
envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f);
std::array<float, 10> 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<float>(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<float>(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<float, 11> output;
envelope.reset(region, state, 0, 0.0f, 100.0f);
std::array<float, 11> 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<float, 10> output;
envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f);
std::array<float, 10> 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<float>(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<float>(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<float, 13> output;
envelope.reset(region, state, 0, 0.0f, 100.0f);
std::array<float, 13> 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<float, 12> output;
envelope.reset(region.amplitudeEG, region, state, 0, 0.0f, 100.0f);
std::array<float, 12> 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<float>(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<float>(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<float, 15> output;
std::array<float, 15> 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<float>(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<float, 15> output;
std::array<float, 15> 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<float>(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));