Documented the envelopes
This commit is contained in:
parent
30e175f4ca
commit
c31da4ef1c
3 changed files with 112 additions and 4 deletions
|
|
@ -25,15 +25,55 @@
|
||||||
#include "LeakDetector.h"
|
#include "LeakDetector.h"
|
||||||
#include <absl/types/span.h>
|
#include <absl/types/span.h>
|
||||||
namespace sfz {
|
namespace sfz {
|
||||||
|
/**
|
||||||
|
* @brief Describe an attack/delay/sustain/release envelope that can
|
||||||
|
* produce its coefficient in a blockwise manner for SIMD-type operations.
|
||||||
|
*
|
||||||
|
* @tparam Type the underlying type
|
||||||
|
*/
|
||||||
template <class Type>
|
template <class Type>
|
||||||
class ADSREnvelope {
|
class ADSREnvelope {
|
||||||
public:
|
public:
|
||||||
ADSREnvelope() = default;
|
ADSREnvelope() = default;
|
||||||
|
/**
|
||||||
|
* @brief Resets the ADSR envelope. There's alot of parameter but what can you do.
|
||||||
|
* They all match the SFZ specification.
|
||||||
|
*
|
||||||
|
* @param attack
|
||||||
|
* @param release
|
||||||
|
* @param sustain
|
||||||
|
* @param delay
|
||||||
|
* @param decay
|
||||||
|
* @param hold
|
||||||
|
* @param start
|
||||||
|
* @param depth
|
||||||
|
*/
|
||||||
void reset(int attack, int release, Type sustain = 1.0, int delay = 0, int decay = 0, int hold = 0, Type start = 0.0, Type depth = 1) noexcept;
|
void reset(int attack, int release, Type sustain = 1.0, int delay = 0, int decay = 0, int hold = 0, Type start = 0.0, Type depth = 1) noexcept;
|
||||||
|
/**
|
||||||
|
* @brief Get the next value for the envelope
|
||||||
|
*
|
||||||
|
* @return Type
|
||||||
|
*/
|
||||||
Type getNextValue() noexcept;
|
Type getNextValue() noexcept;
|
||||||
|
/**
|
||||||
|
* @brief Get a block of values for the envelope. This method tries hard to be efficient
|
||||||
|
* and hopefully it is.
|
||||||
|
*
|
||||||
|
* @param output
|
||||||
|
*/
|
||||||
void getBlock(absl::Span<Type> output) noexcept;
|
void getBlock(absl::Span<Type> output) noexcept;
|
||||||
|
/**
|
||||||
|
* @brief Start the envelope release after a delay.
|
||||||
|
*
|
||||||
|
* @param releaseDelay the delay before releasing in samples
|
||||||
|
*/
|
||||||
void startRelease(int releaseDelay) noexcept;
|
void startRelease(int releaseDelay) noexcept;
|
||||||
|
/**
|
||||||
|
* @brief Is the envelope smoothing?
|
||||||
|
*
|
||||||
|
* @return true
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
bool isSmoothing() noexcept;
|
bool isSmoothing() noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,17 @@
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file FloatEnvelopes.cpp
|
||||||
|
* @author Paul Ferrand (paul@ferrand.cc)
|
||||||
|
* @brief Force the instantiations of the ADSR and linear envelopes for floats
|
||||||
|
* @version 0.1
|
||||||
|
* @date 2019-11-30
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2019 Paul Ferrand
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#include "LinearEnvelope.h"
|
#include "LinearEnvelope.h"
|
||||||
#include "ADSREnvelope.h"
|
#include "ADSREnvelope.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,17 +30,74 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace sfz {
|
namespace sfz {
|
||||||
|
/**
|
||||||
|
* @brief Describes a simple linear envelope that can be polled in a blockwise
|
||||||
|
* manner. It works by storing "events" in the immediate future and linearly
|
||||||
|
* interpolating between these events. This envelope can also transform its
|
||||||
|
* incoming target points through a lambda, although the interpolation will
|
||||||
|
* always be linear (i.e. the lambda function is applied before the interpolation).
|
||||||
|
*
|
||||||
|
* The way to use this class is by repeatedly calling `registerEvent` and then
|
||||||
|
* `getBlock` to get a block of interpolated values in between the specified events.
|
||||||
|
* You should only register events whose timestamps are below the size of the block
|
||||||
|
* you will require when calling `getBlock`.
|
||||||
|
*
|
||||||
|
* @tparam Type
|
||||||
|
*/
|
||||||
template <class Type>
|
template <class Type>
|
||||||
class LinearEnvelope {
|
class LinearEnvelope {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Construct a new linear envelope with a default memory size for
|
||||||
|
* incoming events.
|
||||||
|
*
|
||||||
|
*/
|
||||||
LinearEnvelope();
|
LinearEnvelope();
|
||||||
|
/**
|
||||||
|
* @brief Construct a new linear envelope with a specific memory size for
|
||||||
|
* incoming events as well as a transformation function for incoming events.
|
||||||
|
*
|
||||||
|
* @param maxCapacity
|
||||||
|
* @param function
|
||||||
|
*/
|
||||||
LinearEnvelope(int maxCapacity, std::function<Type(Type)> function);
|
LinearEnvelope(int maxCapacity, std::function<Type(Type)> function);
|
||||||
|
/**
|
||||||
|
* @brief Set the maximum memory size for incoming events
|
||||||
|
*
|
||||||
|
* @param maxCapacity
|
||||||
|
*/
|
||||||
void setMaxCapacity(int maxCapacity);
|
void setMaxCapacity(int maxCapacity);
|
||||||
|
/**
|
||||||
|
* @brief Set the transformation function for the value of incoming events.
|
||||||
|
*
|
||||||
|
* @param function
|
||||||
|
*/
|
||||||
void setFunction(std::function<Type(Type)> function);
|
void setFunction(std::function<Type(Type)> function);
|
||||||
|
/**
|
||||||
|
* @brief Register a new event. Note that the timestamp of the new value should
|
||||||
|
* be less than the future call to `getBlock` otherwise the event will be ignored.
|
||||||
|
*
|
||||||
|
* @param timestamp
|
||||||
|
* @param inputValue
|
||||||
|
*/
|
||||||
void registerEvent(int timestamp, Type inputValue);
|
void registerEvent(int timestamp, Type inputValue);
|
||||||
|
/**
|
||||||
|
* @brief Clear all events in memory
|
||||||
|
*
|
||||||
|
*/
|
||||||
void clear();
|
void clear();
|
||||||
|
/**
|
||||||
|
* @brief Reset the envelope and clears the memory.
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
void reset(Type value = 0.0);
|
void reset(Type value = 0.0);
|
||||||
|
/**
|
||||||
|
* @brief Get a block of interpolated values between events previously registered
|
||||||
|
* using `registerEvent`.
|
||||||
|
*
|
||||||
|
* @param output
|
||||||
|
*/
|
||||||
void getBlock(absl::Span<Type> output);
|
void getBlock(absl::Span<Type> output);
|
||||||
private:
|
private:
|
||||||
std::function<Type(Type)> function { [](Type input) { return input; } };
|
std::function<Type(Type)> function { [](Type input) { return input; } };
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue