Add dynamic zoom and ripple amplitude to woods recipe
- Zoom now driven by audio energy via core:map-range - Ripple amplitude reads from dynamic_params in sexp_to_cuda - Crossfade transition with zoom in/out effect - Move git clone before COPY in Dockerfile for better caching Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -74,12 +74,12 @@ COPY --from=builder /decord-install /usr/local/lib/python3.11/dist-packages/
|
|||||||
COPY --from=builder /tmp/decord/build/libdecord.so /usr/local/lib/
|
COPY --from=builder /tmp/decord/build/libdecord.so /usr/local/lib/
|
||||||
RUN ldconfig
|
RUN ldconfig
|
||||||
|
|
||||||
# Copy application
|
# Clone effects repo (before COPY so it gets cached)
|
||||||
COPY . .
|
|
||||||
|
|
||||||
# Clone effects repo
|
|
||||||
RUN git clone https://git.rose-ash.com/art-dag/effects.git /app/artdag-effects
|
RUN git clone https://git.rose-ash.com/art-dag/effects.git /app/artdag-effects
|
||||||
|
|
||||||
|
# Copy application (this invalidates cache for any code change)
|
||||||
|
COPY . .
|
||||||
|
|
||||||
# Create cache directory
|
# Create cache directory
|
||||||
RUN mkdir -p /data/cache
|
RUN mkdir -p /data/cache
|
||||||
|
|
||||||
|
|||||||
@@ -125,8 +125,8 @@
|
|||||||
dir (get cfg :dir)
|
dir (get cfg :dir)
|
||||||
rot-max-a (get cfg :rot-a)
|
rot-max-a (get cfg :rot-a)
|
||||||
rot-max-b (get cfg :rot-b)
|
rot-max-b (get cfg :rot-b)
|
||||||
zoom-a (get cfg :zoom-a)
|
zoom-max-a (get cfg :zoom-a)
|
||||||
zoom-b (get cfg :zoom-b)
|
zoom-max-b (get cfg :zoom-b)
|
||||||
pair-angle (get pstate :angle)
|
pair-angle (get pstate :angle)
|
||||||
inv-a-on (> (get pstate :inv-a) 0)
|
inv-a-on (> (get pstate :inv-a) 0)
|
||||||
inv-b-on (> (get pstate :inv-b) 0)
|
inv-b-on (> (get pstate :inv-b) 0)
|
||||||
@@ -140,6 +140,10 @@
|
|||||||
angle-a (* dir pair-angle rot-max-a 0.01)
|
angle-a (* dir pair-angle rot-max-a 0.01)
|
||||||
angle-b (* dir pair-angle rot-max-b 0.01)
|
angle-b (* dir pair-angle rot-max-b 0.01)
|
||||||
|
|
||||||
|
;; Energy-driven zoom (maps audio energy 0-1 to 1-max)
|
||||||
|
zoom-a (core:map-range e 0 1 1 zoom-max-a)
|
||||||
|
zoom-b (core:map-range e 0 1 1 zoom-max-b)
|
||||||
|
|
||||||
;; Define effect pipelines for each source
|
;; Define effect pipelines for each source
|
||||||
;; These get compiled to single CUDA kernels!
|
;; These get compiled to single CUDA kernels!
|
||||||
effects-a [{:op "zoom" :amount zoom-a}
|
effects-a [{:op "zoom" :amount zoom-a}
|
||||||
@@ -177,10 +181,20 @@
|
|||||||
;; Process active pair with fused pipeline
|
;; Process active pair with fused pipeline
|
||||||
active-frame (process-pair-fast active)
|
active-frame (process-pair-fast active)
|
||||||
|
|
||||||
;; Crossfade during transition
|
;; Crossfade with zoom during transition
|
||||||
|
;; Old pair: zooms out (1.0 -> 2.0) and fades out
|
||||||
|
;; New pair: starts small (0.1), zooms in (-> 1.0) and fades in
|
||||||
result (if fading
|
result (if fading
|
||||||
(let [next-frame (process-pair-fast next-idx)]
|
(let [next-frame (process-pair-fast next-idx)
|
||||||
(blending:blend-images active-frame next-frame fade-amt))
|
;; Active zooms out as it fades
|
||||||
|
active-zoom (+ 1.0 fade-amt)
|
||||||
|
active-zoomed (streaming_gpu:fused-pipeline active-frame
|
||||||
|
[{:op "zoom" :amount active-zoom}])
|
||||||
|
;; Next starts small and zooms in
|
||||||
|
next-zoom (+ 0.1 (* fade-amt 0.9))
|
||||||
|
next-zoomed (streaming_gpu:fused-pipeline next-frame
|
||||||
|
[{:op "zoom" :amount next-zoom}])]
|
||||||
|
(blending:blend-images active-zoomed next-zoomed fade-amt))
|
||||||
active-frame)
|
active-frame)
|
||||||
|
|
||||||
;; Final effects pipeline (fused!)
|
;; Final effects pipeline (fused!)
|
||||||
@@ -198,4 +212,5 @@
|
|||||||
;; Apply final fused pipeline
|
;; Apply final fused pipeline
|
||||||
(streaming_gpu:fused-pipeline result final-effects
|
(streaming_gpu:fused-pipeline result final-effects
|
||||||
:rotate_angle spin-angle
|
:rotate_angle spin-angle
|
||||||
:ripple_phase (* now 5)))))
|
:ripple_phase (* now 5)
|
||||||
|
:ripple_amplitude rip-amp))))
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ def _build_params(effects: List[dict], dynamic_params: dict) -> cp.ndarray:
|
|||||||
elif op == 'zoom':
|
elif op == 'zoom':
|
||||||
params.append(float(dynamic_params.get('zoom_amount', effect.get('amount', 1.0))))
|
params.append(float(dynamic_params.get('zoom_amount', effect.get('amount', 1.0))))
|
||||||
elif op == 'ripple':
|
elif op == 'ripple':
|
||||||
params.append(float(effect.get('amplitude', 10)))
|
params.append(float(dynamic_params.get('ripple_amplitude', effect.get('amplitude', 10))))
|
||||||
params.append(float(effect.get('frequency', 8)))
|
params.append(float(effect.get('frequency', 8)))
|
||||||
params.append(float(effect.get('decay', 2)))
|
params.append(float(effect.get('decay', 2)))
|
||||||
params.append(float(dynamic_params.get('ripple_phase', effect.get('phase', 0))))
|
params.append(float(dynamic_params.get('ripple_phase', effect.get('phase', 0))))
|
||||||
|
|||||||
Reference in New Issue
Block a user