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))