diff clojure/com/aurellem/run/final_cut.clj @ 544:86d23b6d433f

trying to fix AV sync issues.
author Robert McIntyre <rlm@mit.edu>
date Wed, 27 Jun 2012 11:20:50 -0500
parents 6c379ee3d46e
children 36e5fa62eb3c
line wrap: on
line diff
     1.1 --- a/clojure/com/aurellem/run/final_cut.clj	Mon Jun 25 19:46:48 2012 -0500
     1.2 +++ b/clojure/com/aurellem/run/final_cut.clj	Wed Jun 27 11:20:50 2012 -0500
     1.3 @@ -15,6 +15,14 @@
     1.4  
     1.5  (def render-dir (File. user-home "proj/vba-clojure/render/test"))
     1.6  
     1.7 +(defn force-sync
     1.8 +  "keep the entire movie to a certain fps"
     1.9 +  [fps]
    1.10 +
    1.11 +
    1.12 +  )
    1.13 +
    1.14 +
    1.15  (defn render-files!
    1.16    ([^File target-dir initial-state moves]
    1.17       (let [ram-map-dir (File. target-dir "ram-map")
    1.18 @@ -24,32 +32,81 @@
    1.19             _ (.mkdir ram-map-dir)
    1.20             _ (.mkdir frames-dir)
    1.21             wave-writer (WaveWriter. audio-file)
    1.22 -           moves (vec moves)]
    1.23 +           moves (vec moves)
    1.24 +           desired-fps 60
    1.25 +           seconds-per-frame (/ 1.0 desired-fps)
    1.26 +
    1.27 +           ]
    1.28         (set-state! initial-state)
    1.29 -       (dorun
    1.30 -        (map
    1.31 -         (fn [index]
    1.32 -           (run-moves @current-state (vector (moves index)))
    1.33 +       ;; clear sound buffer
    1.34 +       (sound-bytes)
    1.35 +       (try 
    1.36 +         (dorun
    1.37 +          (reduce
    1.38 +           (fn [[total-audio-samples
    1.39 +                 total-video-samples] move]
    1.40 +             (run-moves @current-state (vector move))
    1.41 +             (let [sound (sound-bytes)
    1.42 +                   total-audio-samples (+ total-audio-samples
    1.43 +                                          (count sound))
    1.44 +                   total-audio-time
    1.45 +                   (*
    1.46 +                    (/ total-audio-samples 4)
    1.47 +                    (/ 44100))
    1.48 +                   
    1.49 +                   total-video-time (* total-video-samples
    1.50 +                                       seconds-per-frame)
    1.51  
    1.52 -           ;; record audio
    1.53 -           (.process wave-writer (sound-bytes)
    1.54 -                     gb-sound-format)
    1.55 -
    1.56 -           ;; write screenshot
    1.57 -           (write-png!
    1.58 -            @current-state
    1.59 -            (File. frames-dir (format "%07d.png" index)))
    1.60 -
    1.61 -           ;; write ram-image
    1.62 -           (write-ram-image!
    1.63 -            @current-state
    1.64 -            (File. ram-map-dir (format "%07d.png" index))))
    1.65 -         (range (count moves))))
    1.66 -       (.cleanup wave-writer)))
    1.67 -  ([initial-state moves]
    1.68 -     (render-files! render-dir initial-state moves))
    1.69 -  ([moves]
    1.70 -     (render-files! (root) moves)))
    1.71 +                   av-diff (- total-audio-time
    1.72 +                              total-video-time)
    1.73 +                   write-video!
    1.74 +                   (fn [index]
    1.75 +                     ;; write screenshot
    1.76 +                     
    1.77 +                     
    1.78 +                     (write-png!
    1.79 +                      @current-state
    1.80 +                      (File. frames-dir (format "%07d.png" index)))
    1.81 +                     
    1.82 +                     ;; write ram-image
    1.83 +                     (write-ram-image!
    1.84 +                      @current-state
    1.85 +                      (File. ram-map-dir (format "%07d.png" index))))]
    1.86 +               ;;(println "audio-samples:" (count sound))
    1.87 +               
    1.88 +               ;; record audio
    1.89 +               (.process wave-writer sound gb-sound-format)
    1.90 +               
    1.91 +               ;; duplicate or drop frames depending on
    1.92 +               ;; desired-fps
    1.93 +               (if (> (Math/abs av-diff) (* 2 seconds-per-frame))
    1.94 +                 (if (<  0 av-diff)
    1.95 +                   ;; audio has gone past video, duplicate video.
    1.96 +                   (do (println
    1.97 +                        "duplicating frame, av-diff is" av-diff)
    1.98 +                       (write-video! (+ 1 total-video-samples))
    1.99 +                       (write-video! (+ 2 total-video-samples))
   1.100 +                       [total-audio-samples
   1.101 +                        (+ 2 total-video-samples)])
   1.102 +                   ;; video has gone past audio, drop frame.
   1.103 +                   (do (println
   1.104 +                        "dropping frame, av-diff is" av-diff)
   1.105 +                       [total-audio-samples
   1.106 +                        total-video-samples]))
   1.107 +                 ;; no frame dropping or duplication required.
   1.108 +                 (do ;;(println "all normal")
   1.109 +                     (write-video! (+ 1 total-video-samples))
   1.110 +                     [total-audio-samples
   1.111 +                      (+ 1 total-video-samples)]))))
   1.112 +           [0 0 0] moves))
   1.113 +         (finally
   1.114 +           (do
   1.115 +             (println "cleanup audio.")
   1.116 +             (.cleanup wave-writer))))))
   1.117 +     ([initial-state moves]
   1.118 +        (render-files! render-dir initial-state moves))
   1.119 +     ([moves]
   1.120 +        (render-files! (root) moves)))
   1.121  
   1.122  (defn file-names [#^File dir]
   1.123     (mapv #(.getCanonicalPath %) (next (sort (file-seq dir)))))
   1.124 @@ -96,12 +153,16 @@
   1.125  
   1.126  (defn final-cut! [^File render-dir]
   1.127    (let [movie (File. render-dir "final.ogg")
   1.128 +        final-audio (File. render-dir "final.wav")
   1.129          final (File. render-dir "final")]
   1.130      (.delete movie)
   1.131      (clojure.java.shell/sh
   1.132 +     "sox" (.getCanonicalPath (File. render-dir "audio.wav"))
   1.133 +     (.getCanonicalPath final-audio))
   1.134 +    (clojure.java.shell/sh
   1.135       "ffmpeg" "-r" "60" ;; maybe 59.7 ???!
   1.136       "-i" (str (.getCanonicalPath final) "/" "%07d.bmp")
   1.137 -     "-i" (.getCanonicalPath (File. render-dir "audio.wav"))
   1.138 +     "-i" (.getCanonicalPath final-audio)
   1.139       "-b:a" "128k"
   1.140       "-b:v" "9000k"
   1.141       "-c:a" "libvorbis"