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 Oversampling defaultOversamplingFactor { Oversampling::x1 };
|
||||||
constexpr float A440 { 440.0 };
|
constexpr float A440 { 440.0 };
|
||||||
constexpr size_t powerHistoryLength { 16 };
|
constexpr size_t powerHistoryLength { 16 };
|
||||||
|
constexpr size_t powerFollowerStep { 512 };
|
||||||
constexpr float powerFollowerAttackFactor { 100 };
|
constexpr float powerFollowerAttackFactor { 100 };
|
||||||
constexpr float powerFollowerReleaseFactor { 10 };
|
constexpr float powerFollowerReleaseFactor { 10 };
|
||||||
constexpr uint16_t numCCs { 512 };
|
constexpr uint16_t numCCs { 512 };
|
||||||
|
|
|
||||||
|
|
@ -42,26 +42,51 @@ void PowerFollower::process(AudioSpan<float> buffer) noexcept
|
||||||
if (numFrames == 0)
|
if (numFrames == 0)
|
||||||
return;
|
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);
|
const float attackFactor = static_cast<float>(numFrames) * attackTrackingFactor_;
|
||||||
for (unsigned i = 1; i < buffer.getNumChannels(); ++i)
|
const float releaseFactor = static_cast<float>(numFrames) * releaseTrackingFactor_;
|
||||||
add(buffer.getConstSpan(i), tempBuffer);
|
|
||||||
|
|
||||||
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_;
|
copy(buffer.getConstSpan(0).subspan(index, blockSize), tempBuffer);
|
||||||
const float releaseFactor = static_cast<float>(buffer.getNumFrames()) * releaseTrackingFactor_;
|
for (unsigned i = 1, n = buffer.getNumChannels(); i < n; ++i)
|
||||||
|
add(buffer.getConstSpan(i).subspan(index, blockSize), tempBuffer);
|
||||||
|
|
||||||
meanChannelPower_ = max(
|
currentSum += sumSquares<float>(tempBuffer);
|
||||||
meanChannelPower_ * (1 - attackFactor) + meanPower * attackFactor,
|
currentCount += blockSize;
|
||||||
meanChannelPower_ * (1 - releaseFactor) + meanPower * releaseFactor
|
|
||||||
);
|
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
|
void PowerFollower::clear() noexcept
|
||||||
{
|
{
|
||||||
meanChannelPower_ = 0;
|
currentPower_ = 0;
|
||||||
|
currentSum_ = 0;
|
||||||
|
currentCount_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PowerFollower::updateTrackingFactor() noexcept
|
void PowerFollower::updateTrackingFactor() noexcept
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ public:
|
||||||
void setSamplesPerBlock(unsigned samplesPerBlock);
|
void setSamplesPerBlock(unsigned samplesPerBlock);
|
||||||
void process(AudioSpan<float> buffer) noexcept;
|
void process(AudioSpan<float> buffer) noexcept;
|
||||||
void clear() noexcept;
|
void clear() noexcept;
|
||||||
float getAveragePower() const noexcept { return meanChannelPower_; }
|
float getAveragePower() const noexcept { return currentPower_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateTrackingFactor() noexcept;
|
void updateTrackingFactor() noexcept;
|
||||||
|
|
@ -31,7 +31,9 @@ private:
|
||||||
float attackTrackingFactor_ {};
|
float attackTrackingFactor_ {};
|
||||||
float releaseTrackingFactor_ {};
|
float releaseTrackingFactor_ {};
|
||||||
|
|
||||||
float meanChannelPower_ {};
|
float currentPower_ {};
|
||||||
|
float currentSum_ = 0;
|
||||||
|
size_t currentCount_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sfz
|
} // namespace sfz
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue