Mercurial > vba-clojure
comparison clojure/com/aurellem/run/music.clj @ 467:ac0ed5c1a1c4
working on drums.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Fri, 04 May 2012 05:17:18 -0500 |
parents | b31cd6651375 |
children | 85d9fa354f0b |
comparison
equal
deleted
inserted
replaced
466:b31cd6651375 | 467:ac0ed5c1a1c4 |
---|---|
214 (replace | 214 (replace |
215 {:note-length (count play-note)} | 215 {:note-length (count play-note)} |
216 (concat switch play-note))))) | 216 (concat switch play-note))))) |
217 | 217 |
218 (defn play-noise | 218 (defn play-noise |
219 "read [noise-code, duration] and play the noise. Duration is left in | 219 "read [noise-code, volume, duration] and play the noise. Duration is left in |
220 A, and HL is advanced appropraitely." | 220 A, and HL is advanced appropraitely." |
221 ([] | 221 ([] |
222 [0x2A ;; load noise-code into A | 222 [0x2A ;; load noise-code into A |
223 0xE0 | 223 0xE0 |
224 0x22 ;; write noise-code | 224 0x22 ;; write noise-code |
225 | |
226 0x2A ;; load volume | |
227 0xE0 | |
228 0x21 ;; write volume | |
229 | |
225 0x2A] ;; load duration into A | 230 0x2A] ;; load duration into A |
226 )) | 231 )) |
227 | 232 |
228 | 233 |
229 ;; (defn play-note | 234 ;; (defn play-note |
451 (zipmap (map :out (keys track-data)) | 456 (zipmap (map :out (keys track-data)) |
452 (vals track-data)) | 457 (vals track-data)) |
453 channel-nums (map (comp :channel track-order) (range 3))] | 458 channel-nums (map (comp :channel track-order) (range 3))] |
454 channel-nums)) | 459 channel-nums)) |
455 | 460 |
456 (defn midi-track->mini-midi [#^File midi-file track-num] | 461 (defn midi-track->abstract-mini-midi |
457 (let [midi-events (parse-midi midi-file) | 462 [#^File midi-file track-num] |
463 (let [midi-events (parse-midi midi-file) | |
458 | 464 |
459 note-on-events (commands :Note_on_c midi-events) | 465 note-on-events (commands :Note_on_c midi-events) |
460 note-off-events (commands :Note_off_c midi-events) | 466 note-off-events (commands :Note_off_c midi-events) |
461 | 467 |
462 select-channel | 468 select-channel |
474 | 480 |
475 notes | 481 notes |
476 (map | 482 (map |
477 (fn [note-on note-off] | 483 (fn [note-on note-off] |
478 {:frequency (midi-code->frequency (:note (:args note-on))) | 484 {:frequency (midi-code->frequency (:note (:args note-on))) |
485 :midi-code (:note (:args note-on)) | |
479 :duration | 486 :duration |
480 (/ (* (/ tempo division) | 487 (/ (* (/ tempo division) |
481 (- (:time note-off) (:time note-on))) | 488 (- (:time note-off) (:time note-on))) |
482 1e6) ;; convert clock-pulses into seconds | 489 1e6) ;; convert clock-pulses into seconds |
483 :volume (int (/ (:velocity (:args note-on)) 10)) | 490 :volume (int (/ (:velocity (:args note-on)) 10)) |
499 notes-with-silence | 506 notes-with-silence |
500 (concat | 507 (concat |
501 (filter (comp not zero? :duration) | 508 (filter (comp not zero? :duration) |
502 (interleave silences notes)) | 509 (interleave silences notes)) |
503 [(silence 3)])] | 510 [(silence 3)])] |
504 | 511 notes-with-silence)) |
512 | |
513 (defn midi-track->mini-midi-voice [#^File midi-file track-num] | |
514 (let [abstract-mini-midi | |
515 (midi-track->abstract-mini-midi midi-file track-num)] | |
505 (map | 516 (map |
506 (fn [note-event] | 517 (fn [note-event] |
507 (note-codes (:frequency note-event) | 518 (note-codes (:frequency note-event) |
508 (:volume note-event) | 519 (:volume note-event) |
509 (int (* (:duration note-event) 0x100)))) | 520 (int (* (:duration note-event) 0x100)))) |
510 notes-with-silence))) | 521 abstract-mini-midi))) |
511 | 522 |
523 (defn noise-codes [code volume duration] | |
524 (assert (<= 0 volume 0xF)) | |
525 (if (<= duration 0xFF) | |
526 [(if (nil? code) 0xFF code) | |
527 (bit-shift-left volume 4) | |
528 duration] | |
529 (vec | |
530 (flatten | |
531 [(noise-codes code volume 0xFF) | |
532 (noise-codes code volume (- duration 0xFF))])))) | |
533 | |
534 (defn midi-track->mini-midi-noise [#^File midi-file track-num] | |
535 (let [abstract-mini-midi | |
536 (midi-track->abstract-mini-midi midi-file track-num)] | |
537 (map | |
538 (fn [noise-event] | |
539 (noise-codes (:midi-code noise-event) | |
540 (:volume noise-event) | |
541 (int (* (:duration noise-event) 0x100)))) | |
542 abstract-mini-midi))) | |
543 | |
544 | |
512 (defn midi->mini-midi [#^File midi-file] | 545 (defn midi->mini-midi [#^File midi-file] |
513 (let [targets (target-tracks midi-file) | 546 (let [targets (target-tracks midi-file) |
514 get-track (fn [n] | |
515 (if (not (nil? n)) | |
516 (midi-track->mini-midi midi-file n) | |
517 [])) | |
518 duty-info (keys (track-info midi-file))] | 547 duty-info (keys (track-info midi-file))] |
519 | 548 |
520 {:voice-1 (get-track (nth targets 0)) | 549 {:voice-1 (midi-track->mini-midi-voice midi-file (nth targets 0)) |
521 :voice-2 (get-track (nth targets 1)) | 550 :voice-2 (midi-track->mini-midi-voice midi-file (nth targets 1)) |
522 :noise (get-track (nth targets 2)) | 551 :noise (midi-track->mini-midi-noise midi-file (nth targets 2)) |
523 :duty (zipmap (map :out duty-info) | 552 :duty (zipmap (map :out duty-info) |
524 (map #(get % :duty 0) duty-info))})) | 553 (map #(get % :duty 0) duty-info))})) |
525 | 554 |
526 (defn play-midi [#^File midi-file] | 555 (defn play-midi [#^File midi-file] |
527 (let [track-1-target 0xA000 | 556 (let [voice-1-target 0xA000 |
528 track-2-target 0xB000 | 557 voice-2-target 0xB000 |
558 noise-target 0xA900 | |
529 program-target 0xC000 | 559 program-target 0xC000 |
530 mini-midi (midi->mini-midi midi-file) | 560 mini-midi (midi->mini-midi midi-file) |
531 long-silence (flatten (note-codes 20 0 9001)) | 561 long-silence (flatten (note-codes 20 0 20001)) |
532 | 562 long-noise-silence |
563 (interleave (range 500) (repeat 0x00) (repeat 255)) | |
564 | |
533 voice-1 (flatten (:voice-1 mini-midi)) | 565 voice-1 (flatten (:voice-1 mini-midi)) |
534 wave-duty-1 ((:duty mini-midi) 0 0) | 566 wave-duty-1 ((:duty mini-midi) 0 0) |
535 | 567 |
536 voice-2 (flatten (:voice-2 mini-midi)) | 568 voice-2 (flatten (:voice-2 mini-midi)) |
537 wave-duty-2 ((:duty mini-midi) 1 0) | 569 wave-duty-2 ((:duty mini-midi) 1 0) |
538 | 570 |
539 noise (flatten (:noise mini-midi)) | 571 noise (flatten (:noise mini-midi)) |
540 ] | 572 ] |
541 | 573 |
542 (-> (second (music-base)) | 574 (-> (second (music-base)) |
543 (set-memory-range track-1-target long-silence) | 575 (set-memory-range voice-1-target long-silence) |
544 (set-memory-range track-2-target long-silence) | 576 (set-memory-range voice-2-target long-silence) |
545 (set-memory-range track-1-target voice-1) | 577 (set-memory-range noise-target long-noise-silence) |
546 (set-memory-range track-2-target voice-2) | 578 (set-memory-range voice-1-target voice-1) |
579 (set-memory-range voice-2-target voice-2) | |
580 (set-memory-range noise-target noise) | |
547 (set-memory-range | 581 (set-memory-range |
548 program-target | 582 program-target |
549 (music-kernel wave-duty-1 wave-duty-2)) | 583 (music-kernel wave-duty-1 wave-duty-2)) |
550 (PC! program-target)))) | 584 (PC! program-target)))) |
585 | |
586 | |
587 (defn test-noise [] | |
588 (let [noise-pattern | |
589 (concat (interleave (range 0x100) (repeat 0xF0) (repeat 255)) | |
590 (interleave (range 10) (repeat 0x00) (repeat 255)))] | |
591 | |
592 (-> (second (music-base)) | |
593 (set-memory-range 0xA900 (flatten noise-pattern)) | |
594 (set-memory-range 0xC000 (music-kernel 0 0)) | |
595 (PC! 0xC000)))) | |
596 | |
597 (defn test-play-noise [noise-code] | |
598 (println "playing-noise" noise-code) | |
599 (run-moves | |
600 (let [noise-pattern | |
601 (interleave (repeat 10 noise-code) (repeat 0xF0) (repeat 255))] | |
602 (-> (second (music-base)) | |
603 (set-memory-range 0xA900 (flatten noise-pattern)) | |
604 (set-memory-range 0xC000 (music-kernel 0 0)) | |
605 (PC! 0xC000))) | |
606 (repeat 128 []))) | |
607 | |
608 (defn test-all-noises [] | |
609 (dorun (map test-play-noise (range 0x100)))) | |
610 | |
611 | |
551 | 612 |
552 (def C4 (partial note-codes 261.63)) | 613 (def C4 (partial note-codes 261.63)) |
553 (def D4 (partial note-codes 293.66)) | 614 (def D4 (partial note-codes 293.66)) |
554 (def E4 (partial note-codes 329.63)) | 615 (def E4 (partial note-codes 329.63)) |
555 (def F4 (partial note-codes 349.23)) | 616 (def F4 (partial note-codes 349.23)) |