Mercurial > hg > amuse
comparison implementations/midi/midifile-import.lisp @ 36:ad321ce17e3e
Moving some functionality from specialised geerdes area. Also added mcsv output
darcs-hash:20070511120916-f76cc-d6f1b566eea7115c5de1d3aad285c84b304730b7.gz
author | David Lewis <d.lewis@gold.ac.uk> |
---|---|
date | Fri, 11 May 2007 13:09:16 +0100 |
parents | 1d757c33e00e |
children | cf198383852d |
comparison
equal
deleted
inserted
replaced
35:1d757c33e00e | 36:ad321ce17e3e |
---|---|
27 (or (< (midi:message-time x) | 27 (or (< (midi:message-time x) |
28 (midi:message-time y)) | 28 (midi:message-time y)) |
29 (and (= (midi:message-time x) | 29 (and (= (midi:message-time x) |
30 (midi:message-time y)) | 30 (midi:message-time y)) |
31 (typep x 'midi:note-off-message)))))) | 31 (typep x 'midi:note-off-message)))))) |
32 (let ((ons (make-array '(17 128) :initial-element nil)) | 32 (let ((ons (make-array '(16 128) :initial-element nil)) |
33 (offs) | 33 (offs) |
34 (patches (make-array 17 :initial-element 0))) | 34 (patches (make-array 16 :initial-element 0))) |
35 (dolist (event track) | 35 (dolist (event track) |
36 (when (> (midi:message-time event) last-time) | 36 (when (> (midi:message-time event) last-time) |
37 (setf last-time (midi:message-time event))) | 37 (setf last-time (midi:message-time event))) |
38 (cond | 38 (cond |
39 ((or (typep event 'midi:note-off-message) | 39 ((or (typep event 'midi:note-off-message) |
40 (and (typep event 'midi:note-on-message) | 40 (and (typep event 'midi:note-on-message) |
41 (= (midi:message-velocity event) 0))) | 41 (= (midi:message-velocity event) 0))) |
42 (let ((pitch (midi:message-key event)) | 42 (let ((pitch (midi:message-key event)) |
43 (channel (1+ (midi:message-channel event))) | 43 (channel (midi:message-channel event)) |
44 (t-off (midi:message-time event))) | 44 (t-off (midi:message-time event))) |
45 (if (aref ons channel pitch) | 45 (if (aref ons channel pitch) |
46 (push (make-event-from-on-off-pair (aref ons channel pitch) | 46 (push (make-event-from-on-off-pair (aref ons channel pitch) |
47 t-off | 47 t-off |
48 division | 48 division |
52 ;; if there's no matching on, wait until the beat | 52 ;; if there's no matching on, wait until the beat |
53 ;; is done. | 53 ;; is done. |
54 (push event offs)))) | 54 (push event offs)))) |
55 ((typep event 'midi:note-on-message) | 55 ((typep event 'midi:note-on-message) |
56 (let ((pitch (midi:message-key event)) | 56 (let ((pitch (midi:message-key event)) |
57 (channel (1+ (midi:message-channel event))) | 57 (channel (midi:message-channel event)) |
58 (t-off (midi:message-time event))) | 58 (t-off (midi:message-time event))) |
59 (when (aref ons channel pitch) | 59 (when (aref ons channel pitch) |
60 ;; there's a note already sounding. End it. | 60 ;; there's a note already sounding. End it. |
61 (push (make-event-from-on-off-pair (aref ons channel pitch) | 61 (push (make-event-from-on-off-pair (aref ons channel pitch) |
62 t-off | 62 t-off |
75 (timepoint (car time-sigs))))) | 75 (timepoint (car time-sigs))))) |
76 (push (make-instance 'basic-time-signature | 76 (push (make-instance 'basic-time-signature |
77 :time (/ (midi:message-time event) | 77 :time (/ (midi:message-time event) |
78 division) | 78 division) |
79 :numerator (midi:message-numerator event) | 79 :numerator (midi:message-numerator event) |
80 :denominator (midi:message-denominator event)) | 80 :denominator (expt 2 (midi:message-denominator event))) |
81 time-sigs)) | 81 time-sigs)) |
82 ((typep event 'midi:tempo-message) | 82 ((typep event 'midi:tempo-message) |
83 (when tempi | 83 (when tempi |
84 (setf (duration (car tempi)) | 84 (setf (duration (car tempi)) |
85 (- (/ (midi:message-time event) | 85 (- (/ (midi:message-time event) |
89 :time (/ (midi:message-time event) | 89 :time (/ (midi:message-time event) |
90 division) | 90 division) |
91 :bpm (microsecond-per-crotchet-to-bpm (midi:message-tempo event))) | 91 :bpm (microsecond-per-crotchet-to-bpm (midi:message-tempo event))) |
92 tempi)) | 92 tempi)) |
93 ((typep event 'midi:program-change-message) | 93 ((typep event 'midi:program-change-message) |
94 (setf (aref patches (1+ (midi:message-channel event))) | 94 (setf (aref patches (midi:message-channel event)) |
95 (midi:message-program event))) | 95 (midi:message-program event))) |
96 (t (incf misses)))))) | 96 (t (incf misses)))))) |
97 (when tempi | 97 (when tempi |
98 (setf (duration (car tempi)) (- (/ last-time division) (timepoint (car tempi))))) | 98 (setf (duration (car tempi)) (- (/ last-time division) (timepoint (car tempi))))) |
99 (when time-sigs | 99 (when time-sigs |
100 (setf (duration (car time-sigs)) (- (/ last-time division) (timepoint (car time-sigs))))) | 100 (setf (duration (car time-sigs)) (- (/ last-time division) (timepoint (car time-sigs))))) |
101 ;; make a midi object from notes, etc. | 101 ;; make a midi object from notes, etc. |
102 (let ((composition (make-instance 'midi-composition | 102 (let ((composition (make-instance 'midi-composition |
103 :time 0 | 103 :time 0 |
104 :interval (/ last-time division) | 104 :interval (/ last-time division) |
105 :time-signatures (sort time-sigs #'time<) | 105 :time-signatures (if time-sigs |
106 (sort time-sigs #'time<) | |
107 (list (make-instance 'basic-time-signature | |
108 :time 0 | |
109 :interval (/ last-time division) | |
110 :numerator 4 | |
111 :denominator 4))) | |
106 :tempi (sort tempi #'time<)))) | 112 :tempi (sort tempi #'time<)))) |
107 (sequence:adjust-sequence composition | 113 (sequence:adjust-sequence composition |
108 (length notes) | 114 (length notes) |
109 :initial-contents (sort notes #'time<))))) | 115 :initial-contents (sort notes #'time<))))) |
110 | 116 |
111 (defparameter *short* nil) | |
112 | |
113 (defun make-event-from-on-off-pair (note-on cut-off divisions track patch) | 117 (defun make-event-from-on-off-pair (note-on cut-off divisions track patch) |
114 (when (< (/ (- cut-off (midi:message-time note-on)) divisions) 1/8) | |
115 (push (cons note-on cut-off) *short*)) | |
116 (cond | 118 (cond |
117 ((or (= (midi:message-channel note-on) 9) | 119 ((or (= (midi:message-channel note-on) 9) |
118 (> patch 111)) | 120 (> patch 111)) |
119 ;; percussive | 121 ;; percussive |
120 (make-instance 'midi-percussive-event | 122 (make-instance 'midi-percussive-event |