;; 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)))