comparison 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
comparison
equal deleted inserted replaced
425:df4e03672b05 426:c03f28aa98d9
2 (:use (com.aurellem.gb saves gb-driver util constants 2 (:use (com.aurellem.gb saves gb-driver util constants
3 items vbm characters money 3 items vbm characters money
4 rlm-assembly)) 4 rlm-assembly))
5 (:use (com.aurellem.run util title save-corruption 5 (:use (com.aurellem.run util title save-corruption
6 bootstrap-0 bootstrap-1)) 6 bootstrap-0 bootstrap-1))
7 (:import [com.aurellem.gb.gb_driver SaveState])) 7 (:require clojure.string)
8 (:import [com.aurellem.gb.gb_driver SaveState])
9 (:import java.io.File))
8 10
9 11
10 (def music-base new-kernel) 12 (def music-base new-kernel)
11 13
12 14
293 (let [target 0xC000] 295 (let [target 0xC000]
294 (-> (set-memory-range (second (music-base)) 296 (-> (set-memory-range (second (music-base))
295 target program) 297 target program)
296 (PC! target))))) 298 (PC! target)))))
297 299
298 (defn trippy []
299 (run-moves (play-music many-notes ) (repeat 8000 [])))
300
301 (defn test-timer [] 300 (defn test-timer []
302 (flatten 301 (flatten
303 [0x3E 302 [0x3E
304 0x01 303 0x01
305 0xE0 304 0xE0
312 311
313 (repeat 312 (repeat
314 500 313 500
315 [0xF0 314 [0xF0
316 0x05])])) 315 0x05])]))
316
317 (def third-kind
318 (File. "/home/r/proj/midi/third-kind.mid"))
319
320 (defn raw-midi-text [#^File midi-file]
321 (:out
322 (clojure.java.shell/sh
323 "midicsv"
324 (.getCanonicalPath midi-file)
325 "-")))
326
327 (def command-line #"^(\d+), (\d+), ([^,]+)(.*)$")
328
329 (defmulti parse-command :command)
330
331 (defn discard-args [command] (dissoc command :args))
332
333 (defmethod parse-command :Start_track
334 [command] (discard-args command))
335
336 (defmethod parse-command :End_track
337 [command] (discard-args command))
338
339 (defmethod parse-command :default
340 [command] command)
341
342 (defn parse-number-list
343 [number-list-str]
344 (map #(Integer/parseInt %)
345 (clojure.string/split number-list-str #", ")))
346
347 (defmethod parse-command :Tempo
348 [command]
349 (update-in command [:args] #(Integer/parseInt %)))
350
351 (defn parse-midi-note-list
352 [midi-note-list-str]
353 (let [[channel note velocity]
354 (parse-number-list midi-note-list-str)]
355 {:channel channel :note note :velocity velocity}))
356
357
358 (defmethod parse-command :Note_on_c
359 [command]
360 (update-in command [:args] parse-midi-note-list))
361
362 (defmethod parse-command :Note_off_c
363 [command]
364 (update-in command [:args] parse-midi-note-list))
365
366 (defmethod parse-command :Header
367 [command]
368 (let [args (:args command)
369 [format num-tracks division] (parse-number-list args)]
370 (assoc command :args
371 {:format format
372 :num-tracks num-tracks
373 :division division})))
374
375 (defmethod parse-command :Program_c
376 [command]
377 (let [args (:args command)
378 [channel program-num] (parse-number-list args)]
379 (assoc command :args
380 {:channel channel
381 :program-num program-num})))
382
383
384 (defn parse-midi [#^File midi-file]
385 (map
386 (comp parse-command
387 (fn [line]
388 (let [[[_ channel time command args]]
389 (re-seq command-line line)]
390 ;;(println (re-seq command-parse-1 line))
391 {:channel (Integer/parseInt channel)
392 :time (Integer/parseInt time)
393 :command (keyword command)
394 :args (apply str (drop 2 args))})))
395 (drop-last
396 (clojure.string/split-lines
397 (raw-midi-text midi-file)))))
398