comparison implementations/gsharp/gsharp-import.lisp @ 197:22ac5ec1733c

Basic key and time signature support
author David Lewis <d.lewis@gold.ac.uk>
date Wed, 16 Feb 2011 09:19:12 +0000
parents db4acf840bf0
children bc893627f92d
comparison
equal deleted inserted replaced
196:3b36cf79b525 197:22ac5ec1733c
1 (in-package "AMUSE-GSHARP") 1 (in-package "AMUSE-GSHARP")
2
3 (defun make-gsharp-composition (events buffer timepoint interval &key tempi key-signatures time-signatures)
4 (let ((comp (make-instance 'gsharp-composition :buffer buffer :time timepoint :interval interval
5 :tempi tempi :key-signatures key-signatures :time-signatures time-signatures)))
6 (sequence:adjust-sequence comp (length events) :initial-contents events)))
2 7
3 (defun last-bar-p (bar) 8 (defun last-bar-p (bar)
4 ;; I know most of this file is cut-and-pasted, but this is a 9 ;; I know most of this file is cut-and-pasted, but this is a
5 ;; particularly horrible example. 10 ;; particularly horrible example.
6 (eq bar (car (last (gsharp-buffer:bars (gsharp-buffer:slice bar)))))) 11 (eq bar (car (last (gsharp-buffer:bars (gsharp-buffer:slice bar))))))
34 (loop for n = note then (find-next-note n) 39 (loop for n = note then (find-next-note n)
35 while n 40 while n
36 sum (gsharp-buffer:duration (gsharp-buffer:cluster n)))) 41 sum (gsharp-buffer:duration (gsharp-buffer:cluster n))))
37 42
38 (defun events-from-element (element index time) 43 (defun events-from-element (element index time)
39 (when (typep element 'gsharp-buffer:cluster) 44 (typecase element
40 (mapcar (lambda (note) 45 (gsharp-buffer:cluster
41 (make-instance 'gsharp-pitched-event 46 (mapcar (lambda (note)
42 :note note 47 (make-instance 'gsharp-pitched-event
43 :slice-index index 48 :note note
44 :number (gsharp-play::midi-pitch note) 49 :slice-index index
45 :time time 50 :number (gsharp-play::midi-pitch note)
46 :interval (* 4 (compute-duration note)))) 51 :time time
47 (remove-if #'gsharp-buffer:tie-left (gsharp-buffer:notes element))))) 52 :interval (* 4 (compute-duration note))))
53 (remove-if #'gsharp-buffer:tie-left (gsharp-buffer:notes element))))
54 (gsharp-buffer:key-signature
55 (list (make-gsharp-key-signature-period element time nil)))
56 (gsharp-buffer::time-signature
57 (list (make-gsharp-time-signature-period element time nil)))))
48 58
49 (defun events-from-bar (bar index time) 59 (defun events-from-bar (bar index time)
50 (mapcan (lambda (element) 60 (mapcan (lambda (element)
51 (prog1 (events-from-element element index time) 61 (prog1 (events-from-element element index time)
52 (incf time (* 4 (gsharp-buffer:duration element))))) 62 (incf time (* 4 (gsharp-buffer:duration element)))))
59 (incf time (* 4 duration)))) 69 (incf time (* 4 duration))))
60 (gsharp-buffer:bars slice) durations))) 70 (gsharp-buffer:bars slice) durations)))
61 71
62 (defun segment-composition (segment) 72 (defun segment-composition (segment)
63 (let* ((slices (mapcar #'gsharp-buffer:body (gsharp-buffer::layers segment))) 73 (let* ((slices (mapcar #'gsharp-buffer:body (gsharp-buffer::layers segment)))
64 (durations (gsharp-play::measure-durations slices)) 74 (durations (gsharp-play::measure-durations slices))
65 (gsharp-play::*tuning* (gsharp-buffer:tuning segment)) 75 (gsharp-play::*tuning* (gsharp-buffer:tuning segment))
66 (events (loop for slice in slices 76 (key-signatures (get-initial-keysigs segment))
67 for i from 0 77 (time-signatures)
68 for events = (events-from-slice slice i durations) 78 (events (loop for slice in slices
69 then (merge 'list events (events-from-slice slice i durations) 'time<) 79 for i from 0
70 finally (return events)))) 80 for events = (events-from-slice slice i durations)
71 (let* ((duration (* 4 (reduce #'+ durations))) 81 then (merge 'list events (events-from-slice slice i durations) 'time<)
72 (result (make-instance 'gsharp-composition 82 finally (return events)))
73 :buffer (gsharp-buffer:buffer segment) 83 (duration (* 4 (reduce #'+ durations))))
74 ;; FIXME: this will break as soon as 84 (multiple-value-setq (events key-signatures time-signatures)
75 ;; gsharp is made to have a sane 85 (filter-event-list-for-signatures events key-signatures duration))
76 ;; divisions value in play.lisp 86
77 ;; instead of 25 87 ;; FIXME: TEMPI here will break as soon as gsharp is made to have
78 :tempi (list (make-standard-tempo-period (* 128 (/ (* 4 25) (gsharp-buffer:tempo segment))) 0 duration)) 88 ;; a sane divisions value in play.lisp instead of 25
79 :time 0 89 (make-gsharp-composition events (gsharp::buffer segment) 0 duration
80 :interval duration))) 90 :tempi (list (make-standard-tempo-period (* 128 (/ (* 4 25) (gsharp-buffer:tempo segment)))
81 (sequence:adjust-sequence result (length events) 91 0 duration))
82 :initial-contents events)))) 92 :key-signatures key-signatures
93 :time-signatures time-signatures)))
94
95 (defun filter-event-list-for-signatures (events key-signatures duration)
96 "key-signatures here are initial `staff-level' signatures (what
97 MusicXML calls attributes). MusicXML also has time sigs in the
98 attributes, but GSharp converts them to normal elements."
99 (let ((filtered-events) (time-signatures)
100 (staves-data (mapcar #'(lambda (k)
101 (list (gsharp::staff (gsh-source k)) k nil))
102 key-signatures)))
103 (dolist (event events)
104 (typecase event
105 (gsharp-pitched-event (push event filtered-events))
106 (gsharp-key-signature-period
107 (if (assoc (gsharp::staff (gsh-source event)) staves-data)
108 (let ((data (assoc (gsharp::staff (gsh-source event)) staves-data)))
109 (if (second data)
110 (setf (duration (second data)) (- (timepoint event) (timepoint (second data)))
111 (second data) event)
112 (setf (second data) event)))
113 (acons (gsharp::staff (gsh-source event)) (list event nil) staves-data))
114 (push event key-signatures))
115 (gsharp-time-signature-period
116 (if (assoc (gsharp::staff (gsh-source event)) staves-data)
117 (let ((data (assoc (gsharp::staff (gsh-source event)) staves-data)))
118 (if (third data)
119 (setf (duration (third data)) (- (timepoint event) (timepoint (third data)))
120 (third data) event)
121 (setf (third data) event)))
122 (acons (gsharp::staff (gsh-source event)) (list nil event) staves-data))
123 (push event time-signatures))))
124 (loop for item in staves-data
125 when (second item)
126 do (setf (duration (second item)) duration)
127 when (third item)
128 do (setf (duration (third item)) duration))
129 (values (reverse filtered-events) (reverse key-signatures) (reverse time-signatures))))
130
131 (defun get-initial-keysigs (segment)
132 (let ((staves (remove-duplicates
133 (loop for layer in (gsharp::layers segment)
134 nconc (gsharp::staves layer)))))
135 (loop for staff in staves
136 collect (make-gsharp-key-signature-period (gsharp::keysig staff) 0 nil))))
83 137
84 #| 138 #|
85 139
86 (in-package :clim-user) 140 (in-package :clim-user)
87 141