Comments and licenses
This commit is contained in:
parent
0c68e40cc4
commit
b0bae1df9a
5 changed files with 186 additions and 0 deletions
|
|
@ -1,3 +1,9 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Range.h"
|
#include "Range.h"
|
||||||
|
|
@ -55,6 +61,14 @@ float crossfadeOut(const sfz::Range<T>& crossfadeRange, U value, SfzCrossfadeCur
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compute a linear envelope based on events, with a lambda applied to the event values
|
||||||
|
*
|
||||||
|
* @tparam F
|
||||||
|
* @param events
|
||||||
|
* @param envelope
|
||||||
|
* @param lambda
|
||||||
|
*/
|
||||||
template <class F>
|
template <class F>
|
||||||
void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda)
|
void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda)
|
||||||
{
|
{
|
||||||
|
|
@ -76,6 +90,15 @@ void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& l
|
||||||
fill(envelope.subspan(lastDelay), lastValue);
|
fill(envelope.subspan(lastDelay), lastValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compute a quantized linear envelope based on events, with a lambda applied to the event values
|
||||||
|
*
|
||||||
|
* @tparam F
|
||||||
|
* @param events
|
||||||
|
* @param envelope
|
||||||
|
* @param lambda
|
||||||
|
* @param step
|
||||||
|
*/
|
||||||
template <class F>
|
template <class F>
|
||||||
void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda, float step)
|
void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda, float step)
|
||||||
{
|
{
|
||||||
|
|
@ -116,6 +139,15 @@ void linearEnvelope(const EventVector& events, absl::Span<float> envelope, F&& l
|
||||||
fill(envelope.subspan(lastDelay), lastValue);
|
fill(envelope.subspan(lastDelay), lastValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compute a multiplicative envelope based on events, with a lambda applied to the event values
|
||||||
|
*
|
||||||
|
* @tparam F
|
||||||
|
* @param events
|
||||||
|
* @param envelope
|
||||||
|
* @param lambda
|
||||||
|
*/
|
||||||
template <class F>
|
template <class F>
|
||||||
void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda)
|
void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda)
|
||||||
{
|
{
|
||||||
|
|
@ -139,6 +171,16 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelop
|
||||||
fill(envelope.subspan(lastDelay), lastValue);
|
fill(envelope.subspan(lastDelay), lastValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compute a quantized multiplicative envelope based on events, with a lambda applied to the event values
|
||||||
|
*
|
||||||
|
* @tparam F
|
||||||
|
* @tparam Round is true if the quantization rounds rather than truncs the elements
|
||||||
|
* @param events
|
||||||
|
* @param envelope
|
||||||
|
* @param lambda
|
||||||
|
* @param step
|
||||||
|
*/
|
||||||
template <class F, bool Round = false>
|
template <class F, bool Round = false>
|
||||||
void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda, float step)
|
void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda, float step)
|
||||||
{
|
{
|
||||||
|
|
@ -186,18 +228,46 @@ void multiplicativeEnvelope(const EventVector& events, absl::Span<float> envelop
|
||||||
fill(envelope.subspan(lastDelay), lastValue);
|
fill(envelope.subspan(lastDelay), lastValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Alias for a multiplicative envelope that rounds the elements
|
||||||
|
*
|
||||||
|
* @tparam F
|
||||||
|
* @param events
|
||||||
|
* @param envelope
|
||||||
|
* @param lambda
|
||||||
|
* @param step
|
||||||
|
*/
|
||||||
template <class F>
|
template <class F>
|
||||||
void pitchBendEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda, float step)
|
void pitchBendEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda, float step)
|
||||||
{
|
{
|
||||||
multiplicativeEnvelope<F, true>(events, envelope, std::forward<F>(lambda), step);
|
multiplicativeEnvelope<F, true>(events, envelope, std::forward<F>(lambda), step);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Alias for a multiplicative envelope
|
||||||
|
*
|
||||||
|
* @tparam F
|
||||||
|
* @param events
|
||||||
|
* @param envelope
|
||||||
|
* @param lambda
|
||||||
|
*/
|
||||||
template <class F>
|
template <class F>
|
||||||
void pitchBendEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda)
|
void pitchBendEnvelope(const EventVector& events, absl::Span<float> envelope, F&& lambda)
|
||||||
{
|
{
|
||||||
multiplicativeEnvelope<F>(events, envelope, std::forward<F>(lambda));
|
multiplicativeEnvelope<F>(events, envelope, std::forward<F>(lambda));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Builds a linear envelope, possibly quantized, based on the events fetched
|
||||||
|
* from a midi state and the modifier data. This is a helper function for recurrent
|
||||||
|
* code in the voice logic.
|
||||||
|
*
|
||||||
|
* @tparam F
|
||||||
|
* @param resources
|
||||||
|
* @param span
|
||||||
|
* @param ccData
|
||||||
|
* @param lambda
|
||||||
|
*/
|
||||||
template <class F>
|
template <class F>
|
||||||
void linearModifier(const sfz::Resources& resources, absl::Span<float> span, const sfz::CCData<sfz::Modifier>& ccData, F&& lambda)
|
void linearModifier(const sfz::Resources& resources, absl::Span<float> span, const sfz::CCData<sfz::Modifier>& ccData, F&& lambda)
|
||||||
{
|
{
|
||||||
|
|
@ -217,6 +287,17 @@ void linearModifier(const sfz::Resources& resources, absl::Span<float> span, con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Builds a multiplicative envelope, possibly quantized, based on the events fetched
|
||||||
|
* from a midi state and the modifier data. This is a helper function for recurrent
|
||||||
|
* code in the voice logic.
|
||||||
|
*
|
||||||
|
* @tparam F
|
||||||
|
* @param resources
|
||||||
|
* @param span
|
||||||
|
* @param ccData
|
||||||
|
* @param lambda
|
||||||
|
*/
|
||||||
template <class F>
|
template <class F>
|
||||||
void multiplicativeModifier(const sfz::Resources& resources, absl::Span<float> span, const sfz::CCData<sfz::Modifier>& ccData, F&& lambda)
|
void multiplicativeModifier(const sfz::Resources& resources, absl::Span<float> span, const sfz::CCData<sfz::Modifier>& ccData, F&& lambda)
|
||||||
{
|
{
|
||||||
|
|
@ -236,6 +317,15 @@ void multiplicativeModifier(const sfz::Resources& resources, absl::Span<float> s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Alias for a simple linear modifier with no lambda
|
||||||
|
*
|
||||||
|
* @tparam F
|
||||||
|
* @param resources
|
||||||
|
* @param span
|
||||||
|
* @param ccData
|
||||||
|
* @param lambda
|
||||||
|
*/
|
||||||
inline void linearModifier(const sfz::Resources& resources, absl::Span<float> span, const sfz::CCData<sfz::Modifier>& ccData)
|
inline void linearModifier(const sfz::Resources& resources, absl::Span<float> span, const sfz::CCData<sfz::Modifier>& ccData)
|
||||||
{
|
{
|
||||||
linearModifier(resources, span, ccData, [](float x) { return x; });
|
linearModifier(resources, span, ccData, [](float x) { return x; });
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
@ -5,6 +11,10 @@
|
||||||
|
|
||||||
namespace sfz {
|
namespace sfz {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Base modifier class
|
||||||
|
*
|
||||||
|
*/
|
||||||
struct Modifier {
|
struct Modifier {
|
||||||
float value { 0.0f };
|
float value { 0.0f };
|
||||||
float step { 0.0f };
|
float step { 0.0f };
|
||||||
|
|
@ -23,6 +33,11 @@ enum class Mod : size_t {
|
||||||
sentinel
|
sentinel
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vectors of elements indexed on modifiers with casting and iterators
|
||||||
|
*
|
||||||
|
* @tparam T
|
||||||
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
class ModifierVector : public std::vector<T> {
|
class ModifierVector : public std::vector<T> {
|
||||||
public:
|
public:
|
||||||
|
|
@ -30,6 +45,11 @@ public:
|
||||||
const T& operator[](sfz::Mod idx) const { return this->std::vector<T>::operator[](static_cast<size_t>(idx)); }
|
const T& operator[](sfz::Mod idx) const { return this->std::vector<T>::operator[](static_cast<size_t>(idx)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Array of elements indexed on modifiers with casting and iterators
|
||||||
|
*
|
||||||
|
* @tparam T
|
||||||
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
class ModifierArray {
|
class ModifierArray {
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
#include "Smoothers.h"
|
#include "Smoothers.h"
|
||||||
|
|
||||||
namespace sfz {
|
namespace sfz {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
|
@ -9,11 +15,34 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
namespace sfz {
|
namespace sfz {
|
||||||
|
/**
|
||||||
|
* @brief Wrapper class for a one pole filter smoother
|
||||||
|
*
|
||||||
|
*/
|
||||||
class Smoother {
|
class Smoother {
|
||||||
public:
|
public:
|
||||||
Smoother();
|
Smoother();
|
||||||
|
/**
|
||||||
|
* @brief Set the filter cutoff based on the sfz smoothing value
|
||||||
|
* and the sample rate.
|
||||||
|
*
|
||||||
|
* @param smoothValue
|
||||||
|
* @param sampleRate
|
||||||
|
*/
|
||||||
void setSmoothing(uint8_t smoothValue, float sampleRate);
|
void setSmoothing(uint8_t smoothValue, float sampleRate);
|
||||||
|
/**
|
||||||
|
* @brief Reset the filter state to a given value
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
void reset(float value = 0.0f);
|
void reset(float value = 0.0f);
|
||||||
|
/**
|
||||||
|
* @brief Process a span of data. Input and output can refer to the same
|
||||||
|
* memory.
|
||||||
|
*
|
||||||
|
* @param input
|
||||||
|
* @param output
|
||||||
|
*/
|
||||||
void process(absl::Span<const float> input, absl::Span<float> output);
|
void process(absl::Span<const float> input, absl::Span<float> output);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -333,13 +333,46 @@ private:
|
||||||
const AudioSpan<const float>& source, AudioSpan<float>& dest,
|
const AudioSpan<const float>& source, AudioSpan<float>& dest,
|
||||||
absl::Span<const int> indices, absl::Span<const float> coeffs);
|
absl::Span<const int> indices, absl::Span<const float> coeffs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compute the amplitude envelope, applied as a gain to a mono
|
||||||
|
* or stereo buffer
|
||||||
|
*
|
||||||
|
* @param modulationSpan
|
||||||
|
*/
|
||||||
void amplitudeEnvelope(absl::Span<float> modulationSpan) noexcept;
|
void amplitudeEnvelope(absl::Span<float> modulationSpan) noexcept;
|
||||||
|
/**
|
||||||
|
* @brief Amplitude stage for a mono source
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
void ampStageMono(AudioSpan<float> buffer) noexcept;
|
void ampStageMono(AudioSpan<float> buffer) noexcept;
|
||||||
|
/**
|
||||||
|
* @brief Amplitude stage for a stereo source
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
void ampStageStereo(AudioSpan<float> buffer) noexcept;
|
void ampStageStereo(AudioSpan<float> buffer) noexcept;
|
||||||
|
/**
|
||||||
|
* @brief Amplitude stage for a mono source
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
void panStageMono(AudioSpan<float> buffer) noexcept;
|
void panStageMono(AudioSpan<float> buffer) noexcept;
|
||||||
void panStageStereo(AudioSpan<float> buffer) noexcept;
|
void panStageStereo(AudioSpan<float> buffer) noexcept;
|
||||||
|
/**
|
||||||
|
* @brief Amplitude stage for a mono source
|
||||||
|
*
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
void filterStageMono(AudioSpan<float> buffer) noexcept;
|
void filterStageMono(AudioSpan<float> buffer) noexcept;
|
||||||
void filterStageStereo(AudioSpan<float> buffer) noexcept;
|
void filterStageStereo(AudioSpan<float> buffer) noexcept;
|
||||||
|
/**
|
||||||
|
* @brief Compute the pitch envelope. This envelope is meant to multiply
|
||||||
|
* the frequency parameter for each sample (which translates to floating
|
||||||
|
* point intervals for sample-based voices, or phases for generators)
|
||||||
|
*
|
||||||
|
* @param pitchSpan
|
||||||
|
*/
|
||||||
void pitchEnvelope(absl::Span<float> pitchSpan) noexcept;
|
void pitchEnvelope(absl::Span<float> pitchSpan) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -348,6 +381,14 @@ private:
|
||||||
*/
|
*/
|
||||||
void removeVoiceFromRing() noexcept;
|
void removeVoiceFromRing() noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Helper function to iterate jointly on modifiers and smoothers
|
||||||
|
* for a given modulation target of type sfz::Mod
|
||||||
|
*
|
||||||
|
* @tparam F
|
||||||
|
* @param modId
|
||||||
|
* @param lambda
|
||||||
|
*/
|
||||||
template <class F>
|
template <class F>
|
||||||
void forEachWithSmoother(sfz::Mod modId, F&& lambda)
|
void forEachWithSmoother(sfz::Mod modId, F&& lambda)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue