# HG changeset patch
# User Robert McIntyre <rlm@mit.edu>
# Date 1336126638 18000
# Node ID ac0ed5c1a1c44e90931ace562960886abf2b9e97
# Parent  b31cd66513753cb3d51db18b877fc7776666f7e7
working on drums.

diff -r b31cd6651375 -r ac0ed5c1a1c4 clojure/com/aurellem/run/music.clj
--- a/clojure/com/aurellem/run/music.clj	Fri May 04 04:13:13 2012 -0500
+++ b/clojure/com/aurellem/run/music.clj	Fri May 04 05:17:18 2012 -0500
@@ -216,12 +216,17 @@
         (concat switch play-note)))))
 
 (defn play-noise
-  "read [noise-code, duration] and play the noise. Duration is left in
+  "read [noise-code, volume,  duration] and play the noise. Duration is left in
    A, and HL is advanced appropraitely."
   ([]
      [0x2A  ;; load noise-code into A
       0xE0
       0x22  ;; write noise-code
+
+      0x2A  ;; load volume
+      0xE0
+      0x21  ;; write volume
+      
       0x2A] ;; load duration into A
      ))
 
@@ -453,8 +458,9 @@
         channel-nums (map (comp :channel track-order) (range 3))]
     channel-nums))
 
-(defn midi-track->mini-midi [#^File midi-file track-num]
-  (let [midi-events (parse-midi midi-file)
+(defn midi-track->abstract-mini-midi
+  [#^File midi-file track-num]
+    (let [midi-events (parse-midi midi-file)
 
         note-on-events  (commands :Note_on_c  midi-events)
         note-off-events (commands :Note_off_c midi-events)
@@ -476,6 +482,7 @@
         (map
          (fn [note-on note-off]
            {:frequency (midi-code->frequency (:note (:args note-on)))
+            :midi-code (:note (:args note-on))
             :duration
             (/ (* (/ tempo division)
                   (- (:time note-off) (:time note-on)))
@@ -501,35 +508,60 @@
          (filter (comp not zero? :duration)
                  (interleave silences notes))
          [(silence 3)])]
-
+    notes-with-silence))
+      
+(defn midi-track->mini-midi-voice [#^File midi-file track-num]
+  (let [abstract-mini-midi
+        (midi-track->abstract-mini-midi midi-file track-num)]
      (map
       (fn [note-event]
         (note-codes (:frequency note-event)
                     (:volume note-event)
                     (int (* (:duration note-event) 0x100))))
-      notes-with-silence)))
-     
+      abstract-mini-midi)))
+
+(defn noise-codes [code volume duration]
+  (assert (<= 0 volume 0xF))
+  (if (<= duration 0xFF)
+    [(if (nil? code) 0xFF code)
+     (bit-shift-left volume 4)
+     duration]
+    (vec
+     (flatten 
+      [(noise-codes code volume 0xFF)
+       (noise-codes code volume (- duration 0xFF))]))))
+
+(defn midi-track->mini-midi-noise [#^File midi-file track-num]
+  (let [abstract-mini-midi
+        (midi-track->abstract-mini-midi midi-file track-num)]
+    (map
+     (fn [noise-event]
+       (noise-codes (:midi-code noise-event)
+                    (:volume noise-event)
+                    (int (* (:duration noise-event) 0x100))))
+     abstract-mini-midi)))
+
+
 (defn midi->mini-midi [#^File midi-file]
   (let [targets (target-tracks midi-file)
-        get-track (fn [n]
-                    (if (not (nil? n))
-                      (midi-track->mini-midi midi-file n)
-                      []))
         duty-info (keys (track-info midi-file))]
     
-    {:voice-1 (get-track (nth targets 0))
-     :voice-2 (get-track (nth targets 1))
-     :noise   (get-track (nth targets 2))
+    {:voice-1 (midi-track->mini-midi-voice midi-file (nth targets 0))
+     :voice-2 (midi-track->mini-midi-voice midi-file (nth targets 1))
+     :noise   (midi-track->mini-midi-noise midi-file (nth targets 2))
      :duty    (zipmap (map :out duty-info)
                       (map #(get % :duty 0) duty-info))}))
 
 (defn play-midi [#^File midi-file]
-  (let [track-1-target 0xA000
-        track-2-target 0xB000
+  (let [voice-1-target 0xA000
+        voice-2-target 0xB000
+        noise-target   0xA900
         program-target 0xC000
         mini-midi (midi->mini-midi midi-file)
-        long-silence (flatten (note-codes 20 0 9001))
-
+        long-silence (flatten (note-codes 20 0 20001))
+        long-noise-silence
+        (interleave (range 500) (repeat 0x00) (repeat 255))
+        
         voice-1 (flatten (:voice-1 mini-midi))
         wave-duty-1 ((:duty mini-midi) 0 0)
 
@@ -540,15 +572,44 @@
         ]
     
     (-> (second (music-base))
-        (set-memory-range track-1-target long-silence)
-        (set-memory-range track-2-target long-silence)
-        (set-memory-range track-1-target voice-1)
-        (set-memory-range track-2-target voice-2)
+        (set-memory-range voice-1-target long-silence)
+        (set-memory-range voice-2-target long-silence)
+        (set-memory-range noise-target   long-noise-silence)
+        (set-memory-range voice-1-target voice-1)
+        (set-memory-range voice-2-target voice-2)
+        (set-memory-range noise-target   noise)
         (set-memory-range
          program-target
          (music-kernel wave-duty-1 wave-duty-2))
         (PC! program-target))))
 
+
+(defn test-noise []
+  (let [noise-pattern
+        (concat (interleave (range 0x100) (repeat 0xF0) (repeat 255))
+                (interleave (range 10) (repeat 0x00) (repeat 255)))]
+                
+    (-> (second (music-base))
+        (set-memory-range 0xA900 (flatten noise-pattern))
+        (set-memory-range 0xC000 (music-kernel 0 0))
+        (PC! 0xC000))))
+
+(defn test-play-noise [noise-code]
+  (println "playing-noise" noise-code)
+  (run-moves
+   (let [noise-pattern
+         (interleave (repeat 10 noise-code) (repeat 0xF0) (repeat 255))]
+     (-> (second (music-base))
+         (set-memory-range 0xA900 (flatten noise-pattern))
+         (set-memory-range 0xC000 (music-kernel 0 0))
+         (PC! 0xC000)))
+   (repeat 128 [])))
+
+(defn test-all-noises []
+  (dorun (map test-play-noise (range 0x100))))
+
+
+
 (def C4 (partial note-codes 261.63))
 (def D4 (partial note-codes 293.66))
 (def E4 (partial note-codes 329.63))
diff -r b31cd6651375 -r ac0ed5c1a1c4 music/Friendship is Magic (MLP Theme Song).rg
Binary file music/Friendship is Magic (MLP Theme Song).rg has changed
diff -r b31cd6651375 -r ac0ed5c1a1c4 music/drum-test.mid
Binary file music/drum-test.mid has changed
diff -r b31cd6651375 -r ac0ed5c1a1c4 music/drum-test.rg
Binary file music/drum-test.rg has changed
diff -r b31cd6651375 -r ac0ed5c1a1c4 music/pony-title.mid
Binary file music/pony-title.mid has changed