Mercurial > hg > amuse
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 |