annotate clojure/com/aurellem/run/final_cut.clj @ 604:c8cda378e1a0

fixed flaw in advanced move recording.
author Robert McIntyre <rlm@mit.edu>
date Sun, 02 Sep 2012 10:34:14 -0500
parents bc2858781507
children 54644b08da1a
rev   line source
rlm@530 1 (ns com.aurellem.run.final-cut
rlm@530 2 (:use (com.aurellem.gb saves gb-driver util constants
rlm@530 3 items vbm characters money
rlm@530 4 rlm-assembly))
rlm@530 5 (:use (com.aurellem.run util sound music title save-corruption
rlm@530 6 bootstrap-0 bootstrap-1
rlm@530 7 ram-display
rlm@530 8 ))
rlm@530 9 (:require clojure.string)
rlm@530 10 (:import [com.aurellem.gb.gb_driver SaveState])
rlm@530 11 (:import java.awt.image.BufferedImage)
rlm@530 12 (:import java.io.File)
rlm@530 13 (:import com.aurellem.gb.WaveWriter))
rlm@530 14
rlm@530 15
rlm@542 16 (def render-dir (File. user-home "proj/vba-clojure/render/test"))
rlm@530 17
rlm@544 18
rlm@530 19 (defn render-files!
rlm@599 20 ([^File target-dir
rlm@599 21 moves-render-fn
rlm@599 22 render-ram-map?
rlm@599 23 initial-state
rlm@601 24 moves]
rlm@604 25 (write-moves-to-file! moves (File. target-dir "rlm-yellow-hack.vbm"))
rlm@530 26 (let [ram-map-dir (File. target-dir "ram-map")
rlm@530 27 frames-dir (File. target-dir "frames")
rlm@546 28 moves-dir (File. target-dir "moves")
rlm@530 29 audio-file (File. target-dir "audio.wav")
rlm@533 30 _ (.mkdir target-dir)
rlm@601 31 _ (if render-ram-map? (.mkdir ram-map-dir))
rlm@533 32 _ (.mkdir frames-dir)
rlm@546 33 _ (.mkdir moves-dir)
rlm@530 34 wave-writer (WaveWriter. audio-file)
rlm@544 35 moves (vec moves)
rlm@544 36 desired-fps 60
rlm@547 37 seconds-per-frame (/ 1.0 desired-fps)]
rlm@530 38 (set-state! initial-state)
rlm@544 39 ;; clear sound buffer
rlm@544 40 (sound-bytes)
rlm@544 41 (try
rlm@544 42 (dorun
rlm@544 43 (reduce
rlm@544 44 (fn [[total-audio-samples
rlm@544 45 total-video-samples] move]
rlm@544 46 (run-moves @current-state (vector move))
rlm@544 47 (let [sound (sound-bytes)
rlm@544 48 total-audio-samples (+ total-audio-samples
rlm@544 49 (count sound))
rlm@544 50 total-audio-time
rlm@544 51 (*
rlm@544 52 (/ total-audio-samples 4)
rlm@544 53 (/ 44100))
rlm@544 54
rlm@544 55 total-video-time (* total-video-samples
rlm@544 56 seconds-per-frame)
rlm@530 57
rlm@544 58 av-diff (- total-audio-time
rlm@544 59 total-video-time)
rlm@544 60 write-video!
rlm@544 61 (fn [index]
rlm@544 62 ;; write screenshot
rlm@599 63 (moves-render-fn
rlm@546 64 move
rlm@546 65 (File. moves-dir (format "%07d.png" index)))
rlm@544 66
rlm@544 67 (write-png!
rlm@544 68 @current-state
rlm@544 69 (File. frames-dir (format "%07d.png" index)))
rlm@544 70
rlm@544 71 ;; write ram-image
rlm@599 72 (if render-ram-map?
rlm@599 73 (write-ram-image!
rlm@599 74 @current-state
rlm@599 75 (File. ram-map-dir (format "%07d.png" index)))))]
rlm@544 76 ;;(println "audio-samples:" (count sound))
rlm@544 77
rlm@544 78 ;; record audio
rlm@544 79 (.process wave-writer sound gb-sound-format)
rlm@544 80
rlm@544 81 ;; duplicate or drop frames depending on
rlm@544 82 ;; desired-fps
rlm@544 83 (if (> (Math/abs av-diff) (* 2 seconds-per-frame))
rlm@544 84 (if (< 0 av-diff)
rlm@544 85 ;; audio has gone past video, duplicate video.
rlm@544 86 (do (println
rlm@544 87 "duplicating frame, av-diff is" av-diff)
rlm@544 88 (write-video! (+ 1 total-video-samples))
rlm@544 89 (write-video! (+ 2 total-video-samples))
rlm@544 90 [total-audio-samples
rlm@544 91 (+ 2 total-video-samples)])
rlm@544 92 ;; video has gone past audio, drop frame.
rlm@544 93 (do (println
rlm@544 94 "dropping frame, av-diff is" av-diff)
rlm@544 95 [total-audio-samples
rlm@544 96 total-video-samples]))
rlm@544 97 ;; no frame dropping or duplication required.
rlm@544 98 (do ;;(println "all normal")
rlm@544 99 (write-video! (+ 1 total-video-samples))
rlm@544 100 [total-audio-samples
rlm@544 101 (+ 1 total-video-samples)]))))
rlm@544 102 [0 0 0] moves))
rlm@544 103 (finally
rlm@544 104 (do
rlm@544 105 (println "cleanup audio.")
rlm@544 106 (.cleanup wave-writer))))))
rlm@544 107 ([initial-state moves]
rlm@544 108 (render-files! render-dir initial-state moves))
rlm@544 109 ([moves]
rlm@544 110 (render-files! (root) moves)))
rlm@530 111
rlm@531 112 (defn file-names [#^File dir]
rlm@531 113 (mapv #(.getCanonicalPath %) (next (sort (file-seq dir)))))
rlm@531 114
rlm@531 115
rlm@532 116
rlm@549 117 ;; (defn final-cut! [^File render-dir]
rlm@549 118 ;; (let [movie (File. render-dir "final.ogg")
rlm@549 119 ;; final-audio (File. render-dir "final.wav")
rlm@549 120 ;; final (File. render-dir "final")]
rlm@549 121 ;; (.delete movie)
rlm@549 122 ;; (.delete final-audio)
rlm@549 123 ;; (clojure.java.shell/sh
rlm@549 124 ;; "sox" (.getCanonicalPath (File. render-dir "audio.wav"))
rlm@549 125 ;; (.getCanonicalPath final-audio))
rlm@549 126 ;; (clojure.java.shell/sh
rlm@549 127 ;; "ffmpeg" "-r" "60" ;; maybe 59.7 ???!
rlm@549 128 ;; "-i" (str (.getCanonicalPath final) "/" "%07d.bmp")
rlm@549 129 ;; "-i" (.getCanonicalPath final-audio)
rlm@549 130 ;; "-b:a" "128k"
rlm@549 131 ;; "-b:v" "9000k"
rlm@549 132 ;; "-c:a" "libvorbis"
rlm@549 133 ;; "-f" "webm"
rlm@549 134 ;; "-g" "200"
rlm@549 135 ;; (.getCanonicalPath movie)) nil))
rlm@549 136
rlm@532 137 (defn final-cut! [^File render-dir]
rlm@532 138 (let [movie (File. render-dir "final.ogg")
rlm@544 139 final-audio (File. render-dir "final.wav")
rlm@532 140 final (File. render-dir "final")]
rlm@532 141 (.delete movie)
rlm@547 142 (.delete final-audio)
rlm@532 143 (clojure.java.shell/sh
rlm@544 144 "sox" (.getCanonicalPath (File. render-dir "audio.wav"))
rlm@544 145 (.getCanonicalPath final-audio))
rlm@544 146 (clojure.java.shell/sh
rlm@549 147 "ffmpeg"
rlm@549 148 "-framerate" "60"
rlm@600 149 "-i" (str (.getCanonicalPath final) "/" "%07d.png")
rlm@544 150 "-i" (.getCanonicalPath final-audio)
rlm@532 151 "-b:a" "128k"
rlm@532 152 "-b:v" "9000k"
rlm@532 153 "-c:a" "libvorbis"
rlm@549 154 "-c:v" "libtheora"
rlm@549 155 "-r" "60"
rlm@532 156 (.getCanonicalPath movie)) nil))
rlm@549 157
rlm@531 158
rlm@532 159 (comment
rlm@531 160
rlm@532 161 ;; step 1
rlm@532 162
rlm@532 163 (render-files!
rlm@532 164 render-dir (root)
rlm@532 165 (take 9000 (first (control-checkpoint))))
rlm@531 166
rlm@532 167 ;; step 2
rlm@532 168
rlm@532 169 (generate-composite-frames!
rlm@532 170 render-dir
rlm@532 171 (take 9000 (first (control-checkpoint))))
rlm@532 172
rlm@532 173 ;; step 3
rlm@532 174 (final-cut! render-dir)
rlm@532 175 )