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 <absl/types/span.h>
|
||||
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>
|
||||
class ADSREnvelope {
|
||||
public:
|
||||
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;
|
||||
/**
|
||||
* @brief Get the next value for the envelope
|
||||
*
|
||||
* @return Type
|
||||
*/
|
||||
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;
|
||||
/**
|
||||
* @brief Start the envelope release after a delay.
|
||||
*
|
||||
* @param releaseDelay the delay before releasing in samples
|
||||
*/
|
||||
void startRelease(int releaseDelay) noexcept;
|
||||
/**
|
||||
* @brief Is the envelope smoothing?
|
||||
*
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool isSmoothing() noexcept;
|
||||
|
||||
private:
|
||||
|
|
@ -62,4 +102,4 @@ private:
|
|||
LEAK_DETECTOR(ADSREnvelope);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,17 @@
|
|||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// 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 "ADSREnvelope.h"
|
||||
|
||||
|
|
@ -33,4 +44,4 @@ namespace sfz
|
|||
{
|
||||
template class LinearEnvelope<float>;
|
||||
template class ADSREnvelope<float>;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,17 +30,74 @@
|
|||
#include <vector>
|
||||
|
||||
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>
|
||||
class LinearEnvelope {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new linear envelope with a default memory size for
|
||||
* incoming events.
|
||||
*
|
||||
*/
|
||||
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);
|
||||
/**
|
||||
* @brief Set the maximum memory size for incoming events
|
||||
*
|
||||
* @param 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);
|
||||
/**
|
||||
* @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);
|
||||
/**
|
||||
* @brief Clear all events in memory
|
||||
*
|
||||
*/
|
||||
void clear();
|
||||
/**
|
||||
* @brief Reset the envelope and clears the memory.
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
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);
|
||||
private:
|
||||
std::function<Type(Type)> function { [](Type input) { return input; } };
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue