;; slice-on construct - iterate over analysis times with user function ;; ;; Usage: ;; (construct slice-on :path "constructs/slice-on.sexp") ;; (def segments (slice-on beats-data ;; :init 0 ;; :reducer (fn [acc i start end] ;; {:source (nth (list video-a video-b) (mod acc 2)) ;; :effects (list) ;; :acc (inc acc)}))) ;; ;; The construct receives: ;; - First positional arg as 'analysis' (the analysis data with :times) ;; - :init as 'init' (initial accumulator value) ;; - :reducer as 'reducer' (the reducer lambda) (define-construct slice-on :params ( (analysis :type any :desc "Analysis data with :times") (init :type any :default 0 :desc "Initial accumulator value") (reducer :type any :desc "Reducer function (fn [acc i start end] ...)") ) ;; Get times from analysis data (let [times (get analysis :times) pairs (zip-pairs (cons 0 times))] ;; Use nth to get second element of reduce result (the segments list) (nth (reduce (fn [state pair] (let [acc (first state) segments (nth state 1) i (len segments) start (first pair) end (nth pair 1) ;; Call user's reducer function result (reducer acc i start end) ;; Extract new acc and build segment new-acc (get result :acc) segment (dict :source (get result :source) :start start :end end :duration (- end start) :effects (get result :effects))] (list new-acc (append segments segment)))) (list init (list)) pairs) 1)))