Added a white noise generator

This commit is contained in:
Paul Fd 2020-02-09 14:55:46 +01:00
parent d455ee5232
commit 6461b4f4b4
3 changed files with 33 additions and 23 deletions

View file

@ -56,6 +56,7 @@ namespace config {
constexpr int filtersInPool { maxVoices * 2 };
constexpr int filtersPerVoice { 2 };
constexpr int eqsPerVoice { 3 };
constexpr float noiseVariance { 0.1f };
/**
Minimum interval in frames between recomputations of coefficients of the
modulated filter. The lower, the more CPU resources are consumed.

View file

@ -478,35 +478,41 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
void sfz::Voice::fillWithGenerator(AudioSpan<float> buffer) noexcept
{
if (region->sample != "*sine")
return;
const auto leftSpan = buffer.getSpan(0);
const auto rightSpan = buffer.getSpan(1);
if (region->sample == "*noise") {
absl::c_generate(leftSpan, [&](){ return noiseDist(Random::randomGenerator); });
absl::c_generate(rightSpan, [&](){ return noiseDist(Random::randomGenerator); });
}
else if (region->sample == "*sine") {
// TODO: wavetables for sine and other generators
if (buffer.getNumFrames() == 0)
return;
if (buffer.getNumFrames() == 0)
return;
auto jumps = tempSpan1.first(buffer.getNumFrames());
auto bends = tempSpan2.first(buffer.getNumFrames());
auto phases = tempSpan2.first(buffer.getNumFrames());
auto jumps = tempSpan1.first(buffer.getNumFrames());
auto bends = tempSpan2.first(buffer.getNumFrames());
auto phases = tempSpan2.first(buffer.getNumFrames());
const float step = baseFrequency * twoPi<float> / sampleRate;
fill<float>(jumps, step);
const float step = baseFrequency * twoPi<float> / sampleRate;
fill<float>(jumps, step);
if (region->bendStep > 1)
pitchBendEnvelope.getQuantizedBlock(bends, bendStepFactor);
else
pitchBendEnvelope.getBlock(bends);
if (region->bendStep > 1)
pitchBendEnvelope.getQuantizedBlock(bends, bendStepFactor);
else
pitchBendEnvelope.getBlock(bends);
applyGain<float>(bends, jumps);
jumps[0] += phase;
cumsum<float>(jumps, phases);
phase = phases.back();
applyGain<float>(bends, jumps);
jumps[0] += phase;
cumsum<float>(jumps, phases);
phase = phases.back();
sin<float>(phases, leftSpan);
copy<float>(leftSpan, rightSpan);
sin<float>(phases, buffer.getSpan(0));
copy<float>(buffer.getSpan(0), buffer.getSpan(1));
// Wrap the phase so we don't loose too much precision on longer notes
const auto numTwoPiWraps = static_cast<int>(phase / twoPi<float>);
phase -= twoPi<float> * static_cast<float>(numTwoPiWraps);
// Wrap the phase so we don't loose too much precision on longer notes
const auto numTwoPiWraps = static_cast<int>(phase / twoPi<float>);
phase -= twoPi<float> * static_cast<float>(numTwoPiWraps);
}
}
bool sfz::Voice::checkOffGroup(int delay, uint32_t group) noexcept

View file

@ -18,6 +18,7 @@
#include <absl/types/span.h>
#include <atomic>
#include <memory>
#include <random>
namespace sfz {
/**
@ -308,6 +309,8 @@ private:
MultiplicativeEnvelope<float> volumeEnvelope;
float bendStepFactor { centsFactor(1) };
std::normal_distribution<float> noiseDist { 0, config::noiseVariance };
HistoricalBuffer<float> powerHistory { config::powerHistoryLength };
LEAK_DETECTOR(Voice);
};