Changed the historical buffer to a smoothed envelope tracker

This commit is contained in:
Paul Ferrand 2020-05-07 01:27:20 +02:00
parent d740f1c32b
commit a9980f163f
3 changed files with 42 additions and 8 deletions

View file

@ -54,6 +54,7 @@ namespace config {
constexpr Oversampling defaultOversamplingFactor { Oversampling::x1 };
constexpr float A440 { 440.0 };
constexpr size_t powerHistoryLength { 16 };
constexpr float filteredEnvelopeCutoff { 5 };
constexpr uint16_t numCCs { 512 };
constexpr int maxCurves { 256 };
constexpr int chunkSize { 1024 };

View file

@ -21,6 +21,9 @@ sfz::Voice::Voice(sfz::Resources& resources)
for (WavetableOscillator& osc : waveOscillators)
osc.init(sampleRate);
for (auto & filter : channelPowerFilters)
filter.setGain(vaGain(config::filteredEnvelopeCutoff, sampleRate));
}
void sfz::Voice::startVoice(Region* region, int delay, int number, float value, sfz::Voice::TriggerType triggerType) noexcept
@ -192,6 +195,9 @@ void sfz::Voice::setSampleRate(float sampleRate) noexcept
{
this->sampleRate = sampleRate;
for (auto & filter : channelPowerFilters)
filter.setGain(vaGain(config::filteredEnvelopeCutoff, sampleRate));
for (WavetableOscillator& osc : waveOscillators)
osc.init(sampleRate);
}
@ -207,11 +213,6 @@ void sfz::Voice::renderBlock(AudioSpan<float> buffer) noexcept
ASSERT(static_cast<int>(buffer.getNumFrames()) <= samplesPerBlock);
buffer.fill(0.0f);
if (state == State::idle || region == nullptr) {
powerHistory.push(0.0f);
return;
}
const auto delay = min(static_cast<size_t>(initialDelay), buffer.getNumFrames());
auto delayed_buffer = buffer.subspan(delay);
initialDelay -= static_cast<int>(delay);
@ -237,7 +238,8 @@ void sfz::Voice::renderBlock(AudioSpan<float> buffer) noexcept
if (!egEnvelope.isSmoothing())
reset();
powerHistory.push(buffer.meanSquared());
updateChannelPowers(buffer);
this->triggerDelay = absl::nullopt;
#if 0
ASSERT(!hasNanInf(buffer.getConstSpan(0)));
@ -629,13 +631,20 @@ void sfz::Voice::reset() noexcept
sourcePosition = 0;
floatPositionOffset = 0.0f;
noteIsOff = false;
for (auto& f : channelPowerFilters)
f.reset();
for (auto& p : channelPowers)
p = 0.0f;
filters.clear();
equalizers.clear();
}
float sfz::Voice::getMeanSquaredAverage() const noexcept
{
return powerHistory.getAverage();
return max(channelPowers[0], channelPowers[1]);
}
bool sfz::Voice::releasedOrFree() const noexcept
@ -718,3 +727,24 @@ void sfz::Voice::setupOscillatorUnison()
}
#endif
}
void sfz::Voice::updateChannelPowers(AudioSpan<float> buffer)
{
assert(channelPowers.size() == channelPowerFilters.size());
assert(buffer.getNumFrames() <= channelPowerFilters.size());
if (buffer.getNumFrames() == 0)
return;
auto tempSpan = resources.bufferPool.getBuffer(buffer.getNumFrames());
if (!tempSpan)
return;
for (unsigned i = 0; i < channelPowers.size(); ++i) {
for (unsigned s = 0; s < buffer.getNumFrames(); ++s)
(*tempSpan)[s] = std::abs(buffer.getConstSpan(i)[s]);
channelPowerFilters[i].processLowpass(*tempSpan, *tempSpan);
channelPowers[i] = tempSpan->back();
}
}

View file

@ -13,6 +13,7 @@
#include "Resources.h"
#include "AudioSpan.h"
#include "LeakDetector.h"
#include "OnePoleFilter.h"
#include "absl/types/span.h"
#include <memory>
#include <random>
@ -245,6 +246,7 @@ private:
* @brief Initialize frequency and gain coefficients for the oscillators.
*/
void setupOscillatorUnison();
void updateChannelPowers(AudioSpan<float> buffer);
Region* region { nullptr };
@ -299,7 +301,8 @@ private:
std::normal_distribution<float> noiseDist { 0, config::noiseVariance };
HistoricalBuffer<float> powerHistory { config::powerHistoryLength };
std::array<OnePoleFilter<float>, 2> channelPowerFilters;
std::array<float, 2> channelPowers;
LEAK_DETECTOR(Voice);
};