Mercurial > vba-clojure
diff clojure/com/aurellem/run/music.clj @ 462:32375de697e5
implememted automatic detection of tracks.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Fri, 04 May 2012 03:34:32 -0500 |
parents | a2ae4213deb7 |
children | 3e74bf517d8f |
line wrap: on
line diff
1.1 --- a/clojure/com/aurellem/run/music.clj Fri May 04 03:01:28 2012 -0500 1.2 +++ b/clojure/com/aurellem/run/music.clj Fri May 04 03:34:32 2012 -0500 1.3 @@ -402,6 +402,25 @@ 1.4 :duration length 1.5 :volume 0}) 1.6 1.7 +(defn track-info [#^File midi-file] 1.8 + (let [events (parse-midi midi-file) 1.9 + track-titles (commands :Title_t events) 1.10 + track-info 1.11 + (map #(read-string (read-string (:args %))) track-titles) 1.12 + track-map 1.13 + (zipmap track-info track-titles)] 1.14 + track-map)) 1.15 + 1.16 +(defn target-tracks 1.17 + "return the track-numbers in the form [voice-0 voice-1 noise]" 1.18 + [#^File midi-file] 1.19 + (let [track-data (track-info midi-file) 1.20 + track-order 1.21 + (zipmap (map :out (keys track-data)) 1.22 + (vals track-data)) 1.23 + channel-nums (map (comp :channel track-order) (range 3))] 1.24 + channel-nums)) 1.25 + 1.26 (defn commands 1.27 "return all events where #(= (:command %) command)" 1.28 [command s] 1.29 @@ -415,7 +434,7 @@ 1.30 1.31 select-channel 1.32 (fn [n s] 1.33 - (sort-by :time (filter #(= n (:channel (:args %))) s))) 1.34 + (sort-by :time (filter #(= n (:channel %)) s))) 1.35 1.36 channel-on (select-channel track-num note-on-events) 1.37 1.38 @@ -465,8 +484,29 @@ 1.39 1.40 1.41 (defn midi->mini-midi [#^File midi-file] 1.42 - {:track-1 (flatten (midi-track->mini-midi midi-file 0)) 1.43 - :track-2 (flatten (midi-track->mini-midi midi-file 1))}) 1.44 + (let [targets (target-tracks midi-file) 1.45 + get-track (fn [n] 1.46 + (if (not (nil? n)) 1.47 + (midi-track->mini-midi midi-file n) 1.48 + []))] 1.49 + {:voice-1 (get-track (nth targets 0)) 1.50 + :voice-2 (get-track (nth targets 1)) 1.51 + :noise (get-track (nth targets 2))})) 1.52 + 1.53 + ;; {:track-1 (flatten (midi-track->mini-midi midi-file 0)) 1.54 + ;; :track-2 (flatten (midi-track->mini-midi midi-file 1))}) 1.55 + 1.56 + 1.57 + 1.58 + 1.59 + 1.60 +(defn wave-duty 1.61 + "get desired wave-duty from the file for the particular channel." 1.62 + [#^File midi-file channel] 1.63 + 1.64 + 1.65 + ) 1.66 + 1.67 1.68 (defn play-midi [#^File midi-file] 1.69 (let [track-1-target 0xA000 1.70 @@ -475,14 +515,14 @@ 1.71 mini-midi (midi->mini-midi midi-file) 1.72 long-silence (flatten (note-codes 20 0 9001)) 1.73 wave-duty-1 2 1.74 - wave-duty-2 2 1.75 + wave-duty-2 3 1.76 ] 1.77 1.78 (-> (second (music-base)) 1.79 (set-memory-range track-1-target long-silence) 1.80 (set-memory-range track-2-target long-silence) 1.81 - (set-memory-range track-1-target (:track-1 mini-midi)) 1.82 - (set-memory-range track-2-target (:track-2 mini-midi)) 1.83 + (set-memory-range track-1-target (flatten (:voice-1 mini-midi))) 1.84 + (set-memory-range track-2-target (flatten (:voice-2 mini-midi))) 1.85 (set-memory-range 1.86 program-target 1.87 (music-kernel wave-duty-1 wave-duty-2))