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(sampleRate) || !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;
131 muted_.store(muted, std::memory_order_relaxed);
134 [[nodiscard]]
bool isMuted() const noexcept {
return muted_.load(std::memory_order_relaxed); }
142 inverted_.store(inverted, std::memory_order_relaxed);
153 if (!std::isfinite(rampTimeMs))
return;
154 rampTimeMs_.store(std::max(0.0, rampTimeMs), std::memory_order_relaxed);
167 const int nCh = buffer.getNumChannels();
168 const int nS = buffer.getNumSamples();
172 process(buffer.getChannel(0), nS);
177 int useCh = nCh < 16 ? nCh : 16;
178 for (
int c = 0; c < useCh; ++c)
179 channels[c] = buffer.getChannel(c);
187 void process(T* data,
int numSamples)
noexcept
193 for (; i < numSamples &&
gainSmooth_.isSmoothing(); ++i)
210 void process(T** channelData,
int numChannels,
int numSamples)
noexcept
215 for (; i < numSamples &&
gainSmooth_.isSmoothing(); ++i)
218 for (
int ch = 0; ch < numChannels; ++ch)
219 channelData[ch][i] *= g;
225 const int remaining = numSamples - i;
226 for (
int ch = 0; ch < numChannels; ++ch)
236 void process(
const T* input, T* output,
int numSamples)
noexcept
241 for (; i < numSamples &&
gainSmooth_.isSmoothing(); ++i)
249 const int remaining = numSamples - i;
252 std::copy_n(input + i, remaining, output + i);
273 [[nodiscard]] std::vector<uint8_t>
getState()
const
277 w.
write(
"rampMs",
static_cast<float>(
rampTimeMs_.load(std::memory_order_relaxed)));
278 w.
write(
"muted",
muted_.load(std::memory_order_relaxed));
319 const T baseTarget =
muted_.load(std::memory_order_relaxed) ? T(0)
322 const T finalTarget =
inverted_.load(std::memory_order_relaxed) ? -baseTarget : baseTarget;
336 const T baseTarget =
muted_.load(std::memory_order_relaxed) ? T(0)
338 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
void publishGain() noexcept
Publishes the smoother's value for cross-thread metering.
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.
std::atomic< T > publishedGain_
Cross-thread metering readout.
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.