pub struct MilkEngine {Show 15 fields
renderer: MilkRenderer,
current: PresetSlot,
fading_out: Option<PresetSlot>,
transition: Option<TransitionState>,
audio_analyzer: AudioAnalyzer,
beat_detector: BeatDetector,
config: EngineConfig,
fft: FFTAnalyzer,
spectrum_bins: Vec<f32>,
last_profile: Option<FrameProfile>,
baseline_mesh: (u32, u32),
mpris: Option<MprisPoller>,
sprites: SpriteManager,
messages: MessageManager,
mpris_last_title: Option<String>,
}Expand description
Main Milkdrop visualization engine.
Fields§
§renderer: MilkRendererRenderer
current: PresetSlotActive preset bundle: preset + evaluator + warp executor + state + compiled wave/shape equations.
fading_out: Option<PresetSlot>Outgoing preset’s bundle, alive only between a load_preset call
and the moment the configured transition duration elapses. Driven
each frame in lock-step with current so its warp / wave / shape
outputs land on the renderer’s secondary chain for the blend pass.
transition: Option<TransitionState>Delta-time tracker for the in-flight transition. None outside
transitions. Cleared in the same frame as fading_out once it
reaches the configured duration.
audio_analyzer: AudioAnalyzerAudio analyzer
beat_detector: BeatDetectorBeat detector for automatic preset changes
config: EngineConfigEngine configuration
fft: FFTAnalyzerFrequency-domain analyzer feeding value1/value2 for
wavecode_N blocks with b_spectrum = 1. Always populated each
frame so the per-point loop pays no cost when no preset is active.
spectrum_bins: Vec<f32>Spectrum magnitudes (size SPECTRUM_FFT_SIZE / 2) of the most
recent audio buffer. Reused across waves within a frame.
last_profile: Option<FrameProfile>Wall-clock breakdown of the most recent update call. None when
EngineConfig::profile is false (default). The bench tool flips
it on; production builds leave it off to save the Instant::now
reads (Instant::elapsed measured at ~20 ns × 9 phases = ~180 ns,
negligible but trivially avoidable).
baseline_mesh: (u32, u32)User-configured baseline warp mesh size, captured at engine
init. The MD1 per-pixel auto-upgrade (md1_mesh_override)
densifies the mesh for MD1 presets; loading an MD2+ preset
reverts to this baseline so the user’s mesh-quality choice
stays honoured on the common case. Manual set_mesh_size
calls (e.g., GUI quality slider) update this baseline too.
mpris: Option<MprisPoller>MPRIS2 progress reader, when EngineConfig::progress_source
requests it and the mpris feature is enabled. None means
progress falls back to the local-window computation each
frame (the historical behaviour).
sprites: SpriteManagerSprite (MILK_IMG.INI) manager: holds the parsed defs, the
active sprite list, and runs per-frame equations against each
active sprite’s own evaluator. The result list is forwarded to
the renderer’s update_sprites each frame.
messages: MessageManagerMessage (MILK_MSG.INI) overlay manager. Drives the text
pipeline + the MPRIS auto-title path: when the MPRIS poller
reports a new track title, the engine spawns a transient
“Now playing — …” message.
mpris_last_title: Option<String>Last MPRIS title observed — used to suppress duplicate
show_transient spawns on idle polls that report the same
metadata. None until the first non-empty title is seen.
Implementations§
Source§impl MilkEngine
impl MilkEngine
Sourcepub async fn new(config: EngineConfig) -> Result<Self>
pub async fn new(config: EngineConfig) -> Result<Self>
Create a new engine.
Sourcepub fn from_device(
device: Arc<Device>,
queue: Arc<Queue>,
config: EngineConfig,
) -> Result<Self>
pub fn from_device( device: Arc<Device>, queue: Arc<Queue>, config: EngineConfig, ) -> Result<Self>
Create an engine from an existing device and queue. This is useful when sharing a GPU context with a GUI.
Sourcefn from_renderer(renderer: MilkRenderer, config: EngineConfig) -> Result<Self>
fn from_renderer(renderer: MilkRenderer, config: EngineConfig) -> Result<Self>
Create an engine from an existing renderer.
Sourcefn autoload_overlay_inis(&mut self, dir: &Path)
fn autoload_overlay_inis(&mut self, dir: &Path)
Look for MILK_IMG.INI and MILK_MSG.INI siblings of a preset
file and load them into the sprite + message managers.
Best-effort: missing / unparseable files log a warning and
leave the previous load untouched.
Sourcepub fn load_default_preset(&mut self) -> Result<()>
pub fn load_default_preset(&mut self) -> Result<()>
Load the default preset. This is useful as a fallback when no preset is available or loading fails.
Sourcepub fn load_preset_from_data(&mut self, preset: MilkPreset) -> Result<()>
pub fn load_preset_from_data(&mut self, preset: MilkPreset) -> Result<()>
Load a preset from parsed data.
When config.transition_duration_s > 0 and a preset is already
loaded, archives the current slot into fading_out, asks the
renderer to allocate a secondary chain for it, and starts the
transition timer. The next update() will tick both slots and
drive the renderer’s blend pass through the eased crossfade.
Sourcefn compile_phase(
evaluator: &mut MilkEvaluator,
equations: &[String],
) -> Vec<Node>
fn compile_phase( evaluator: &mut MilkEvaluator, equations: &[String], ) -> Vec<Node>
Compile a single equation-phase batch, logging individual failures and returning the surviving Nodes. Public-by-convention for testability inside the module.
Sourcefn init_evaluator_from_preset(&mut self, preset: &MilkPreset)
fn init_evaluator_from_preset(&mut self, preset: &MilkPreset)
Initialize evaluator context from preset parameters.
Sourcepub fn update(
&mut self,
audio_samples: &[f32],
delta_time: f32,
) -> Result<Option<PresetChange>>
pub fn update( &mut self, audio_samples: &[f32], delta_time: f32, ) -> Result<Option<PresetChange>>
Update engine with mono audio + render a frame. Convenience
wrapper around Self::update_stereo that feeds the same buffer
for both channels — handy for callers that only have a downmixed
stream (CLI render path, test fixtures, headless smoke tests).
Custom waves’ value2 will mirror value1; real stereo content
requires Self::update_stereo.
Returns Some(PresetChange) if beat detection triggered a preset
change.
Sourcepub fn update_stereo(
&mut self,
left: &[f32],
right: &[f32],
delta_time: f32,
) -> Result<Option<PresetChange>>
pub fn update_stereo( &mut self, left: &[f32], right: &[f32], delta_time: f32, ) -> Result<Option<PresetChange>>
Update engine with split L/R audio + render a frame. The two
buffers must be the same length; MD2 custom waves’
value1 reads from left, value2 from right. Audio
analysis (band levels, beat detection, FFT spectrum) runs on a
downmix of the two channels — the perceptual loudness those
metrics report is the listener’s, not one channel’s.
delta_time is in seconds; the engine multiplies it into every
per-frame time step.
Sourcepub fn last_profile(&self) -> Option<&FrameProfile>
pub fn last_profile(&self) -> Option<&FrameProfile>
Per-phase wall-clock breakdown of the most recent update call.
Returns None unless EngineConfig::profile was set. Cleared on
engine reset.
Sourcepub fn transition_progress(&self) -> Option<f32>
pub fn transition_progress(&self) -> Option<f32>
Return the current transition’s eased progress in [0, 1], or
None when no transition is in flight. Useful for HUD overlays
and tests.
Sourcepub fn is_transitioning(&self) -> bool
pub fn is_transitioning(&self) -> bool
true while a preset transition is animating. Equivalent to
transition_progress().is_some().
Sourcefn update_spectrum(&mut self, audio_samples: &[f32])
fn update_spectrum(&mut self, audio_samples: &[f32])
Refresh the FFT magnitude spectrum from the current audio frame.
Used by b_spectrum = 1 wavecode_N blocks to populate
value1/value2. Always runs (even with no preset loaded) so
the buffer stays warm across preset hops.
Sourcepub fn render_texture(&self) -> &Texture
pub fn render_texture(&self) -> &Texture
Get the current render texture.
Sourcepub fn state(&self) -> &RenderState
pub fn state(&self) -> &RenderState
Get current state.
Sourcepub fn current_preset(&self) -> Option<&MilkPreset>
pub fn current_preset(&self) -> Option<&MilkPreset>
Get current preset.
Sourcepub fn q_snapshot(&self) -> [f32; 32]
pub fn q_snapshot(&self) -> [f32; 32]
Snapshot of q1..q32 after the most recent update.
Returned as f32 so a future GPU pipeline can copy it directly into a
q: array<vec4<f32>, 8> uniform (MilkDrop 2’s standard q-channel
layout). The CPU-side bridge — per-frame eqs write q1..q32,
per-vertex eqs read them, identical state restored across vertices —
is already in place via WarpExecutor; this getter is the GPU-side
hand-off point for upcoming comp/warp user shaders (sprint B).
Sourcepub fn beat_detector(&self) -> &BeatDetector
pub fn beat_detector(&self) -> &BeatDetector
Get the beat detector.
Sourcepub fn beat_detector_mut(&mut self) -> &mut BeatDetector
pub fn beat_detector_mut(&mut self) -> &mut BeatDetector
Get the beat detector mutably.
Sourcepub fn set_beat_detection_mode(&mut self, mode: BeatDetectionMode)
pub fn set_beat_detection_mode(&mut self, mode: BeatDetectionMode)
Set beat detection mode.
Sourcepub fn next_beat_detection_mode(&mut self)
pub fn next_beat_detection_mode(&mut self)
Toggle beat detection to next mode.
Sourcepub fn enable_beat_detection(&mut self)
pub fn enable_beat_detection(&mut self)
Enable beat detection.
Sourcepub fn disable_beat_detection(&mut self)
pub fn disable_beat_detection(&mut self)
Disable beat detection.
Sourcepub fn load_sprite_defs(&mut self, defs: Vec<SpriteDef>, dir: &Path)
pub fn load_sprite_defs(&mut self, defs: Vec<SpriteDef>, dir: &Path)
Load a set of parsed MILK_IMG.INI sprite definitions and pre-
resolve their image files against dir. Missing files fall
back to a 1×1 transparent texture inside the renderer’s sprite
pool — the engine’s texture_index mapping stays dense.
Sourcepub fn spawn_sprite_slot(&mut self, slot: u32) -> bool
pub fn spawn_sprite_slot(&mut self, slot: u32) -> bool
Spawn the sprite at INI slot slot (1-based, matching the
[img01] section header). Returns false if no def is
loaded for that slot. Multiple spawns of the same slot stack
— that matches MD2 + lets K-hammering build up effects.
Sourcepub fn cycle_next_sprite(&mut self) -> Option<u32>
pub fn cycle_next_sprite(&mut self) -> Option<u32>
Cycle to the next sprite slot (K keybind). Returns the slot
that was spawned (or None if no sprites are loaded).
Sourcepub fn spawn_random_sprite(&mut self, seed: u64) -> Option<u32>
pub fn spawn_random_sprite(&mut self, seed: u64) -> Option<u32>
Spawn a random sprite (Shift+K keybind). The caller supplies
the RNG seed (typically state.frame as u64 ^ time bits) so
tests stay deterministic.
Sourcepub fn clear_sprites(&mut self)
pub fn clear_sprites(&mut self)
Drop every active sprite (Ctrl+T keybind).
Sourcepub fn pop_most_recent_sprite(&mut self) -> bool
pub fn pop_most_recent_sprite(&mut self) -> bool
Remove the most recently spawned sprite (Delete keybind).
Returns true when something was popped — the GUI suppresses
the keystroke on an empty list.
Sourcepub fn sprite_def_count(&self) -> usize
pub fn sprite_def_count(&self) -> usize
Number of loaded sprite definitions (size of the texture pool).
Sourcepub fn sprite_active_count(&self) -> usize
pub fn sprite_active_count(&self) -> usize
Number of sprites being drawn this frame.
Sourcepub fn load_message_defs(&mut self, defs: Vec<MessageDef>)
pub fn load_message_defs(&mut self, defs: Vec<MessageDef>)
Load a set of parsed MILK_MSG.INI message definitions.
Replaces the previous load.
Sourcepub fn spawn_message_slot(&mut self, slot: u32) -> bool
pub fn spawn_message_slot(&mut self, slot: u32) -> bool
Spawn the message at INI slot slot. Returns false if no
def matches that slot.
Sourcepub fn cycle_next_message(&mut self) -> Option<u32>
pub fn cycle_next_message(&mut self) -> Option<u32>
Cycle through the loaded message slots (T keybind). Returns
the slot that was spawned, or None if no messages are
loaded.
Sourcepub fn clear_messages(&mut self)
pub fn clear_messages(&mut self)
Drop every active message (Ctrl+Y keybind).
Sourcepub fn show_transient_message(&mut self, text: impl Into<String>)
pub fn show_transient_message(&mut self, text: impl Into<String>)
Show an ad-hoc transient message. Used by the MPRIS-driven auto-title path; surfaced publicly so the GUI can post its own transient toasts (“preset loaded”, “audio source: …”, …).
pub fn message_def_count(&self) -> usize
pub fn message_active_count(&self) -> usize
Sourcepub fn renderer(&self) -> &MilkRenderer
pub fn renderer(&self) -> &MilkRenderer
Get a reference to the renderer.
Sourcepub fn renderer_mut(&mut self) -> &mut MilkRenderer
pub fn renderer_mut(&mut self) -> &mut MilkRenderer
Get a mutable reference to the renderer.
Sourcepub fn config(&self) -> &EngineConfig
pub fn config(&self) -> &EngineConfig
Borrow the engine config — used by the GUI’s Options panel to reflect current values in widgets at startup.
Sourcepub fn config_mut(&mut self) -> &mut EngineConfig
pub fn config_mut(&mut self) -> &mut EngineConfig
Mutate hot-toggleable config fields (enable_per_frame,
transition_duration_s, profile). The GUI’s Options panel
calls this when the user moves a widget. Fields that aren’t
safely hot-swappable (render_config, sample_rate) should not
be poked here — change them via dedicated APIs that handle
the side effects (pipeline rebuild, audio stream restart).
Sourcefn track_progress_override(&self) -> Option<f32>
fn track_progress_override(&self) -> Option<f32>
Resolve the MD2 progress override for the current frame.
Returns Some(p) when EngineConfig::progress_source is
ProgressSource::MprisAutoTrack, the mpris feature is
enabled, and an MPRIS player is reachable with a non-zero
mpris:length. Returns None otherwise so the slot tick
falls back to the local-window computation.
Sourcepub fn mpris_snapshot(&self) -> Option<MprisSnapshot>
pub fn mpris_snapshot(&self) -> Option<MprisSnapshot>
Current MPRIS snapshot, when the mpris feature is enabled and
a poller is active. Exposed so a HUD/overlay can render the
track title without opening its own D-Bus connection.
Auto Trait Implementations§
impl Freeze for MilkEngine
impl !RefUnwindSafe for MilkEngine
impl Send for MilkEngine
impl Sync for MilkEngine
impl Unpin for MilkEngine
impl !UnwindSafe for MilkEngine
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more