Commit Graph
18 Commits
Author SHA1 Message Date
Brandon ThomasandClaude Opus 5.5 4b83e088eb Merge main into the playback branch (mixer recordStart moves to the end of preroll; GopCache keeps main's random-access key walk-back)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 08:30:04 -04:00
Brandon ThomasandClaude Opus 5.5 9baa34fa45 Merge M10.1–2 + M3.2/M3.11 into M7.2 (audio mixer): preferences gain audio + playback + trim groups; ROADMAP refreshed
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 02:17:12 -04:00
Brandon ThomasandClaude Opus 5.5 c42fa205cd M7.5: Audio Gain dialog (set / adjust / normalize max peak / normalize all peaks) and default audio transitions
- clip.audioGain takes mode set|adjust|normalizeMax|normalizeAll (the
  old {db, relative} form still works); peaks are measured on the
  clips' source ranges. Normalize Max Peak applies one adjustment so the
  loudest clip lands on the target; Normalize All Peaks sets each clip.
- clip.audioPeak reports the selection's peak amplitude (with gain).
- Clip > Audio Gain... (G) opens the dialog with the four options, dB
  fields and the peak amplitude; automation ids audioGain.*.
- effects.setDefaultTransition sets the default video or audio
  transition (Constant Power / Constant Gain / Exponential Fade) that
  sequence.applyAudioTransition (Cmd+Shift+D) uses.
- tests: gain modes and peaks, dialog by automation id, transition
  curves (power / amplitude preservation, end points).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 02:11:57 -04:00
Brandon ThomasandClaude Opus 5.5 14ae01885f M7.2: Audio Track Mixer and Audio Clip Mixer panels, timeline track keyframes, live recording
- Audio Track Mixer: strips for audio tracks, submixes and the Mix with
  effect/send slots (disclosure), input mapping, output assignment, pan
  knob, automation mode, M/S/R (solo safe on submixes), fader with dB
  scale and our own taper, stereo meters fed by the playing mix, value
  hot text, footer transport; horizontal/vertical scrolling. Fader and
  knob drags are mixer.touch while held and mixer.release on let go, so
  they are heard live and recorded in Latch/Touch/Write.
- Audio Clip Mixer: per-track strips for the clip under the playhead
  (clip Volume / Panner, write-keyframes toggle), clipMixer.set with one
  undo step per drag (Session::edit_merged).
- Timeline: per-track "Show Keyframes" button picks clip keyframes or a
  track lane (volume, panner, mute, sends, insert params); the lane is
  drawn across the track, Pen / Cmd-click adds, diamonds drag in time and
  value, right-click deletes.
- Playback starts an automation pass and stopping writes it; the audio
  callback reads the newest project snapshot (LiveMix), so mixer moves
  are heard while playing. Audio Meters read the graph's live meters
  instead of re-mixing at the playhead.
- Automation ids on every control; headless kittest tests drive the
  panels by id and by multi-frame drags (FILMCRAFT_UI_SNAPSHOT_DIR renders
  offscreen PNGs through wgpu).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 02:10:29 -04:00
Brandon ThomasandClaude Opus 5.5 5823e22e89 M4.6: cancel frame jobs playback no longer needs (stale in-flight jobs, prefetch after Stop)
- filmcraft_media::cancel: a per-job cancellation flag passed through a thread-local, so the
  MediaSource API is unchanged. Frame workers run each job inside it.
- FrameServer::retain_queue (called by schedule_playback every refresh) now also cancels running
  jobs for frames the playhead has passed. Before, a worker blocked on a source's decoder lock
  went on to decode its frame after playback had moved 50–100 frames on, found it evicted and
  restarted the decoder at the keyframe (decoder trace: "seek i=32 key=0 next=142").
- GopCache gives up (CodecError/MediaError::Cancelled) before seeking or decoding for a cancelled
  job and between samples; decoder state stays consistent, so the next request carries on.
- The CPU compositor checks the flag between tracks and effects; cancelled results are never
  cached.
- Stop drops queued prefetch jobs and cancels running ones (FrameServer::stop_prefetch). They
  used to run to completion after Stop, e.g. 14 frames of live effects rendering competing with
  a Render In to Out started right after.

bench, same-session A/B (GPU path, 8 s, load avg 35–41):
  after-preview Full live play (1080p + Lumetri/Sharpen/Levels/Tint, CPU-bound):
    38/154 → 98/94 shown/dropped, 297 → 267 ms CPU/frame, 84 jobs cancelled
  after-preview plays from previews, h264-1080, stack3, h264-2160: unchanged within noise

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 01:54:44 -04:00
Brandon ThomasandClaude Opus 5.5 4918555906 M10.2: graphic clips — text and shape layers in the project model, vector renderer (CPU + GPU plan), graphics.* commands
- project: ItemKind::Graphic (transparent canvas source, hidden from the Project panel,
  unlimited duration); graphic layers are hidden effect instances graphic_text /
  graphic_shape on the clip (serde for free, keyframes on every animatable property,
  Source Text holds), with appearance (fill, two strokes outer/centre/inner, background
  box with radius, drop shadow) and transform (position, anchor, scale, rotation,
  opacity); eval_layer gives a plain LayerSpec. No schema migration: all additive.
- render: graphic_clip rasterises each layer straight to the output transform (crisp at
  any Motion scale/rotation), caches layer rasters, composes a tight image for the GPU
  plan; standard effects on a graphic run at source resolution first.
- engine: graphics.newText (Cmd+T) / newShape (new clip above the footage at the playhead
  or a layer in an existing clip), setText (typing coalesces into one undo step), set,
  selectLayer, deleteLayer, arrangeLayer, align (frame / selection), distribute,
  graphics.list, fonts.list. EditorState.graphic_layers holds the layer selection.
- goldens: graphic_title, graphic_shapes (CPU and GPU parity).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 01:38:04 -04:00
Brandon ThomasandClaude Opus 5.5 6b00314e96 M7.2: audio mixer graph, track automation and mixer commands
- project: MixerStrip on every audio track, submix tracks and the Mix
  (automation mode Off/Read/Latch/Touch/Write, lanes for volume/pan/mute/
  send levels, effect-parameter automation in the insert's own keyframes,
  sends pre/post fader, output routing, record arm, solo safe, input map);
  pre/post-fader flag on inserts; serde defaults (no schema migration).
- render: mixer graph (tracks -> submixes -> Mix) in Premiere's order:
  pre-fader inserts, pre-fader sends, mute, fader, meter, post-fader
  inserts, post-fader sends, pan/balance. Per-sample automation, effect
  params on an absolute 64-sample grid (output independent of request
  cutting), route-level latency compensation, cached continuation state
  with pre-roll, solo/solo-safe logic, -3 dB constant-power pan law for
  mono tracks, balance for stereo. LiveMix carries held controls (Touch
  ramps back over the automatch time), meters and the newest project.
- engine: mixer.* commands (setStrip, setValue, touch/release,
  recordStart/recordStop, submixes, inserts, sends, track keyframes,
  writeAutomation, inspect) and the automation recorder (gesture streams
  thinned into keyframes, one undo step per pass, Switch to Touch after
  Write); Preferences > Audio (automatch time, keyframe thinning).
- tests: gain/pan law, block-boundary automation, solo/mute/solo-safe,
  sends, latency alignment, render-vs-playback identity, recorder modes,
  perf (24 tracks x EQ+Dynamics+Reverb + submix: 6.3x realtime, one core).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 01:29:49 -04:00
Brandon ThomasandClaude Opus 5.5 b141c406e9 M10.1: text engine (crates/text): font database with bundled OFL fonts and system-font discovery, harfrust shaping, bidi, line breaking, paragraph layout, glyph cache and rasteriser; captions and Timecode/Clip Name burn-ins use it
- New L1 crate filmcraft-text: fonts (bundled Inter Regular/Medium/SemiBold/Bold/Italic,
  JetBrains Mono, Noto Serif; DirectorySource scans system font folders reading only name/OS2
  tables; family/style resolution with synthetic bold/italic; per-char fallback), layout
  (harfrust kerning/ligatures, unicode-bidi, unicode-linebreak, alignment incl. justify,
  leading, tracking, baseline shift, all/small caps, underline, carets/hit-test/selection,
  cached), raster (moved from captions; active-edge list, shapes, emboldening), render
  (outline + sub-pixel glyph-mask caches; transformed-outline path for rotation/skew),
  mask (distance-transform strokes, blur).
- Captions burn-in now shapes and kerns via the engine (font.rs/raster.rs removed).
- Timecode / Clip Name effects draw real text (full clip names, not seven-segment digits);
  text_burnin golden re-blessed.
- UI takes its font bytes from the text crate (no duplicate copies in the binary).
- New fonts: Inter Bold, Inter Italic (OFL-1.1, rsms/inter v4.1), Noto Serif Regular
  (OFL-1.1, notofonts) with sidecars, ATTRIBUTION.md rows and licence text.
- Perf: 3-line 96 px title at 1080p ~1.6 ms cold / 0.15 ms warm (release).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 01:22:30 -04:00
Brandon Thomas 9e54812b2a Merge branch 'worktree-agent-ae361fad8d71a0eef'
# Conflicts:
#	crates/engine/src/commands.rs
#	crates/export/src/lib.rs
#	crates/ui-egui/src/frames.rs
#	crates/ui-egui/src/state.rs
2026-10-01 00:08:58 -04:00
Brandon ThomasandClaude Opus 5.5 5c5a10e1b9 M4.5: render bar painted from preview segments (green/yellow/red, merged spans, hover text, automation ids timeline.renderBar.N); playback, Program monitor (CPU and GPU plan paths), audio output and meters read render previews where valid; status-bar job progress with cancel (status.job.cancel); play after rendering previews; previews pre-opened when rendered. Measured on 1080p H.264 + Lumetri/Sharpen/Levels/Tint, 8 s at Full res: 189–191 of ~192 frames dropped before render, 0–1 dropped after (25–46 on the first play right after the render)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:06:38 -04:00
Brandon ThomasandClaude Opus 5.5 9eb12c0043 M10.4: caption commands in the engine (captions.* — tracks, add at playhead, split/merge/trim/move/delete, text/speaker/timing, style, next/previous, show/hide, list), file.import detects .srt/.vtt/.scc into a new caption track, File ▸ Export ▸ Captions… (SRT/VTT/SCC), Clear/Ripple Delete on selected captions; caption overlays in render + GPU frame plans; burn-in on export (ffmpeg-oracle test)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:06:29 -04:00
Brandon ThomasandClaude Opus 5.5 740fcd95cb M4.5: render-bar segments + render previews in the engine — segments cut at every video edit point, 128-bit content hash relative to the segment start (clips, sources, effects + keyframes, transitions, sequence settings; stable across save/load and ripple moves), measured yellow/red cost estimate; content-addressed ProRes preview cache per project (temp folder until first save), Render Effects In to Out (Enter), Render In to Out, Render Selection, Render Audio (float WAV previews mixed into playback), Delete Render Files (In to Out), sequence.renderBar query; renders run as cancellable jobs on the export pipeline
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 23:43:26 -04:00
Brandon ThomasandClaude Opus 5.5 dc9e3933a8 M7.3: clip audio effects run on filmcraft-audio-dsp (Amplify, Dynamics, Hard Limiter, Delay, Parametric EQ, High/Low/Bandpass, DeNoise, DeHummer, Studio Reverb, Invert, Pitch Shifter) with keyframed params, latency compensation and a continuation cache with pre-roll for random access
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 11:40:58 -04:00
Brandon ThomasandClaude Opus 5.5 581e31b432 M0.12: xtask layers/wasm/ci gates (layer table, same-layer allow-list, UI crates barred below L5); cargo alias
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:02:36 -04:00
Brandon ThomasandClaude Opus 5.5 3dff6e78e2 M8: Lumetri curves, hue curves, colour wheels, looks, HSL secondary (render + panel UI); Color workspace layout
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 09:35:22 -04:00
Brandon ThomasandClaude Opus 5.5 b7b7042b87 M5.8: wgpu compositor — frame plans (render crate), YUV/RGB layer sampling with footprint supersampling in WGSL, linear-light premultiplied compositing, upload cache; Program monitor composites on the GPU (FILMCRAFT_CPU_COMPOSITE=1 to disable)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 07:16:32 -04:00
Brandon ThomasandClaude Opus 5.5 5881842a2e M4: LUT-based linear conversion and linear-light box decimation for reduced-resolution playback
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 06:45:35 -04:00
Brandon ThomasandClaude Opus 5.5 8d83799cc0 M0.3–M0.8: geom, color, frame, media generators, project model, edit algebra, CPU renderer
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 05:58:41 -04:00