# HG changeset patch # User Robert McIntyre # 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