comparison 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
comparison
equal deleted inserted replaced
461:a2ae4213deb7 462:32375de697e5
400 (defn silence [length] 400 (defn silence [length]
401 {:frequency 1 401 {:frequency 1
402 :duration length 402 :duration length
403 :volume 0}) 403 :volume 0})
404 404
405 (defn track-info [#^File midi-file]
406 (let [events (parse-midi midi-file)
407 track-titles (commands :Title_t events)
408 track-info
409 (map #(read-string (read-string (:args %))) track-titles)
410 track-map
411 (zipmap track-info track-titles)]
412 track-map))
413
414 (defn target-tracks
415 "return the track-numbers in the form [voice-0 voice-1 noise]"
416 [#^File midi-file]
417 (let [track-data (track-info midi-file)
418 track-order
419 (zipmap (map :out (keys track-data))
420 (vals track-data))
421 channel-nums (map (comp :channel track-order) (range 3))]
422 channel-nums))
423
405 (defn commands 424 (defn commands
406 "return all events where #(= (:command %) command)" 425 "return all events where #(= (:command %) command)"
407 [command s] 426 [command s]
408 (filter #(= command (:command %)) s)) 427 (filter #(= command (:command %)) s))
409 428
413 note-on-events (commands :Note_on_c midi-events) 432 note-on-events (commands :Note_on_c midi-events)
414 note-off-events (commands :Note_off_c midi-events) 433 note-off-events (commands :Note_off_c midi-events)
415 434
416 select-channel 435 select-channel
417 (fn [n s] 436 (fn [n s]
418 (sort-by :time (filter #(= n (:channel (:args %))) s))) 437 (sort-by :time (filter #(= n (:channel %)) s)))
419 438
420 channel-on (select-channel track-num note-on-events) 439 channel-on (select-channel track-num note-on-events)
421 440
422 channel-off (select-channel track-num note-off-events) 441 channel-off (select-channel track-num note-off-events)
423 442
463 (int (* (:duration note-event) 0x100)))) 482 (int (* (:duration note-event) 0x100))))
464 notes-with-silence))) 483 notes-with-silence)))
465 484
466 485
467 (defn midi->mini-midi [#^File midi-file] 486 (defn midi->mini-midi [#^File midi-file]
468 {:track-1 (flatten (midi-track->mini-midi midi-file 0)) 487 (let [targets (target-tracks midi-file)
469 :track-2 (flatten (midi-track->mini-midi midi-file 1))}) 488 get-track (fn [n]
489 (if (not (nil? n))
490 (midi-track->mini-midi midi-file n)
491 []))]
492 {:voice-1 (get-track (nth targets 0))
493 :voice-2 (get-track (nth targets 1))
494 :noise (get-track (nth targets 2))}))
495
496 ;; {:track-1 (flatten (midi-track->mini-midi midi-file 0))
497 ;; :track-2 (flatten (midi-track->mini-midi midi-file 1))})
498
499
500
501
502
503 (defn wave-duty
504 "get desired wave-duty from the file for the particular channel."
505 [#^File midi-file channel]
506
507
508 )
509
470 510
471 (defn play-midi [#^File midi-file] 511 (defn play-midi [#^File midi-file]
472 (let [track-1-target 0xA000 512 (let [track-1-target 0xA000
473 track-2-target 0xB000 513 track-2-target 0xB000
474 program-target 0xC000 514 program-target 0xC000
475 mini-midi (midi->mini-midi midi-file) 515 mini-midi (midi->mini-midi midi-file)
476 long-silence (flatten (note-codes 20 0 9001)) 516 long-silence (flatten (note-codes 20 0 9001))
477 wave-duty-1 2 517 wave-duty-1 2
478 wave-duty-2 2 518 wave-duty-2 3
479 ] 519 ]
480 520
481 (-> (second (music-base)) 521 (-> (second (music-base))
482 (set-memory-range track-1-target long-silence) 522 (set-memory-range track-1-target long-silence)
483 (set-memory-range track-2-target long-silence) 523 (set-memory-range track-2-target long-silence)
484 (set-memory-range track-1-target (:track-1 mini-midi)) 524 (set-memory-range track-1-target (flatten (:voice-1 mini-midi)))
485 (set-memory-range track-2-target (:track-2 mini-midi)) 525 (set-memory-range track-2-target (flatten (:voice-2 mini-midi)))
486 (set-memory-range 526 (set-memory-range
487 program-target 527 program-target
488 (music-kernel wave-duty-1 wave-duty-2)) 528 (music-kernel wave-duty-1 wave-duty-2))
489 (PC! program-target)))) 529 (PC! program-target))))
490 530