19#include "../Core/DspMath.h"
20#include "../Core/SmoothedValue.h"
21#include "../Core/AudioSpec.h"
22#include "../Core/AudioBuffer.h"
23#include "../Core/SimdOps.h"
24#include "../Core/StateBlob.h"
63 void prepare(
double sampleRate,
double rampTimeMs = 10.0)
65 if (!(sampleRate > 0.0) || !std::isfinite(rampTimeMs))
return;
67 rampTimeMs_.store(std::max(0.0, rampTimeMs), std::memory_order_relaxed);
87 if (!std::isfinite(dB))
return;
99 if (!std::isfinite(linear))
return;
128 muted_.store(muted, std::memory_order_relaxed);
131 [[nodiscard]]
bool isMuted() const noexcept {
return muted_.load(std::memory_order_relaxed); }
139 inverted_.store(inverted, std::memory_order_relaxed);
150 if (!std::isfinite(rampTimeMs))
return;
151 rampTimeMs_.store(std::max(0.0, rampTimeMs), std::memory_order_relaxed);
164 const int nCh = buffer.getNumChannels();
165 const int nS = buffer.getNumSamples();
169 process(buffer.getChannel(0), nS);
174 int useCh = nCh < 16 ? nCh : 16;
175 for (
int c = 0; c < useCh; ++c)
176 channels[c] = buffer.getChannel(c);
184 void process(T* data,
int numSamples)
noexcept
190 for (; i < numSamples &&
gainSmooth_.isSmoothing(); ++i)
205 void process(T** channelData,
int numChannels,
int numSamples)
noexcept
210 for (; i < numSamples &&
gainSmooth_.isSmoothing(); ++i)
213 for (
int ch = 0; ch < numChannels; ++ch)
214 channelData[ch][i] *= g;
220 const int remaining = numSamples - i;
221 for (
int ch = 0; ch < numChannels; ++ch)
229 void process(
const T* input, T* output,
int numSamples)
noexcept
234 for (; i < numSamples &&
gainSmooth_.isSmoothing(); ++i)
242 const int remaining = numSamples - i;
245 std::copy_n(input + i, remaining, output + i);
264 [[nodiscard]] std::vector<uint8_t>
getState()
const
268 w.
write(
"rampMs",
static_cast<float>(
rampTimeMs_.load(std::memory_order_relaxed)));
269 w.
write(
"muted",
muted_.load(std::memory_order_relaxed));
298 const T baseTarget =
muted_.load(std::memory_order_relaxed) ? T(0)
301 const T finalTarget =
inverted_.load(std::memory_order_relaxed) ? -baseTarget : baseTarget;
315 const T baseTarget =
muted_.load(std::memory_order_relaxed) ? T(0)
317 const T finalTarget =
inverted_.load(std::memory_order_relaxed) ? -baseTarget : baseTarget;
Non-owning view over audio channel data.
Professional click-free gain processor.
void setGainLinear(T linear) noexcept
Sets the target gain as a linear multiplier. (Thread-safe, callable from UI).
void process(T *data, int numSamples) noexcept
Processes an interleaved or single-channel buffer in-place.
void prepare(double sampleRate, double rampTimeMs=10.0)
Prepares the gain processor for playback.
bool isMuted() const noexcept
std::atomic< bool > rampTimeChanged_
std::atomic< bool > muted_
std::atomic< T > targetGainLinear_
bool setState(const uint8_t *data, size_t size)
Restores parameters from a blob (tolerant; rejects foreign ids).
void setInverted(bool inverted) noexcept
Enables smooth phase inversion. (Thread-safe, callable from UI). Reverses polarity by ramping smoothl...
void process(T **channelData, int numChannels, int numSamples) noexcept
Processes separate channel buffers in-place.
void reset() noexcept
Resets gain internal state to match targets immediately.
void setMuted(bool muted) noexcept
Enables or disables mute smoothly. (Thread-safe, callable from UI).
void forceSynchronize() noexcept
Forces instantaneous synchronization of state without ramping.
void updateInternalState() noexcept
Synchronizes atomic UI variables with audio thread state. Must be called at the start of any audio pr...
T getGainLinear() const noexcept
Returns current target linear gain.
std::atomic< double > rampTimeMs_
std::vector< uint8_t > getState() const
Serializes the parameter state (setup/UI threads; allocates).
T getCurrentGain() const noexcept
Returns the current internal smoothed value.
void process(const T *input, T *output, int numSamples) noexcept
Processes input to output (not in-place).
void setRampTime(double rampTimeMs) noexcept
Sets the smoothing ramp time. (Thread-safe). Non-finite values are ignored; negatives clamp to 0.
void setGainDb(T dB) noexcept
Sets the target gain in decibels. (Thread-safe, callable from UI).
void prepare(const AudioSpec &spec)
Prepares from AudioSpec, preserving existing ramp time.
void processBlock(AudioBufferView< T > buffer) noexcept
Processes an AudioBufferView in-place. (Audio Thread only).
bool isInverted() const noexcept
SmoothedValue< T > gainSmooth_
std::atomic< bool > inverted_
void skipRamp() noexcept
Skips smoothing - immediately sets current gain to target.
T getGainDb() const noexcept
Returns current target gain in dB.
Zero-allocation parameter smoother for real-time audio.
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.
void applyGain(float *DSPARK_RESTRICT data, float gain, int count) noexcept
Multiplies all samples in a buffer by a gain factor.
Main namespace for the DSPark framework.
T decibelsToGain(T dB, T minusInfinityDb=T(-100)) noexcept
Converts a value in decibels to linear gain.
T gainToDecibels(T gain, T minusInfinityDb=T(-100)) noexcept
Converts a linear gain value to decibels.
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.
double sampleRate
Sample rate in Hz.