MilkEngine

Struct MilkEngine 

Source
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: MilkRenderer

Renderer

§current: PresetSlot

Active 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: AudioAnalyzer

Audio analyzer

§beat_detector: BeatDetector

Beat detector for automatic preset changes

§config: EngineConfig

Engine configuration

§fft: FFTAnalyzer

Frequency-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: SpriteManager

Sprite (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: MessageManager

Message (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

Source

pub async fn new(config: EngineConfig) -> Result<Self>

Create a new engine.

Source

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.

Source

fn from_renderer(renderer: MilkRenderer, config: EngineConfig) -> Result<Self>

Create an engine from an existing renderer.

Source

pub fn load_preset<P: AsRef<Path>>(&mut self, path: P) -> Result<()>

Load a preset from file.

Source

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.

Source

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.

Source

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.

Source

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.

Source

fn init_evaluator_from_preset(&mut self, preset: &MilkPreset)

Initialize evaluator context from preset parameters.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn is_transitioning(&self) -> bool

true while a preset transition is animating. Equivalent to transition_progress().is_some().

Source

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.

Source

pub fn render_texture(&self) -> &Texture

Get the current render texture.

Source

pub fn state(&self) -> &RenderState

Get current state.

Source

pub fn current_preset(&self) -> Option<&MilkPreset>

Get current preset.

Source

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).

Source

pub fn beat_detector(&self) -> &BeatDetector

Get the beat detector.

Source

pub fn beat_detector_mut(&mut self) -> &mut BeatDetector

Get the beat detector mutably.

Source

pub fn set_beat_detection_mode(&mut self, mode: BeatDetectionMode)

Set beat detection mode.

Source

pub fn next_beat_detection_mode(&mut self)

Toggle beat detection to next mode.

Source

pub fn enable_beat_detection(&mut self)

Enable beat detection.

Source

pub fn disable_beat_detection(&mut self)

Disable beat detection.

Source

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.

Source

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.

Source

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).

Source

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.

Source

pub fn clear_sprites(&mut self)

Drop every active sprite (Ctrl+T keybind).

Source

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.

Source

pub fn sprite_def_count(&self) -> usize

Number of loaded sprite definitions (size of the texture pool).

Source

pub fn sprite_active_count(&self) -> usize

Number of sprites being drawn this frame.

Source

pub fn load_message_defs(&mut self, defs: Vec<MessageDef>)

Load a set of parsed MILK_MSG.INI message definitions. Replaces the previous load.

Source

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.

Source

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.

Source

pub fn clear_messages(&mut self)

Drop every active message (Ctrl+Y keybind).

Source

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: …”, …).

Source

pub fn message_def_count(&self) -> usize

Source

pub fn message_active_count(&self) -> usize

Source

pub fn renderer(&self) -> &MilkRenderer

Get a reference to the renderer.

Source

pub fn renderer_mut(&mut self) -> &mut MilkRenderer

Get a mutable reference to the renderer.

Source

pub fn config(&self) -> &EngineConfig

Borrow the engine config — used by the GUI’s Options panel to reflect current values in widgets at startup.

Source

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).

Source

pub fn reset(&mut self)

Reset engine state.

Source

pub fn resize(&mut self, width: u32, height: u32)

Resize the renderer.

Source

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.

Source

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§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Downcast<T> for T

§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<S> FromSample<S> for S

§

fn from_sample_(s: S) -> S

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Upcast<T> for T

§

fn upcast(&self) -> Option<&T>

§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

§

impl<T> WasmNotSend for T
where T: Send,

§

impl<T> WasmNotSendSync for T
where T: WasmNotSend + WasmNotSync,

§

impl<T> WasmNotSync for T
where T: Sync,