fix(paint): give the audio-reactive painters the scenario's clock - #203
Merged
Conversation
A waveform in a scene starting at t=73 s drew the analysis at 73 s *into that scene*. 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 window falls in a silent region. Measured on the same scene, same track, same build — only its position in the scenario differs: 42 px of trace as the first scene, 0 px starting at t~73 s. PaintCtx carried no scenario-global time: `time` restarts at every scene and frame_index is documented as "frames elapsed since this scene started". So waveform, audio_spectrum and the audio-reactive binding had nothing else to read, while AudioAnalysis is indexed on the scenario's own timeline. Carry the position on the FrameTask — it is the index in the schedule, known at build time — and thread it through PaintFrame/PaintCtx and BuildAnimationCtx as `scenario_time`. Everything else stays on `time`, which is what a delay, a stagger or a preset is written against. A container's time_scale/time_offset remaps the animation clock of its subtree; the audio is not part of that subtree and passes through unremapped. The incremental encoder builds slots in isolation, so it renumbers each slot from its own start rather than taking the local Vec's length — the existing slot_tasks_reproduce_the_full_builder_exactly caught that immediately.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #201. Unblocks #202.
What
A
waveformin a scene starting at t=73 s drew the analysis at 73 s into that scene. Same scene, same track, same build — only its position in the scenario differs:PaintCtxcarried no scenario-global time:timerestarts at every scene, andframe_indexis documented as "frames elapsed since this scene started". Sowaveform,audio_spectrumand theaudio-reactivebinding had nothing else to read, whileAudioAnalysisis indexed on the scenario's own timeline. The two only agreed for a track at 0 and a scene at 0.How
FrameTaskcarriesglobal_frame— its index in the schedule, known at build time — and that becomesscenario_timeonPaintFrame/PaintCtxandBuildAnimationCtx.Deliberate boundaries:
time. A delay, a stagger, a reveal, a preset are all written against the scene. Only the three audio consumers move.time_scale/time_offsetdoes not remap it. That remaps the animation clock of a subtree; the audio plays at wall-clock speed regardless, so the scenario clock passes through untouched.render_scene_bg_scaleddid not get the parameter — the background layer paints no component.The incremental encoder builds slots in isolation, so
build_slot_frame_taskstakes the slot's start and renumbers rather than using the localVec's length.slot_tasks_reproduce_the_full_builder_exactlycaught that on the first run — exactly what it exists for.Test
a_waveform_reads_the_scenario_clock_not_the_scene_clock: 3 s of sine then 1 s of silence, behind a 2 s filler scene. At frame 105 the scenario is at 3.5 s (silence) while the scene is 1.5 s old (still sine), so the two clocks disagree by construction.Checked that it discriminates: reverting
waveform.rstoctx.timemakes it fail, restoring the fix makes it pass. My first attempt at this test passed in both states — it was worthless, and I only found that out by trying to break it.cargo test --workspacegreen,cargo fmt --checkandcargo clippy --all-targets -- -D warningsclean.