Corrected the multiplicative envelope logic
The previous version alternatively cleared or ignored messages every other block
This commit is contained in:
parent
f34d96b46c
commit
6c2f5b5ecb
2 changed files with 31 additions and 9 deletions
|
|
@ -57,6 +57,8 @@ void EventEnvelope<Type>::setFunction(std::function<Type(Type)> function)
|
||||||
template <class Type>
|
template <class Type>
|
||||||
void EventEnvelope<Type>::registerEvent(int timestamp, Type inputValue)
|
void EventEnvelope<Type>::registerEvent(int timestamp, Type inputValue)
|
||||||
{
|
{
|
||||||
|
if (resetEvents)
|
||||||
|
clear();
|
||||||
|
|
||||||
if (static_cast<int>(events.size()) < maxCapacity)
|
if (static_cast<int>(events.size()) < maxCapacity)
|
||||||
events.emplace_back(timestamp, function(inputValue));
|
events.emplace_back(timestamp, function(inputValue));
|
||||||
|
|
@ -65,14 +67,14 @@ void EventEnvelope<Type>::registerEvent(int timestamp, Type inputValue)
|
||||||
template <class Type>
|
template <class Type>
|
||||||
void EventEnvelope<Type>::prepareEvents()
|
void EventEnvelope<Type>::prepareEvents()
|
||||||
{
|
{
|
||||||
if (resetEvents) {
|
if (resetEvents)
|
||||||
clear();
|
clear();
|
||||||
} else {
|
|
||||||
absl::c_sort(events, [](const auto& lhs, const auto& rhs) {
|
absl::c_sort(events, [](const auto& lhs, const auto& rhs) {
|
||||||
return lhs.first < rhs.first;
|
return lhs.first < rhs.first;
|
||||||
});
|
});
|
||||||
resetEvents = true;
|
|
||||||
}
|
resetEvents = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Type>
|
template <class Type>
|
||||||
|
|
@ -201,7 +203,8 @@ void MultiplicativeEnvelope<Type>::getBlock(absl::Span<Type> output)
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto step = std::exp((std::log(event.second) - std::log(currentValue)) / length);
|
const auto step = std::exp((std::log(event.second) - std::log(currentValue)) / length);
|
||||||
currentValue = multiplicativeRamp<Type>(output.subspan(index, length), currentValue, step);
|
multiplicativeRamp<Type>(output.subspan(index, length), currentValue, step);
|
||||||
|
currentValue = event.second;
|
||||||
index += length;
|
index += length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@
|
||||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "EventEnvelopes.h"
|
#include "EventEnvelopes.h"
|
||||||
|
#include "SfzHelpers.h"
|
||||||
|
#include "Buffer.h"
|
||||||
#include "catch2/catch.hpp"
|
#include "catch2/catch.hpp"
|
||||||
#include <absl/algorithm/container.h>
|
#include <absl/algorithm/container.h>
|
||||||
#include <absl/types/span.h>
|
#include <absl/types/span.h>
|
||||||
|
|
@ -385,3 +387,20 @@ TEST_CASE("[MultiplicativeEnvelope] Going down quantized with 2 steps and starti
|
||||||
envelope.getQuantizedBlock(absl::MakeSpan(output), 2.0f);
|
envelope.getQuantizedBlock(absl::MakeSpan(output), 2.0f);
|
||||||
REQUIRE(output == expected);
|
REQUIRE(output == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("[MultiplicativeEnvelope] Pitch envelope basic function")
|
||||||
|
{
|
||||||
|
sfz::Buffer<float> output { 256 };
|
||||||
|
sfz::MultiplicativeEnvelope<float> envelope;
|
||||||
|
envelope.setFunction([](float pitchValue){
|
||||||
|
const auto normalizedBend = sfz::normalizeBend(pitchValue);
|
||||||
|
const auto bendInCents = normalizedBend * 200;
|
||||||
|
return sfz::centsFactor(bendInCents);
|
||||||
|
});
|
||||||
|
envelope.reset(0);
|
||||||
|
envelope.getBlock(absl::MakeSpan(output));
|
||||||
|
REQUIRE(output[255] == 1.0_a);
|
||||||
|
envelope.registerEvent(252, -6020);
|
||||||
|
envelope.getBlock(absl::MakeSpan(output));
|
||||||
|
REQUIRE(output[255] == Approx(0.9168).epsilon(0.01));
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue