Mercurial > vba-clojure
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 |