changeset 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 2b6cdea9bcdb
files clojure/com/aurellem/run/basic_choreo.clj clojure/com/aurellem/run/final_cut.clj todo.org
diffstat 3 files changed, 90 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
     1.1 --- a/clojure/com/aurellem/run/basic_choreo.clj	Mon Jun 25 19:46:48 2012 -0500
     1.2 +++ b/clojure/com/aurellem/run/basic_choreo.clj	Wed Jun 27 11:20:50 2012 -0500
     1.3 @@ -69,10 +69,8 @@
     1.4            (transfer-control image-program-start)
     1.5            (do-nothing 1800))))
     1.6  
     1.7 -
     1.8 -
     1.9  (def basic-render-dir
    1.10 -  (File. user-home "proj/vba-clojure/render/basic"))
    1.11 +  (File. user-home "proj/vba-clojure/render/basic2"))
    1.12  
    1.13  (defn basic-steps [] (first (activate-media)))
    1.14  
     2.1 --- a/clojure/com/aurellem/run/final_cut.clj	Mon Jun 25 19:46:48 2012 -0500
     2.2 +++ b/clojure/com/aurellem/run/final_cut.clj	Wed Jun 27 11:20:50 2012 -0500
     2.3 @@ -15,6 +15,14 @@
     2.4  
     2.5  (def render-dir (File. user-home "proj/vba-clojure/render/test"))
     2.6  
     2.7 +(defn force-sync
     2.8 +  "keep the entire movie to a certain fps"
     2.9 +  [fps]
    2.10 +
    2.11 +
    2.12 +  )
    2.13 +
    2.14 +
    2.15  (defn render-files!
    2.16    ([^File target-dir initial-state moves]
    2.17       (let [ram-map-dir (File. target-dir "ram-map")
    2.18 @@ -24,32 +32,81 @@
    2.19             _ (.mkdir ram-map-dir)
    2.20             _ (.mkdir frames-dir)
    2.21             wave-writer (WaveWriter. audio-file)
    2.22 -           moves (vec moves)]
    2.23 +           moves (vec moves)
    2.24 +           desired-fps 60
    2.25 +           seconds-per-frame (/ 1.0 desired-fps)
    2.26 +
    2.27 +           ]
    2.28         (set-state! initial-state)
    2.29 -       (dorun
    2.30 -        (map
    2.31 -         (fn [index]
    2.32 -           (run-moves @current-state (vector (moves index)))
    2.33 +       ;; clear sound buffer
    2.34 +       (sound-bytes)
    2.35 +       (try 
    2.36 +         (dorun
    2.37 +          (reduce
    2.38 +           (fn [[total-audio-samples
    2.39 +                 total-video-samples] move]
    2.40 +             (run-moves @current-state (vector move))
    2.41 +             (let [sound (sound-bytes)
    2.42 +                   total-audio-samples (+ total-audio-samples
    2.43 +                                          (count sound))
    2.44 +                   total-audio-time
    2.45 +                   (*
    2.46 +                    (/ total-audio-samples 4)
    2.47 +                    (/ 44100))
    2.48 +                   
    2.49 +                   total-video-time (* total-video-samples
    2.50 +                                       seconds-per-frame)
    2.51  
    2.52 -           ;; record audio
    2.53 -           (.process wave-writer (sound-bytes)
    2.54 -                     gb-sound-format)
    2.55 -
    2.56 -           ;; write screenshot
    2.57 -           (write-png!
    2.58 -            @current-state
    2.59 -            (File. frames-dir (format "%07d.png" index)))
    2.60 -
    2.61 -           ;; write ram-image
    2.62 -           (write-ram-image!
    2.63 -            @current-state
    2.64 -            (File. ram-map-dir (format "%07d.png" index))))
    2.65 -         (range (count moves))))
    2.66 -       (.cleanup wave-writer)))
    2.67 -  ([initial-state moves]
    2.68 -     (render-files! render-dir initial-state moves))
    2.69 -  ([moves]
    2.70 -     (render-files! (root) moves)))
    2.71 +                   av-diff (- total-audio-time
    2.72 +                              total-video-time)
    2.73 +                   write-video!
    2.74 +                   (fn [index]
    2.75 +                     ;; write screenshot
    2.76 +                     
    2.77 +                     
    2.78 +                     (write-png!
    2.79 +                      @current-state
    2.80 +                      (File. frames-dir (format "%07d.png" index)))
    2.81 +                     
    2.82 +                     ;; write ram-image
    2.83 +                     (write-ram-image!
    2.84 +                      @current-state
    2.85 +                      (File. ram-map-dir (format "%07d.png" index))))]
    2.86 +               ;;(println "audio-samples:" (count sound))
    2.87 +               
    2.88 +               ;; record audio
    2.89 +               (.process wave-writer sound gb-sound-format)
    2.90 +               
    2.91 +               ;; duplicate or drop frames depending on
    2.92 +               ;; desired-fps
    2.93 +               (if (> (Math/abs av-diff) (* 2 seconds-per-frame))
    2.94 +                 (if (<  0 av-diff)
    2.95 +                   ;; audio has gone past video, duplicate video.
    2.96 +                   (do (println
    2.97 +                        "duplicating frame, av-diff is" av-diff)
    2.98 +                       (write-video! (+ 1 total-video-samples))
    2.99 +                       (write-video! (+ 2 total-video-samples))
   2.100 +                       [total-audio-samples
   2.101 +                        (+ 2 total-video-samples)])
   2.102 +                   ;; video has gone past audio, drop frame.
   2.103 +                   (do (println
   2.104 +                        "dropping frame, av-diff is" av-diff)
   2.105 +                       [total-audio-samples
   2.106 +                        total-video-samples]))
   2.107 +                 ;; no frame dropping or duplication required.
   2.108 +                 (do ;;(println "all normal")
   2.109 +                     (write-video! (+ 1 total-video-samples))
   2.110 +                     [total-audio-samples
   2.111 +                      (+ 1 total-video-samples)]))))
   2.112 +           [0 0 0] moves))
   2.113 +         (finally
   2.114 +           (do
   2.115 +             (println "cleanup audio.")
   2.116 +             (.cleanup wave-writer))))))
   2.117 +     ([initial-state moves]
   2.118 +        (render-files! render-dir initial-state moves))
   2.119 +     ([moves]
   2.120 +        (render-files! (root) moves)))
   2.121  
   2.122  (defn file-names [#^File dir]
   2.123     (mapv #(.getCanonicalPath %) (next (sort (file-seq dir)))))
   2.124 @@ -96,12 +153,16 @@
   2.125  
   2.126  (defn final-cut! [^File render-dir]
   2.127    (let [movie (File. render-dir "final.ogg")
   2.128 +        final-audio (File. render-dir "final.wav")
   2.129          final (File. render-dir "final")]
   2.130      (.delete movie)
   2.131      (clojure.java.shell/sh
   2.132 +     "sox" (.getCanonicalPath (File. render-dir "audio.wav"))
   2.133 +     (.getCanonicalPath final-audio))
   2.134 +    (clojure.java.shell/sh
   2.135       "ffmpeg" "-r" "60" ;; maybe 59.7 ???!
   2.136       "-i" (str (.getCanonicalPath final) "/" "%07d.bmp")
   2.137 -     "-i" (.getCanonicalPath (File. render-dir "audio.wav"))
   2.138 +     "-i" (.getCanonicalPath final-audio)
   2.139       "-b:a" "128k"
   2.140       "-b:v" "9000k"
   2.141       "-c:a" "libvorbis"
     3.1 --- a/todo.org	Mon Jun 25 19:46:48 2012 -0500
     3.2 +++ b/todo.org	Wed Jun 27 11:20:50 2012 -0500
     3.3 @@ -1,12 +1,14 @@
     3.4 -* vba-clojure [3/8]
     3.5 +* vba-clojure [3/10]
     3.6    - [X] create ram display
     3.7    - [ ] derpy hack 
     3.8    - [X] sound recording
     3.9    - [ ] fix unnecessary pauses before take-over
    3.10    - [ ] sell two of the 0x00 items at once.
    3.11 +  - [ ] walk out of elevator efficiently
    3.12    - [ ] design demo choreography
    3.13    - [ ] implement choreography
    3.14    - [X] clojure function to assemble final video
    3.15 +  - [ ] fix A/V sync issues
    3.16  
    3.17  * fimfiction [0/1]
    3.18    - [ ] clojure catalogue