35#include "../Core/AnalogRandom.h"
36#include "../Core/AudioBuffer.h"
37#include "../Core/AudioSpec.h"
38#include "../Core/DspMath.h"
39#include "../Core/StateBlob.h"
88 generators_.reserve(
static_cast<size_t>(targetChannels));
90 for (
int ch = 0; ch < targetChannels; ++ch)
98 gen.
setRateHz(
static_cast<T
>(sampleRate_));
102 gen.
reseed(
static_cast<uint64_t
>(ch + 1) * 0x9E3779B97F4A7C15ULL);
103 generators_.push_back(std::move(gen));
107 currentGain_ = gain_.load(std::memory_order_relaxed);
120 if (generators_.empty())
123 if (typeDirty_.exchange(
false, std::memory_order_acquire))
125 for (
auto& gen : generators_)
129 const int numCh = std::min<int>(buffer.getNumChannels(),
static_cast<int>(generators_.size()));
130 const int numSamples = buffer.getNumSamples();
132 if (numSamples <= 0 || numCh <= 0)
136 const T targetGain = gain_.load(std::memory_order_relaxed);
137 const T startGain = currentGain_;
138 const bool needsSmoothing = std::abs(targetGain - startGain) > T(1e-6);
139 const T gainStep = needsSmoothing ? ((targetGain - startGain) /
static_cast<T
>(numSamples)) : T(0);
141 for (
int ch = 0; ch < numCh; ++ch)
143 T* data = buffer.getChannel(ch);
144 auto& gen = generators_[
static_cast<size_t>(ch)];
149 for (
int i = 0; i < numSamples; ++i)
152 data[i] = gen.getNextSample() * g;
157 for (
int i = 0; i < numSamples; ++i)
159 data[i] = gen.getNextSample() * targetGain;
165 currentGain_ = targetGain;
179 for (
auto& gen : generators_)
182 gen.reseed(
static_cast<uint64_t
>(++ch) * 0x9E3779B97F4A7C15ULL);
185 currentGain_ = gain_.load(std::memory_order_relaxed);
199 const int t = std::clamp(
static_cast<int>(type), 0,
201 type_.store(
static_cast<Type>(t), std::memory_order_relaxed);
202 typeDirty_.store(
true, std::memory_order_release);
212 if (std::isnan(levelDb) || levelDb > T(1e6))
return;
223 if (!std::isfinite(gain))
return;
224 gain_.store(gain, std::memory_order_relaxed);
233 return type_.load(std::memory_order_relaxed);
242 return gain_.load(std::memory_order_relaxed);
247 [[nodiscard]] std::vector<uint8_t>
getState()
const
250 w.
write(
"gain", gain_.load(std::memory_order_relaxed));
251 w.
write(
"type",
static_cast<int32_t
>(type_.load(std::memory_order_relaxed)));
268 switch (type_.load(std::memory_order_relaxed))
282 double sampleRate_ = 44100.0;
285 std::atomic<T> gain_ { T(1) };
287 std::atomic<bool> typeDirty_ {
false };
290 T currentGain_ { T(1) };
293 std::vector<AnalogRandom::Generator<T>> generators_;
Main generator class for analog-style random modulation.
void setRateHz(Real rateInHz) noexcept
void reseed(std::uint64_t newSeed) noexcept
Request a lock-free reseed of the internal PRNG.
void prepare(double sampleRate) noexcept
Prepare the generator with the audio sample rate.
void setRange(T min, T max) noexcept
Set the output range for values. Safe from tearing.
Non-owning view over audio channel data.
Generates decorellated noise (white, pink, brown) across multiple channels.
void setLevel(T levelDb) noexcept
Sets the output level in decibels. Thread-safe.
void reset() noexcept
Resets the internal PRNG and filter states.
void prepare(const AudioSpec &spec)
Prepares the noise generator and allocates internal state.
bool setState(const uint8_t *data, size_t size)
Restores parameters from a blob (tolerant; rejects foreign ids).
T getGain() const noexcept
Retrieves the current target gain in linear scale.
void setType(Type type) noexcept
Sets the noise spectrum type.
void setGain(T gain) noexcept
Sets the output level as linear gain. Thread-safe.
Type getType() const noexcept
Retrieves the currently requested noise type.
std::vector< uint8_t > getState() const
Serializes the parameter state (setup/UI threads; allocates).
void processBlock(AudioBufferView< T > buffer) noexcept
Fills the buffer with generated noise.
Tolerant reader: missing keys yield defaults, unknown keys are skipped.
float read(const char *key, float defaultValue) const
Reads a float, or defaultValue when the key is absent.
bool isValid() const noexcept
uint32_t processorId() const noexcept
Serializes key/value parameters into a versioned blob.
std::vector< uint8_t > blob() const
Finalizes and returns the blob.
void write(const char *key, float value)
Writes a float parameter.
@ White
Uncorrelated noise for "sample-and-hold" effects.
@ Pink
1/f noise for organic drift.
@ Brown
1/f^2 noise for slow "wow/flutter".
Main namespace for the DSPark framework.
T decibelsToGain(T dB, T minusInfinityDb=T(-100)) noexcept
Converts a value in decibels to linear gain.
constexpr uint32_t stateId(const char(&tag)[5]) noexcept
Builds a FOURCC processor id, e.g. dspark::stateId("COMP").
Describes the audio environment for a DSP processor.
constexpr bool isValid() const noexcept
Checks if the specification contains valid, processable parameters.
int numChannels
Number of audio channels (e.g., 1 = mono, 2 = stereo).
double sampleRate
Sample rate in Hz.