Added the pan envelope
This commit is contained in:
parent
c1d2384e09
commit
83fbfc1fcb
6 changed files with 47 additions and 11 deletions
|
|
@ -41,7 +41,6 @@ public:
|
|||
void clear();
|
||||
void reset(Type value = 0.0);
|
||||
void getBlock(absl::Span<Type> output);
|
||||
|
||||
private:
|
||||
std::function<Type(Type)> function { [](Type input) { return input; } };
|
||||
static_assert(std::is_arithmetic<Type>::value);
|
||||
|
|
|
|||
|
|
@ -712,7 +712,7 @@ float sfz::Region::getNoteGain(int noteNumber, uint8_t velocity) noexcept
|
|||
return baseGain;
|
||||
}
|
||||
|
||||
float sfz::Region::getCCGain(const sfz::CCValueArray& ccState) noexcept
|
||||
float sfz::Region::getCrossfadeGain(const sfz::CCValueArray& ccState) noexcept
|
||||
{
|
||||
float gain { 1.0f };
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ struct Region {
|
|||
bool isStereo() const noexcept;
|
||||
float getBasePitchVariation(int noteNumber, uint8_t velocity) noexcept;
|
||||
float getNoteGain(int noteNumber, uint8_t velocity) noexcept;
|
||||
float getCCGain(const CCValueArray& ccState) noexcept;
|
||||
float getCrossfadeGain(const CCValueArray& ccState) noexcept;
|
||||
float getBaseGain() noexcept;
|
||||
float velocityGain(uint8_t velocity) const noexcept;
|
||||
uint32_t getOffset() noexcept;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,12 @@ inline constexpr float normalizePercents(T percentValue)
|
|||
return std::min(std::max(static_cast<float>(percentValue), 0.0f), 100.0f) / 100.0f;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline constexpr float normalizeNegativePercents(T percentValue)
|
||||
{
|
||||
return std::min(std::max(static_cast<float>(percentValue), -100.0f), 100.0f) / 100.0f;
|
||||
}
|
||||
|
||||
inline float ccSwitchedValue(const CCValueArray& ccValues, const std::optional<CCValuePair>& ccSwitch, float value) noexcept
|
||||
{
|
||||
if (ccSwitch)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "Voice.h"
|
||||
#include "AudioSpan.h"
|
||||
#include "Defaults.h"
|
||||
#include "SIMDHelpers.h"
|
||||
#include "SfzHelpers.h"
|
||||
|
|
@ -50,15 +51,24 @@ void sfz::Voice::startVoice(Region* region, int delay, int channel, int number,
|
|||
state = State::playing;
|
||||
speedRatio = static_cast<float>(region->sampleRate / this->sampleRate);
|
||||
pitchRatio = region->getBasePitchVariation(number, value);
|
||||
|
||||
baseGain = region->getBaseGain();
|
||||
if (triggerType != TriggerType::CC)
|
||||
baseGain *= region->getNoteGain(number, value);
|
||||
baseGain *= region->getCCGain(ccState);
|
||||
baseGain *= region->getCrossfadeGain(ccState);
|
||||
if (region->amplitudeCC)
|
||||
baseGain *= normalizeCC(ccState[region->amplitudeCC->first]) * normalizePercents(region->amplitudeCC->second);
|
||||
amplitudeEnvelope.reset(baseGain);
|
||||
|
||||
basePan = normalizeNegativePercents(region->pan);
|
||||
auto pan = basePan;
|
||||
if (region->panCC)
|
||||
pan += normalizeCC(ccState[region->amplitudeCC->first]) * normalizeNegativePercents(region->amplitudeCC->second);
|
||||
panEnvelope.reset(pan);
|
||||
DBG("Base Panning: " << pan);
|
||||
|
||||
sourcePosition = region->getOffset();
|
||||
floatPosition = static_cast<float>(sourcePosition);
|
||||
initialDelay = delay + region->getDelay();
|
||||
baseFrequency = midiNoteFrequency(number) * pitchRatio;
|
||||
prepareEGEnvelope(delay, value);
|
||||
|
|
@ -129,6 +139,11 @@ void sfz::Voice::registerCC(int delay, int channel [[maybe_unused]], int ccNumbe
|
|||
const float newGain { normalizeCC(ccValue) * normalizePercents(region->amplitudeCC->second) * baseGain };
|
||||
amplitudeEnvelope.registerEvent(delay, newGain);
|
||||
}
|
||||
|
||||
if (region->panCC && ccNumber == region->panCC->first) {
|
||||
const float newPan { basePan + normalizeCC(ccValue) * normalizeNegativePercents(region->amplitudeCC->second)};
|
||||
panEnvelope.registerEvent(delay, newPan);
|
||||
}
|
||||
}
|
||||
|
||||
void sfz::Voice::registerPitchWheel(int delay [[maybe_unused]], int channel [[maybe_unused]], int pitch [[maybe_unused]]) noexcept
|
||||
|
|
@ -190,15 +205,31 @@ void sfz::Voice::processMono(AudioSpan<float> buffer) noexcept
|
|||
auto leftBuffer = buffer.getSpan(0);
|
||||
auto rightBuffer = buffer.getSpan(1);
|
||||
|
||||
auto envelopeSpan = tempSpan1.first(numSamples);
|
||||
amplitudeEnvelope.getBlock(envelopeSpan);
|
||||
::applyGain<float>(envelopeSpan, leftBuffer);
|
||||
auto span1 = tempSpan1.first(numSamples);
|
||||
auto span2 = tempSpan2.first(numSamples);
|
||||
|
||||
egEnvelope.getBlock(envelopeSpan);
|
||||
::applyGain<float>(envelopeSpan, leftBuffer);
|
||||
// Amplitude envelope
|
||||
amplitudeEnvelope.getBlock(span1);
|
||||
::applyGain<float>(span1, leftBuffer);
|
||||
|
||||
// AmpEG envelope
|
||||
egEnvelope.getBlock(span1);
|
||||
::applyGain<float>(span1, leftBuffer);
|
||||
|
||||
// Prepare for stereo output
|
||||
::copy<float>(leftBuffer, rightBuffer);
|
||||
|
||||
panEnvelope.getBlock(span1);
|
||||
// We assume that the pan envelope is already normalized between -1 and 1
|
||||
::fill<float>(span2, 1.0f);
|
||||
::add<float>(span1, span2);
|
||||
::applyGain<float>(piFour<float>, span2);
|
||||
::cos<float>(span2, span1);
|
||||
::sin<float>(span2, span2);
|
||||
::applyGain<float>(span1, leftBuffer);
|
||||
::applyGain<float>(span2, rightBuffer);
|
||||
}
|
||||
|
||||
void sfz::Voice::processStereo(AudioSpan<float> buffer) noexcept
|
||||
{
|
||||
const auto numSamples = buffer.getNumFrames();
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ private:
|
|||
float speedRatio { 1.0 };
|
||||
float pitchRatio { 1.0 };
|
||||
float baseGain { 1.0 };
|
||||
float basePan { 0.0 };
|
||||
float baseFrequency { 440.0 };
|
||||
float phase { 0.0f };
|
||||
|
||||
|
|
@ -113,8 +114,7 @@ private:
|
|||
const CCValueArray& ccState;
|
||||
ADSREnvelope<float> egEnvelope;
|
||||
LinearEnvelope<float> amplitudeEnvelope;
|
||||
LinearEnvelope<float> leftPanEnvelope;
|
||||
LinearEnvelope<float> rightPanEnvelope;
|
||||
LinearEnvelope<float> panEnvelope;
|
||||
|
||||
LEAK_DETECTOR(Voice);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue