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 filtersInPool { maxVoices * 2 };
constexpr int filtersPerVoice { 2 }; constexpr int filtersPerVoice { 2 };
constexpr int eqsPerVoice { 3 }; constexpr int eqsPerVoice { 3 };
constexpr float noiseVariance { 0.1f };
/** /**
Minimum interval in frames between recomputations of coefficients of the Minimum interval in frames between recomputations of coefficients of the
modulated filter. The lower, the more CPU resources are consumed. 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 void sfz::Voice::fillWithGenerator(AudioSpan<float> buffer) noexcept
{ {
if (region->sample != "*sine") const auto leftSpan = buffer.getSpan(0);
return; 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) auto jumps = tempSpan1.first(buffer.getNumFrames());
return; auto bends = tempSpan2.first(buffer.getNumFrames());
auto phases = tempSpan2.first(buffer.getNumFrames());
auto jumps = tempSpan1.first(buffer.getNumFrames()); const float step = baseFrequency * twoPi<float> / sampleRate;
auto bends = tempSpan2.first(buffer.getNumFrames()); fill<float>(jumps, step);
auto phases = tempSpan2.first(buffer.getNumFrames());
const float step = baseFrequency * twoPi<float> / sampleRate; if (region->bendStep > 1)
fill<float>(jumps, step); pitchBendEnvelope.getQuantizedBlock(bends, bendStepFactor);
else
pitchBendEnvelope.getBlock(bends);
if (region->bendStep > 1) applyGain<float>(bends, jumps);
pitchBendEnvelope.getQuantizedBlock(bends, bendStepFactor); jumps[0] += phase;
else cumsum<float>(jumps, phases);
pitchBendEnvelope.getBlock(bends); phase = phases.back();
applyGain<float>(bends, jumps); sin<float>(phases, leftSpan);
jumps[0] += phase; copy<float>(leftSpan, rightSpan);
cumsum<float>(jumps, phases);
phase = phases.back();
sin<float>(phases, buffer.getSpan(0)); // Wrap the phase so we don't loose too much precision on longer notes
copy<float>(buffer.getSpan(0), buffer.getSpan(1)); 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 bool sfz::Voice::checkOffGroup(int delay, uint32_t group) noexcept

View file

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