1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//! [`Vibrato`] — the per-instrument auto-vibrato LFO carried by
//! [`VoiceSetup`].
//!
//! Distinct from the per-cell `Vibrato` automation lane: this is the
//! instrument-level LFO that runs continuously while a note is
//! held, independent of any pattern-row effect. Configures the
//! waveform, speed, depth, and an attack `sweep` (the LFO ramps
//! from zero to full depth over `sweep` ticks at trigger time).
//!
//! [`VoiceSetup`]: crate::core::voice_setup::VoiceSetup
use ;
use crateQ8_8;
use cratePitchDelta;
use crateWaveform;
/// Instrument auto-vibrato.
///
/// Numeric fields are stored in fixed-point so the engine runs
/// without an FPU:
///
/// * [`speed`](Self::speed) — fractional cycles per tick. The
/// XM range, after `byte / 252` normalisation, is `[0, ~1.012]`.
/// `Q8_8` covers this with room to spare (`±128.0`).
/// * [`depth`](Self::depth) — modulation amplitude as a pitch
/// delta. XM stores it as `byte / 30 ∈ [0, ~8.5]` worst case;
/// SID as `byte / 15 ∈ [0, 1]`. [`PitchDelta`] is the right
/// newtype: same Q8.8 storage, semantically a pitch quantity.
/// * [`sweep`](Self::sweep) — phase threshold for ramp-in,
/// measured in the same units as accumulated `speed`. XM
/// stores it as `byte / 255 ∈ [0, 1]`. `Q8_8` again.
///
/// The runtime phase accumulator (in `xmrsplayer`'s
/// `state_auto_vibrato.rs`) is integer Q.16 cycles; combined
/// with these Q-typed parameters, the auto-vibrato chain is
/// `f32`-free end-to-end.