Files
rose-ash/artdag/test/templates/stream-process-pair.sexp
giles 1a74d811f7
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m33s
Incorporate art-dag-mono repo into artdag/ subfolder
Merges full history from art-dag/mono.git into the monorepo
under the artdag/ directory. Contains: core (DAG engine),
l1 (Celery rendering server), l2 (ActivityPub registry),
common (shared templates/middleware), client (CLI), test (e2e).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

git-subtree-dir: artdag
git-subtree-mainline: 1a179de547
git-subtree-split: 4c2e716558
2026-02-27 09:07:23 +00:00

73 lines
2.6 KiB
Common Lisp

;; stream-process-pair template (streaming-compatible)
;;
;; Macro for processing a video source pair with full effects.
;; Reads source, applies A/B effects (rotate, zoom, invert, hue), blends,
;; and applies pair-level rotation.
;;
;; Required context (must be defined in calling scope):
;; - sources: array of video sources
;; - pair-configs: array of {:dir :rot-a :rot-b :zoom-a :zoom-b} configs
;; - pair-states: array from (bind pairs :states)
;; - now: current time (t)
;; - e: audio energy (0-1)
;;
;; Required effects (must be loaded):
;; - rotate, zoom, invert, hue_shift, blend
;;
;; Usage:
;; (include :path "../templates/stream-process-pair.sexp")
;; ...in frame pipeline...
;; (let [pair-states (bind pairs :states)
;; now t
;; e (streaming:audio-energy music now)]
;; (process-pair 0)) ;; process source at index 0
(require-primitives "core")
(defmacro process-pair (src-idx)
(let [src (nth sources src-idx)
frame (streaming:source-read src now)
cfg (nth pair-configs src-idx)
state (nth pair-states src-idx)
;; Get state values (invert uses countdown > 0)
inv-a-active (if (> (get state :inv-a) 0) 1 0)
inv-b-active (if (> (get state :inv-b) 0) 1 0)
;; Hue is active only when countdown > 0
hue-a-val (if (> (get state :hue-a) 0) (get state :hue-a-val) 0)
hue-b-val (if (> (get state :hue-b) 0) (get state :hue-b-val) 0)
mix-opacity (get state :mix)
pair-rot-angle (* (get state :angle) (get cfg :dir))
;; Get config values for energy-mapped ranges
rot-a-max (get cfg :rot-a)
rot-b-max (get cfg :rot-b)
zoom-a-max (get cfg :zoom-a)
zoom-b-max (get cfg :zoom-b)
;; Energy-driven rotation and zoom
rot-a (core:map-range e 0 1 0 rot-a-max)
rot-b (core:map-range e 0 1 0 rot-b-max)
zoom-a (core:map-range e 0 1 1 zoom-a-max)
zoom-b (core:map-range e 0 1 1 zoom-b-max)
;; Apply effects to clip A
clip-a (-> frame
(rotate :angle rot-a)
(zoom :amount zoom-a)
(invert :amount inv-a-active)
(hue_shift :degrees hue-a-val))
;; Apply effects to clip B
clip-b (-> frame
(rotate :angle rot-b)
(zoom :amount zoom-b)
(invert :amount inv-b-active)
(hue_shift :degrees hue-b-val))
;; Blend A+B
blended (blend clip-a clip-b :opacity mix-opacity)]
;; Apply pair-level rotation
(rotate blended :angle pair-rot-angle)))