Power follower using a fixed block size
This commit is contained in:
parent
732222b8d3
commit
b1f1fc4042
3 changed files with 42 additions and 14 deletions
|
|
@ -57,6 +57,7 @@ namespace config {
|
|||
constexpr Oversampling defaultOversamplingFactor { Oversampling::x1 };
|
||||
constexpr float A440 { 440.0 };
|
||||
constexpr size_t powerHistoryLength { 16 };
|
||||
constexpr size_t powerFollowerStep { 512 };
|
||||
constexpr float powerFollowerAttackFactor { 100 };
|
||||
constexpr float powerFollowerReleaseFactor { 10 };
|
||||
constexpr uint16_t numCCs { 512 };
|
||||
|
|
|
|||
|
|
@ -42,26 +42,51 @@ void PowerFollower::process(AudioSpan<float> buffer) noexcept
|
|||
if (numFrames == 0)
|
||||
return;
|
||||
|
||||
absl::Span<float> tempBuffer(tempBuffer_.get(), numFrames);
|
||||
///
|
||||
constexpr size_t step = config::powerFollowerStep;
|
||||
float currentPower = currentPower_;
|
||||
float currentSum = currentSum_;
|
||||
size_t currentCount = currentCount_;
|
||||
|
||||
copy(buffer.getConstSpan(0), tempBuffer);
|
||||
for (unsigned i = 1; i < buffer.getNumChannels(); ++i)
|
||||
add(buffer.getConstSpan(i), tempBuffer);
|
||||
const float attackFactor = static_cast<float>(numFrames) * attackTrackingFactor_;
|
||||
const float releaseFactor = static_cast<float>(numFrames) * releaseTrackingFactor_;
|
||||
|
||||
const float meanPower = meanSquared<float>(tempBuffer);
|
||||
///
|
||||
size_t index = 0;
|
||||
while (index < numFrames) {
|
||||
size_t blockSize = std::min(step - currentCount, numFrames - index);
|
||||
absl::Span<float> tempBuffer(tempBuffer_.get(), blockSize);
|
||||
|
||||
const float attackFactor = static_cast<float>(buffer.getNumFrames()) * attackTrackingFactor_;
|
||||
const float releaseFactor = static_cast<float>(buffer.getNumFrames()) * releaseTrackingFactor_;
|
||||
copy(buffer.getConstSpan(0).subspan(index, blockSize), tempBuffer);
|
||||
for (unsigned i = 1, n = buffer.getNumChannels(); i < n; ++i)
|
||||
add(buffer.getConstSpan(i).subspan(index, blockSize), tempBuffer);
|
||||
|
||||
meanChannelPower_ = max(
|
||||
meanChannelPower_ * (1 - attackFactor) + meanPower * attackFactor,
|
||||
meanChannelPower_ * (1 - releaseFactor) + meanPower * releaseFactor
|
||||
);
|
||||
currentSum += sumSquares<float>(tempBuffer);
|
||||
currentCount += blockSize;
|
||||
|
||||
if (currentCount == step) {
|
||||
const float meanPower = currentSum / step;
|
||||
currentPower = max(
|
||||
currentPower * (1 - attackFactor) + meanPower * attackFactor,
|
||||
currentPower * (1 - releaseFactor) + meanPower * releaseFactor);
|
||||
currentSum = 0;
|
||||
currentCount = 0;
|
||||
}
|
||||
|
||||
index += blockSize;
|
||||
}
|
||||
|
||||
///
|
||||
currentPower_ = currentPower;
|
||||
currentSum_ = currentSum;
|
||||
currentCount_ = currentCount;
|
||||
}
|
||||
|
||||
void PowerFollower::clear() noexcept
|
||||
{
|
||||
meanChannelPower_ = 0;
|
||||
currentPower_ = 0;
|
||||
currentSum_ = 0;
|
||||
currentCount_ = 0;
|
||||
}
|
||||
|
||||
void PowerFollower::updateTrackingFactor() noexcept
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public:
|
|||
void setSamplesPerBlock(unsigned samplesPerBlock);
|
||||
void process(AudioSpan<float> buffer) noexcept;
|
||||
void clear() noexcept;
|
||||
float getAveragePower() const noexcept { return meanChannelPower_; }
|
||||
float getAveragePower() const noexcept { return currentPower_; }
|
||||
|
||||
private:
|
||||
void updateTrackingFactor() noexcept;
|
||||
|
|
@ -31,7 +31,9 @@ private:
|
|||
float attackTrackingFactor_ {};
|
||||
float releaseTrackingFactor_ {};
|
||||
|
||||
float meanChannelPower_ {};
|
||||
float currentPower_ {};
|
||||
float currentSum_ = 0;
|
||||
size_t currentCount_ = 0;
|
||||
};
|
||||
|
||||
} // namespace sfz
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue