From c31da4ef1c78a330348fb70a32e7473a48b19a87 Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Sat, 30 Nov 2019 00:51:35 +0100 Subject: [PATCH] Documented the envelopes --- src/sfizz/ADSREnvelope.h | 44 +++++++++++++++++++++++++-- src/sfizz/FloatEnvelopes.cpp | 13 +++++++- src/sfizz/LinearEnvelope.h | 59 +++++++++++++++++++++++++++++++++++- 3 files changed, 112 insertions(+), 4 deletions(-) diff --git a/src/sfizz/ADSREnvelope.h b/src/sfizz/ADSREnvelope.h index f9cf9ec2..20733032 100644 --- a/src/sfizz/ADSREnvelope.h +++ b/src/sfizz/ADSREnvelope.h @@ -25,15 +25,55 @@ #include "LeakDetector.h" #include 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 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 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); }; -} \ No newline at end of file +} diff --git a/src/sfizz/FloatEnvelopes.cpp b/src/sfizz/FloatEnvelopes.cpp index b3c0cb80..c08a0823 100644 --- a/src/sfizz/FloatEnvelopes.cpp +++ b/src/sfizz/FloatEnvelopes.cpp @@ -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; template class ADSREnvelope; -} \ No newline at end of file +} diff --git a/src/sfizz/LinearEnvelope.h b/src/sfizz/LinearEnvelope.h index ae9b5927..d69562c3 100644 --- a/src/sfizz/LinearEnvelope.h +++ b/src/sfizz/LinearEnvelope.h @@ -30,17 +30,74 @@ #include 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 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 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 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 output); private: std::function function { [](Type input) { return input; } };