pub struct MilkRuntime { /* private fields */ }Expand description
One loaded bundle’s live state: the VM’s arena and the resolved indices.
Built at preset load, borrowed mutably per frame, and never resized while a preset renders — the whole real-time claim.
Implementations§
Source§impl MilkRuntime
impl MilkRuntime
Sourcepub fn new(bundle: MilkBundle, salt: u32) -> Self
pub fn new(bundle: MilkBundle, salt: u32) -> Self
Build a runtime for bundle, resolving every index and running
per_frame_init once.
salt is the preset’s (ADR-0051): the pinned twin on every capture path
and the live one in the app, so a bundle using rand() is reproducible in
the harness and varied in the app.
Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Reset to the state a freshly-loaded preset is in: registers and arenas
zeroed, RNG back at its seed, frame counter at zero, per_frame_init run
once.
What makes a capture reproducible. The harness rebuilds a preset from
the top, and everything the previous run left — a megabuf a program
filled, an RNG stream it advanced — has to go with it (NFR §6).
Sourcepub fn has_per_vertex(&self) -> bool
pub fn has_per_vertex(&self) -> bool
Whether this bundle has a per-vertex program at all. A bundle without one drives the mesh from its per-frame outputs alone, which is a perfectly good MilkDrop preset.
Sourcepub fn run_frame(
&mut self,
frame: &AnalysisFrame,
time: f32,
dt: f32,
mesh: (u32, u32),
aspect: f32,
) -> ([f32; 9], FrameOutputs)
pub fn run_frame( &mut self, frame: &AnalysisFrame, time: f32, dt: f32, mesh: (u32, u32), aspect: f32, ) -> ([f32; 9], FrameOutputs)
Run per_frame for this frame and return the whole-mesh outputs, already
converted from MilkDrop’s per-frame rates to this engine’s per-second ones
(module docs).
Returns (outputs, decay), positionally with OUTPUT_NAMES. decay is
None when the program never names it, so the scene keeps its own default
rather than being handed a zero.
Sourcepub fn wave_count(&self) -> usize
pub fn wave_count(&self) -> usize
How many custom waves this bundle carries.
Sourcepub fn wave_spec(&self, index: usize) -> Option<ElementSpec>
pub fn wave_spec(&self, index: usize) -> Option<ElementSpec>
The structural numbers of custom wave index — how many points it draws
and how it strokes them.
Sourcepub fn shape_spec(&self, index: usize) -> Option<ElementSpec>
pub fn shape_spec(&self, index: usize) -> Option<ElementSpec>
The structural numbers of custom shape index.
Sourcepub fn shape_count(&self) -> usize
pub fn shape_count(&self) -> usize
How many custom shapes this bundle carries.
Sourcepub fn run_wave_point(
&mut self,
index: usize,
sample: f32,
value: f32,
) -> Option<WavePoint>
pub fn run_wave_point( &mut self, index: usize, sample: f32, value: f32, ) -> Option<WavePoint>
Run custom wave index’s per-point program for the point at sample
(0..1 along the wave) with value1/value2 bound to the audio there,
and return where it put the point.
value1 and value2 are MilkDrop’s left and right channel samples. This
engine’s analysis is mono by construction — the ring carries
interleaved PCM and the analyzer averages the channels before anything
else touches them (dsp::Analyzer::push_interleaved) — so the two are the
same number here. A preset that draws value1 against value2 as a
Lissajous figure therefore draws a diagonal line rather than a blob, which
is a real and stated fidelity loss rather than a bug.
Sourcepub fn run_wave_frame(&mut self, index: usize) -> Option<()>
pub fn run_wave_frame(&mut self, index: usize) -> Option<()>
Run custom wave index’s per-frame program, once, before its points.
Sourcepub fn run_shape_instance(
&mut self,
index: usize,
instance: u32,
) -> Option<ShapeInstance>
pub fn run_shape_instance( &mut self, index: usize, instance: u32, ) -> Option<ShapeInstance>
Run custom shape index’s per-frame program for one instance and return
where it put that copy.
Sourcepub fn run_vertex(&mut self, x: f32, y: f32) -> [f32; 9]
pub fn run_vertex(&mut self, x: f32, y: f32) -> [f32; 9]
Run per_vertex for the vertex at uv (x, y) — y = 0 at the top,
which is the reference’s own convention — and return its nine outputs,
converted like the per-frame ones.
rad and ang are computed here rather than taken, and deliberately:
MilkDrop normalizes them differently from this engine’s native
[per_vertex] vocabulary, and a converted preset has to get MilkDrop’s.
The reference takes rad = |(x_ndc * aspectx, y_ndc * aspecty)| with the
longer axis scaled to 1, so rad reaches 1.0 at the middle of the
left and right edges of a wide frame; the native rad
(warp_mesh::vertex_position)
reaches 1.0 at the top and bottom instead. The two differ by a factor of
the aspect, which on a 16:9 display is 1.78 — enough that a preset written
as zoom = 1 + rad * 0.1 would be most of a stop out. ang is the
reference’s atan2 in -pi..pi, not the native 0..tau.
Restores the per-frame register state first, so a write inside the program does not leak into the next vertex — MilkDrop’s semantics, and the reason two adjacent vertices of an identical program give identical answers.
Sourcepub fn shader_bands(&self) -> [f32; 8]
pub fn shader_bands(&self) -> [f32; 8]
bass, mid, treb, vol then their attenuated four, MilkDrop-scaled.
vol is the mean of the three — this engine’s analysis has no separate
loudness, and the mean behaves the way presets use vol.
Sourcepub fn rand_frame(&self) -> [f32; 4]
pub fn rand_frame(&self) -> [f32; 4]
This frame’s rand_frame vector — four uniform randoms, fresh per frame,
a pure function of the salt and the frame index.
Sourcepub fn rand_preset(&self) -> [f32; 4]
pub fn rand_preset(&self) -> [f32; 4]
The preset-lifetime rand_preset vector, fixed at load from the salt.
Sourcepub fn frame_index(&self) -> u32
pub fn frame_index(&self) -> u32
The frame counter, for the shader’s frame.