Implements ascii_fx_zone effect that allows applying arbitrary sexp effects to each character cell via cell_effect lambdas. Each cell is rendered as a small image that effects can operate on. Key changes: - New ascii_fx_zone effect with cell_effect parameter for per-cell transforms - Zone context (row, col, lum, sat, hue, etc.) available in cell_effect lambdas - Effects are now loaded explicitly from recipe declarations, not auto-loaded - Added effects_registry to plan for explicit effect dependency tracking - Updated effect definition syntax across all sexp effects - New run_staged.py for executing staged recipes - Example recipes demonstrating alternating rotation and blur/rgb_split patterns Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
70 lines
2.6 KiB
Common Lisp
70 lines
2.6 KiB
Common Lisp
;; ASCII with Alternating Effects - Checkerboard of blur and RGB split
|
|
;;
|
|
;; Demonstrates using existing sexp effects within cell_effect lambdas.
|
|
;; Even cells get blur, odd cells get RGB split - creating a checkerboard pattern.
|
|
|
|
(recipe "ascii_alternating_fx"
|
|
:version "1.0"
|
|
:description "ASCII art with alternating blur and RGB split effects per cell"
|
|
:encoding (:codec "libx264" :crf 20 :preset "medium" :audio-codec "aac" :fps 30)
|
|
|
|
:params (
|
|
(cols :type int :default 40 :range [20 100]
|
|
:desc "Number of character columns")
|
|
(blur_amount :type float :default 3 :range [1 10]
|
|
:desc "Blur radius for blur cells")
|
|
(rgb_offset :type int :default 3 :range [1 10]
|
|
:desc "RGB split offset for split cells")
|
|
)
|
|
|
|
;; Registry
|
|
(effect ascii_fx_zone :path "../sexp_effects/effects/ascii_fx_zone.sexp")
|
|
(analyzer energy :path "../../artdag-analyzers/energy/analyzer.py")
|
|
|
|
;; Source files
|
|
(def video (source :path "../monday.webm"))
|
|
(def audio (source :path "../dizzy.mp3"))
|
|
|
|
;; Stage 1: Analysis
|
|
(stage :analyze
|
|
:outputs [energy-data]
|
|
(def audio-clip (-> audio (segment :start 60 :duration 10)))
|
|
(def energy-data (-> audio-clip (analyze energy))))
|
|
|
|
;; Stage 2: Process - apply effect with alternating cell effects
|
|
(stage :process
|
|
:requires [:analyze]
|
|
:inputs [energy-data]
|
|
:outputs [result audio-clip]
|
|
(def clip (-> video (segment :start 0 :duration 10)))
|
|
(def audio-clip (-> audio (segment :start 60 :duration 10)))
|
|
|
|
;; Apply effect with cell_effect lambda
|
|
;; Checkerboard: (row + col) even = blur, odd = rgb_split
|
|
(def result (-> clip
|
|
(effect ascii_fx_zone
|
|
:cols cols
|
|
:char_size (bind energy-data values :range [12 24])
|
|
:color_mode "color"
|
|
:background "black"
|
|
;; Pass params to zone dict
|
|
:energy (bind energy-data values :range [0 1])
|
|
:blur_amount blur_amount
|
|
:rgb_offset rgb_offset
|
|
;; Cell effect: alternate between blur and rgb_split
|
|
;; Uses existing sexp effects - each cell is just a small frame
|
|
:cell_effect (lambda [cell zone]
|
|
(if (= (mod (+ (get zone "row") (get zone "col")) 2) 0)
|
|
;; Even cells: blur scaled by energy
|
|
(blur cell (* (get zone "blur_amount") (get zone "energy")))
|
|
;; Odd cells: rgb split scaled by energy
|
|
(rgb_split cell
|
|
(* (get zone "rgb_offset") (get zone "energy"))
|
|
0)))))))
|
|
|
|
;; Stage 3: Output
|
|
(stage :output
|
|
:requires [:process]
|
|
:inputs [result audio-clip]
|
|
(mux result audio-clip)))
|