Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
pulp::state::ParamValue Class Reference

Thread-safe atomic parameter value for lock-free audio/UI communication. More...

#include <parameter.hpp>

Public Types

using PackedIdentity = std::uint64_t
 Packed base identity: low 32 bits are float bits, high 32 bits are a monotonic per-parameter revision.
using VersionedValue = PackedIdentity

Public Member Functions

 ParamValue ()=default
 ParamValue (float initial)
 ParamValue (ParamValue &&other) noexcept
ParamValue & operator= (ParamValue &&other) noexcept
 ParamValue (const ParamValue &other)
ParamValue & operator= (const ParamValue &other)
float get () const
 Read the current base value (lock-free, relaxed ordering).
void set (float v) noexcept
 Write a new base value through the same bounded revision CAS as every other base-value writer.
VersionedValue versioned_value () const
std::uint64_t committed_generation () const
 Highest StateStore generation claimed or committed by a write to this parameter.
bool revision_available () const noexcept
bool revisions_available (std::uint32_t writes) const noexcept
bool set_versioned_if_newer (float value, std::uint64_t generation, std::uint32_t max_attempts)
 Legacy generation-ordered writer retained for source compatibility.
bool set_packed_revisioned (float value, std::uint64_t generation, std::uint32_t max_attempts) noexcept
 StateStore's ordinary base-value publication boundary.
bool compare_exchange_versioned (VersionedValue &expected, std::uint64_t expected_generation, float desired, std::uint64_t generation)
bool compare_exchange_packed (VersionedValue &expected, float desired, std::uint64_t generation)
 Conditional feedback publication boundary.
float get_modulated () const
 Read the modulated value: base + mod_offset.
float get_mod_offset () const
BaseOffsetValue get_base_offset () const noexcept
 Read the explicit base-vs-offset pair used by every automation route.
void set_mod_offset (float offset)
 Set the absolute modulation offset (replaces any existing offset).
bool set_mod_versioned_if_newer (float offset, std::uint64_t generation, std::uint32_t max_attempts)
void add_mod_offset (float delta)
 Add a delta to the current modulation offset (for stacking modulators).
void reset_mod ()
 Clear the modulation offset to zero.
void set_display_modulation (float plain) noexcept
 The value a plugin's OWN modulator is playing for this parameter, in plain units, published for display only (StateStore:: set_display_modulation()).
void clear_display_modulation () noexcept
float display_modulation () const noexcept
float get_normalized (const ParamRange &range) const
 Read the current value mapped to [0, 1] via the given range.
void set_normalized (float n, const ParamRange &range)
 Write a normalized [0, 1] value, denormalized via the given range.

Static Public Member Functions

static VersionedValue make_versioned_value (float value, std::uint64_t revision)
static float value_from_versioned (VersionedValue value)
static std::uint32_t revision_from_versioned (VersionedValue value)

Friends

class ParamValueTest

Detailed Description

Thread-safe atomic parameter value for lock-free audio/UI communication.

The audio thread reads and the UI thread writes via relaxed atomics. No locks, no allocation. Each parameter is independent, so relaxed ordering is correct — there is no dependency between reading param A and param B. For coherent multi-field reads (e.g., transport state), use SeqLock<T> instead.

Note
Relaxed atomics are safe on both x86 (TSO gives acquire/release for free) and ARM (each load/store is individually atomic; reordering between independent parameters is harmless).

Member Typedef Documentation

◆ PackedIdentity

Packed base identity: low 32 bits are float bits, high 32 bits are a monotonic per-parameter revision.

The revision is not StateStore's global generation and never wraps.

◆ VersionedValue

Constructor & Destructor Documentation

◆ ParamValue() [1/4]

pulp::state::ParamValue::ParamValue ( )
default

◆ ParamValue() [2/4]

pulp::state::ParamValue::ParamValue ( float initial)
inlineexplicit
Parameters
initialStarting value for this parameter.

◆ ParamValue() [3/4]

pulp::state::ParamValue::ParamValue ( ParamValue && other)
inlinenoexcept

◆ ParamValue() [4/4]

pulp::state::ParamValue::ParamValue ( const ParamValue & other)
inline

Member Function Documentation

◆ add_mod_offset()

void pulp::state::ParamValue::add_mod_offset ( float delta)
inline

Add a delta to the current modulation offset (for stacking modulators).

Note
Not atomic with respect to concurrent add_mod_offset calls; assumes a single writer (the audio thread).

◆ clear_display_modulation()

void pulp::state::ParamValue::clear_display_modulation ( )
inlinenoexcept

◆ committed_generation()

std::uint64_t pulp::state::ParamValue::committed_generation ( ) const
inline

Highest StateStore generation claimed or committed by a write to this parameter.

It only ever rises. Ordinary generation-ordered writers claim it before publishing so an older paused writer cannot overwrite a newer one; conditional writers authorize on the packed identity and only raise it, so they never revoke a pending ordinary writer's claim.

◆ compare_exchange_packed()

bool pulp::state::ParamValue::compare_exchange_packed ( VersionedValue & expected,
float desired,
std::uint64_t generation )
inline

Conditional feedback publication boundary.

Unlike the legacy generation API above, this compares only the exact packed identity and advances its per-parameter revision; the StateStore generation is diagnostic metadata and cannot participate in a split check/write.

◆ compare_exchange_versioned()

bool pulp::state::ParamValue::compare_exchange_versioned ( VersionedValue & expected,
std::uint64_t expected_generation,
float desired,
std::uint64_t generation )
inline

◆ display_modulation()

float pulp::state::ParamValue::display_modulation ( ) const
inlinenoexcept

◆ get()

float pulp::state::ParamValue::get ( ) const
inline

Read the current base value (lock-free, relaxed ordering).

◆ get_base_offset()

BaseOffsetValue pulp::state::ParamValue::get_base_offset ( ) const
inlinenoexcept

Read the explicit base-vs-offset pair used by every automation route.

◆ get_mod_offset()

float pulp::state::ParamValue::get_mod_offset ( ) const
inline

◆ get_modulated()

float pulp::state::ParamValue::get_modulated ( ) const
inline

Read the modulated value: base + mod_offset.

Used by the audio thread to get the final value after CLAP per-voice modulation.

◆ get_normalized()

float pulp::state::ParamValue::get_normalized ( const ParamRange & range) const
inline

Read the current value mapped to [0, 1] via the given range.

◆ make_versioned_value()

VersionedValue pulp::state::ParamValue::make_versioned_value ( float value,
std::uint64_t revision )
inlinestatic

◆ operator=() [1/2]

ParamValue & pulp::state::ParamValue::operator= ( const ParamValue & other)
inline

◆ operator=() [2/2]

ParamValue & pulp::state::ParamValue::operator= ( ParamValue && other)
inlinenoexcept

◆ reset_mod()

void pulp::state::ParamValue::reset_mod ( )
inline

Clear the modulation offset to zero.

◆ revision_available()

bool pulp::state::ParamValue::revision_available ( ) const
inlinenoexcept

◆ revision_from_versioned()

std::uint32_t pulp::state::ParamValue::revision_from_versioned ( VersionedValue value)
inlinestatic

◆ revisions_available()

bool pulp::state::ParamValue::revisions_available ( std::uint32_t writes) const
inlinenoexcept

◆ set()

void pulp::state::ParamValue::set ( float v)
inlinenoexcept

Write a new base value through the same bounded revision CAS as every other base-value writer.

A saturated revision is a terminal no-op.

◆ set_display_modulation()

void pulp::state::ParamValue::set_display_modulation ( float plain)
inlinenoexcept

The value a plugin's OWN modulator is playing for this parameter, in plain units, published for display only (StateStore:: set_display_modulation()).

NaN means nothing is published. Never read by DSP and never written to the host. Real-time safe.

◆ set_mod_offset()

void pulp::state::ParamValue::set_mod_offset ( float offset)
inline

Set the absolute modulation offset (replaces any existing offset).

◆ set_mod_versioned_if_newer()

bool pulp::state::ParamValue::set_mod_versioned_if_newer ( float offset,
std::uint64_t generation,
std::uint32_t max_attempts )
inline

◆ set_normalized()

void pulp::state::ParamValue::set_normalized ( float n,
const ParamRange & range )
inline

Write a normalized [0, 1] value, denormalized via the given range.

◆ set_packed_revisioned()

bool pulp::state::ParamValue::set_packed_revisioned ( float value,
std::uint64_t generation,
std::uint32_t max_attempts )
inlinenoexcept

StateStore's ordinary base-value publication boundary.

Ordinary writers are ordered by StateStore's global generation. Claim that generation before publishing the packed value; a writer that was paused after claiming an older generation must not overwrite a newer writer that has already published. Conditional feedback deliberately uses compare_exchange_packed() below instead, because its exact packed identity is the authorization token and the global generation is only diagnostic there.

◆ set_versioned_if_newer()

bool pulp::state::ParamValue::set_versioned_if_newer ( float value,
std::uint64_t generation,
std::uint32_t max_attempts )
inline

Legacy generation-ordered writer retained for source compatibility.

StateStore uses set_packed_revisioned() instead; this split API is not suitable for conditional authorization.

◆ value_from_versioned()

float pulp::state::ParamValue::value_from_versioned ( VersionedValue value)
inlinestatic

◆ versioned_value()

VersionedValue pulp::state::ParamValue::versioned_value ( ) const
inline

◆ ParamValueTest

friend class ParamValueTest
friend

The documentation for this class was generated from the following file:
  • /home/runner/work/pulp/pulp/core/state/include/pulp/state/parameter.hpp