Mercurial > vba-clojure
diff clojure/com/aurellem/run/music.clj @ 426:c03f28aa98d9
completed basic midi parser using midicsv
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 23 Apr 2012 07:02:39 -0500 |
parents | df4e03672b05 |
children | fbccf46cf34d |
line wrap: on
line diff
1.1 --- a/clojure/com/aurellem/run/music.clj Mon Apr 23 05:45:25 2012 -0500 1.2 +++ b/clojure/com/aurellem/run/music.clj Mon Apr 23 07:02:39 2012 -0500 1.3 @@ -4,7 +4,9 @@ 1.4 rlm-assembly)) 1.5 (:use (com.aurellem.run util title save-corruption 1.6 bootstrap-0 bootstrap-1)) 1.7 - (:import [com.aurellem.gb.gb_driver SaveState])) 1.8 + (:require clojure.string) 1.9 + (:import [com.aurellem.gb.gb_driver SaveState]) 1.10 + (:import java.io.File)) 1.11 1.12 1.13 (def music-base new-kernel) 1.14 @@ -295,9 +297,6 @@ 1.15 target program) 1.16 (PC! target))))) 1.17 1.18 -(defn trippy [] 1.19 - (run-moves (play-music many-notes ) (repeat 8000 []))) 1.20 - 1.21 (defn test-timer [] 1.22 (flatten 1.23 [0x3E 1.24 @@ -314,3 +313,86 @@ 1.25 500 1.26 [0xF0 1.27 0x05])])) 1.28 + 1.29 +(def third-kind 1.30 + (File. "/home/r/proj/midi/third-kind.mid")) 1.31 + 1.32 +(defn raw-midi-text [#^File midi-file] 1.33 + (:out 1.34 + (clojure.java.shell/sh 1.35 + "midicsv" 1.36 + (.getCanonicalPath midi-file) 1.37 + "-"))) 1.38 + 1.39 +(def command-line #"^(\d+), (\d+), ([^,]+)(.*)$") 1.40 + 1.41 +(defmulti parse-command :command) 1.42 + 1.43 +(defn discard-args [command] (dissoc command :args)) 1.44 + 1.45 +(defmethod parse-command :Start_track 1.46 + [command] (discard-args command)) 1.47 + 1.48 +(defmethod parse-command :End_track 1.49 + [command] (discard-args command)) 1.50 + 1.51 +(defmethod parse-command :default 1.52 + [command] command) 1.53 + 1.54 +(defn parse-number-list 1.55 + [number-list-str] 1.56 + (map #(Integer/parseInt %) 1.57 + (clojure.string/split number-list-str #", "))) 1.58 + 1.59 +(defmethod parse-command :Tempo 1.60 + [command] 1.61 + (update-in command [:args] #(Integer/parseInt %))) 1.62 + 1.63 +(defn parse-midi-note-list 1.64 + [midi-note-list-str] 1.65 + (let [[channel note velocity] 1.66 + (parse-number-list midi-note-list-str)] 1.67 + {:channel channel :note note :velocity velocity})) 1.68 + 1.69 + 1.70 +(defmethod parse-command :Note_on_c 1.71 + [command] 1.72 + (update-in command [:args] parse-midi-note-list)) 1.73 + 1.74 +(defmethod parse-command :Note_off_c 1.75 + [command] 1.76 + (update-in command [:args] parse-midi-note-list)) 1.77 + 1.78 +(defmethod parse-command :Header 1.79 + [command] 1.80 + (let [args (:args command) 1.81 + [format num-tracks division] (parse-number-list args)] 1.82 + (assoc command :args 1.83 + {:format format 1.84 + :num-tracks num-tracks 1.85 + :division division}))) 1.86 + 1.87 +(defmethod parse-command :Program_c 1.88 + [command] 1.89 + (let [args (:args command) 1.90 + [channel program-num] (parse-number-list args)] 1.91 + (assoc command :args 1.92 + {:channel channel 1.93 + :program-num program-num}))) 1.94 + 1.95 + 1.96 +(defn parse-midi [#^File midi-file] 1.97 + (map 1.98 + (comp parse-command 1.99 + (fn [line] 1.100 + (let [[[_ channel time command args]] 1.101 + (re-seq command-line line)] 1.102 + ;;(println (re-seq command-parse-1 line)) 1.103 + {:channel (Integer/parseInt channel) 1.104 + :time (Integer/parseInt time) 1.105 + :command (keyword command) 1.106 + :args (apply str (drop 2 args))}))) 1.107 + (drop-last 1.108 + (clojure.string/split-lines 1.109 + (raw-midi-text midi-file))))) 1.110 +