Skip to main content

truce_params/
info.rs

1use crate::range::ParamRange;
2
3/// Metadata for a single parameter, used by format wrappers.
4///
5/// `Copy` because every field is POD (`&'static str`, scalars,
6/// bitflags, the [`ParamRange`] / [`ParamUnit`] enums). Lets the
7/// audio path pass `param_infos[i]` by value without `clone()` noise.
8#[derive(Clone, Copy, Debug)]
9pub struct ParamInfo {
10    pub id: u32,
11    pub name: &'static str,
12    pub short_name: &'static str,
13    pub group: &'static str,
14    pub range: ParamRange,
15    pub default_plain: f64,
16    pub flags: ParamFlags,
17    pub unit: ParamUnit,
18    /// Which `*Param` type backs this entry. Drives display rounding
19    /// (`IntParam` skips fractional digits) and `value_text` parsing,
20    /// independently of [`ParamRange`] - a `FloatParam` declared with
21    /// `range = "discrete(...)"` should still format as a float, so
22    /// inferring kind from range alone is wrong.
23    pub kind: ParamValueKind,
24}
25
26/// Which strongly-typed `*Param` constructor produced this
27/// [`ParamInfo`]. The `#[derive(Params)]` macro sets it from the
28/// field type so format-side code can branch on the original
29/// typing without re-deriving it from `range` / `unit`.
30#[derive(Clone, Copy, Debug, PartialEq, Eq)]
31pub enum ParamValueKind {
32    Float,
33    Int,
34    Bool,
35    Enum,
36}
37
38bitflags::bitflags! {
39    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
40    pub struct ParamFlags: u32 {
41        const AUTOMATABLE = 0b0_0001;
42        const HIDDEN      = 0b0_0010;
43        const READONLY    = 0b0_0100;
44        const IS_BYPASS   = 0b0_1000;
45        /// This parameter participates in sample-accurate sub-block
46        /// chunking: a `ParamChange` event targeting it splits the
47        /// audio block at its `sample_offset`. Defaults on; cleared
48        /// by `#[param(chunk = false)]` on expensive-to-retarget
49        /// params (FFT sizes, lookahead, etc.) where the per-event
50        /// fixed cost of subdividing the block outweighs the
51        /// sample-accuracy win. Read by
52        /// `truce_core::chunked_process::is_split_event`.
53        const CHUNKED     = 0b1_0000;
54    }
55}
56
57#[derive(Clone, Copy, Debug, PartialEq, Eq)]
58pub enum ParamUnit {
59    None,
60    Db,
61    Hz,
62    Milliseconds,
63    Seconds,
64    Percent,
65    Semitones,
66    Pan,
67    Degrees,
68}
69
70impl ParamUnit {
71    /// Format-agnostic unit string for host display.
72    #[must_use]
73    pub fn as_str(&self) -> &'static str {
74        match self {
75            Self::Db => "dB",
76            Self::Hz => "Hz",
77            Self::Milliseconds => "ms",
78            Self::Seconds => "s",
79            Self::Percent => "%",
80            Self::Semitones => "st",
81            Self::Degrees => "°",
82            Self::Pan | Self::None => "",
83        }
84    }
85}