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))