Skip to content

Audio-reactive components read scene-local time against a scenario-time analysis #201

Description

@LeadcodeDev

Symptom

A waveform in a scene that starts at t=73 s draws the analysis at 73 s into the scene, not into the scenario. With a uniform track nobody notices; with any track whose level varies over the timeline the visualisation is simply wrong, and it goes flat when the scene's own local window falls in a silent region of the analysis.

Evidence

Same scene, same track, same build — only the scene's position in the scenario differs:

scene position trace height
first scene (local ≈ scenario time) 42 px
starting at t≈73 s in the full scenario 0 px (flat)

Cause

PaintCtx carries no scenario-global time:

pub struct PaintFrame {
    pub time: f64,        // scene time
    pub frame_index: u32, // "frames elapsed since this scene started"
    ...
}

waveform.rs and audio_spectrum.rs call analysis.amplitude_at(ctx.time), and the audio-reactive binding in box_builder.rs calls amplitude_smoothed(actx.time, …) — all scene-local. AudioAnalysis is indexed from the file's own start, i.e. scenario time once track.start is applied (#190/#198).

So the two only agree for a track placed at 0 and a scene starting at 0.

Why it stayed hidden

The analysis was uniform enough that any offset looked plausible: a periodic track shows peaks whatever the phase. I "verified" the alignment earlier by observing peaks, which proves nothing about the offset — the test above is the one that discriminates.

Proposed fix

Thread scenario time into the paint context:

  1. Add scenario_time: f64 (or a global frame index) to PaintFrame/PaintCtx. The FrameTask layer already knows it — tasks are a flat list over the whole render.
  2. Use it in waveform, audio_spectrum and the audio-reactive binding; every other consumer keeps time (scene-local), which is correct for animation progress.
  3. Define it for world views as the view timeline's own time, which is what WorldTimeline already computes.

A test asserting that the same scene renders the same waveform whether it is first or last in the scenario pins the property; that is the discriminating case above.

Blocks

The switch to a mix-following analysis (option A on #190's open question) is implemented but cannot land before this: it makes level variation visible, so the misalignment stops being harmless and turns into a flat trace.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions