annotate implementations/gsharp/gsharp-import.lisp @ 253:b5ffec94ae6d

some very sketchy Charm constituent code
author Jamie Forth <j.forth@gold.ac.uk>
date Thu, 24 Feb 2011 11:23:18 +0000
parents 22ac5ec1733c
children bc893627f92d
rev   line source
csr21@59 1 (in-package "AMUSE-GSHARP")
csr21@59 2
d@197 3 (defun make-gsharp-composition (events buffer timepoint interval &key tempi key-signatures time-signatures)
d@197 4 (let ((comp (make-instance 'gsharp-composition :buffer buffer :time timepoint :interval interval
d@197 5 :tempi tempi :key-signatures key-signatures :time-signatures time-signatures)))
d@197 6 (sequence:adjust-sequence comp (length events) :initial-contents events)))
d@197 7
csr21@59 8 (defun last-bar-p (bar)
csr21@59 9 ;; I know most of this file is cut-and-pasted, but this is a
csr21@59 10 ;; particularly horrible example.
csr21@59 11 (eq bar (car (last (gsharp-buffer:bars (gsharp-buffer:slice bar))))))
csr21@59 12
csr21@59 13 (defun find-next-note (note)
csr21@59 14 (when (gsharp-buffer:tie-right note)
csr21@59 15 (let ((bar (gsharp-buffer:bar (gsharp-buffer:cluster note)))
csr21@59 16 (cluster (gsharp-buffer:cluster note))
csr21@59 17 (next-element nil))
csr21@59 18 (loop for (x y) on (gsharp-buffer:elements bar)
csr21@59 19 until (null y)
csr21@59 20 when (eq x cluster) do (setq next-element y))
csr21@59 21 (cond
csr21@59 22 (next-element)
csr21@59 23 ((last-bar-p bar) (return-from find-next-note nil))
csr21@59 24 (t (let ((next-bar (gsharp-buffer:barno (gsharp-buffer:slice bar)
csr21@59 25 (1+ (gsharp-numbering::number bar)))))
csr21@59 26 (if (gsharp-buffer:elements next-bar)
csr21@59 27 (setq next-element (car (gsharp-buffer:elements next-bar)))
csr21@59 28 (return-from find-next-note nil)))))
csr21@59 29 ;; now NEXT-ELEMENT is the next element!
csr21@59 30 (when (typep next-element 'gsharp-buffer:cluster)
csr21@59 31 (loop for n in (gsharp-buffer:notes next-element)
csr21@59 32 if (and (gsharp-buffer:tie-left n)
csr21@59 33 (= (gsharp-buffer:pitch n) (gsharp-buffer:pitch note))
csr21@59 34 (eq (gsharp-buffer:staff n) (gsharp-buffer:staff note))
csr21@59 35 (eq (gsharp-buffer:accidentals n) (gsharp-buffer:accidentals note)))
csr21@59 36 return n)))))
csr21@59 37
csr21@59 38 (defun compute-duration (note)
csr21@59 39 (loop for n = note then (find-next-note n)
csr21@59 40 while n
csr21@59 41 sum (gsharp-buffer:duration (gsharp-buffer:cluster n))))
csr21@59 42
c@61 43 (defun events-from-element (element index time)
d@197 44 (typecase element
d@197 45 (gsharp-buffer:cluster
d@197 46 (mapcar (lambda (note)
d@197 47 (make-instance 'gsharp-pitched-event
d@197 48 :note note
d@197 49 :slice-index index
d@197 50 :number (gsharp-play::midi-pitch note)
d@197 51 :time time
d@197 52 :interval (* 4 (compute-duration note))))
d@197 53 (remove-if #'gsharp-buffer:tie-left (gsharp-buffer:notes element))))
d@197 54 (gsharp-buffer:key-signature
d@197 55 (list (make-gsharp-key-signature-period element time nil)))
d@197 56 (gsharp-buffer::time-signature
d@197 57 (list (make-gsharp-time-signature-period element time nil)))))
csr21@59 58
c@61 59 (defun events-from-bar (bar index time)
csr21@59 60 (mapcan (lambda (element)
c@61 61 (prog1 (events-from-element element index time)
csr21@59 62 (incf time (* 4 (gsharp-buffer:duration element)))))
csr21@59 63 (gsharp-buffer:elements bar)))
csr21@59 64
c@61 65 (defun events-from-slice (slice index durations)
csr21@59 66 (let ((time 0))
csr21@59 67 (mapcan (lambda (bar duration)
c@61 68 (prog1 (events-from-bar bar index time)
csr21@59 69 (incf time (* 4 duration))))
csr21@59 70 (gsharp-buffer:bars slice) durations)))
csr21@59 71
csr21@59 72 (defun segment-composition (segment)
csr21@59 73 (let* ((slices (mapcar #'gsharp-buffer:body (gsharp-buffer::layers segment)))
d@197 74 (durations (gsharp-play::measure-durations slices))
csr21@59 75 (gsharp-play::*tuning* (gsharp-buffer:tuning segment))
d@197 76 (key-signatures (get-initial-keysigs segment))
d@197 77 (time-signatures)
d@197 78 (events (loop for slice in slices
d@197 79 for i from 0
d@197 80 for events = (events-from-slice slice i durations)
d@197 81 then (merge 'list events (events-from-slice slice i durations) 'time<)
d@197 82 finally (return events)))
d@197 83 (duration (* 4 (reduce #'+ durations))))
d@197 84 (multiple-value-setq (events key-signatures time-signatures)
d@197 85 (filter-event-list-for-signatures events key-signatures duration))
d@197 86
d@197 87 ;; FIXME: TEMPI here will break as soon as gsharp is made to have
d@197 88 ;; a sane divisions value in play.lisp instead of 25
d@197 89 (make-gsharp-composition events (gsharp::buffer segment) 0 duration
d@197 90 :tempi (list (make-standard-tempo-period (* 128 (/ (* 4 25) (gsharp-buffer:tempo segment)))
d@197 91 0 duration))
d@197 92 :key-signatures key-signatures
d@197 93 :time-signatures time-signatures)))
d@197 94
d@197 95 (defun filter-event-list-for-signatures (events key-signatures duration)
d@197 96 "key-signatures here are initial `staff-level' signatures (what
d@197 97 MusicXML calls attributes). MusicXML also has time sigs in the
d@197 98 attributes, but GSharp converts them to normal elements."
d@197 99 (let ((filtered-events) (time-signatures)
d@197 100 (staves-data (mapcar #'(lambda (k)
d@197 101 (list (gsharp::staff (gsh-source k)) k nil))
d@197 102 key-signatures)))
d@197 103 (dolist (event events)
d@197 104 (typecase event
d@197 105 (gsharp-pitched-event (push event filtered-events))
d@197 106 (gsharp-key-signature-period
d@197 107 (if (assoc (gsharp::staff (gsh-source event)) staves-data)
d@197 108 (let ((data (assoc (gsharp::staff (gsh-source event)) staves-data)))
d@197 109 (if (second data)
d@197 110 (setf (duration (second data)) (- (timepoint event) (timepoint (second data)))
d@197 111 (second data) event)
d@197 112 (setf (second data) event)))
d@197 113 (acons (gsharp::staff (gsh-source event)) (list event nil) staves-data))
d@197 114 (push event key-signatures))
d@197 115 (gsharp-time-signature-period
d@197 116 (if (assoc (gsharp::staff (gsh-source event)) staves-data)
d@197 117 (let ((data (assoc (gsharp::staff (gsh-source event)) staves-data)))
d@197 118 (if (third data)
d@197 119 (setf (duration (third data)) (- (timepoint event) (timepoint (third data)))
d@197 120 (third data) event)
d@197 121 (setf (third data) event)))
d@197 122 (acons (gsharp::staff (gsh-source event)) (list nil event) staves-data))
d@197 123 (push event time-signatures))))
d@197 124 (loop for item in staves-data
d@197 125 when (second item)
d@197 126 do (setf (duration (second item)) duration)
d@197 127 when (third item)
d@197 128 do (setf (duration (third item)) duration))
d@197 129 (values (reverse filtered-events) (reverse key-signatures) (reverse time-signatures))))
d@197 130
d@197 131 (defun get-initial-keysigs (segment)
d@197 132 (let ((staves (remove-duplicates
d@197 133 (loop for layer in (gsharp::layers segment)
d@197 134 nconc (gsharp::staves layer)))))
d@197 135 (loop for staff in staves
d@197 136 collect (make-gsharp-key-signature-period (gsharp::keysig staff) 0 nil))))
csr21@59 137
csr21@59 138 #|
csr21@59 139
csr21@59 140 (in-package :clim-user)
csr21@59 141
c@60 142 (define-command (com-amuse-play :name t :command-table gsharp::global-gsharp-table)
csr21@59 143 ()
csr21@59 144 (let* ((segment (gsharp-cursor::segment (gsharp::current-cursor)))
csr21@59 145 (composition (amuse-gsharp::segment-composition segment)))
csr21@59 146 (amuse-utils::play composition)))
csr21@59 147
c@60 148 (define-command (com-infer-key :name t :command-table gsharp::global-gsharp-table)
csr21@59 149 ()
csr21@59 150 (let* ((segment (gsharp-cursor::segment (gsharp::current-cursor)))
csr21@59 151 (composition (amuse-gsharp::segment-composition segment))
c@94 152 (result (amuse-harmony:krumhansl-key-finder composition composition))
csr21@59 153 (name (aref #("C" "C#" "D" "Eb" "E" "F" "F#" "G" "Ab" "A" "Bb" "B") (car result)))
csr21@59 154 (string (format nil "Key: ~A ~(~A~)" name (cadr result))))
c@91 155 (esa:display-message string)))
csr21@59 156
csr21@59 157
c@60 158 (in-package :gsharp-measure)
c@60 159
c@92 160 (define-stealth-mixin snote () note
c@60 161 ((misspeltp :initform nil :accessor misspeltp)))
c@60 162
c@60 163 (in-package :gsharp-drawing)
c@60 164
c@60 165 ;;; patch DRAW-NOTE
c@60 166 (defun draw-note (pane note notehead nb-dots x pos dot-xoffset dot-pos)
c@60 167 (score-pane:with-vertical-score-position (pane (staff-yoffset (staff note)))
c@61 168 (cond
c@61 169 ((gsharp-measure::misspeltp note)
c@61 170 (with-output-as-presentation (pane note 'note)
c@61 171 (score-pane:draw-notehead pane notehead x pos))
c@61 172 (let ((ypos (score-pane:staff-step (- pos))))
c@61 173 (draw-line* pane (- x 5) (+ ypos 3) (+ x 5) (+ ypos 3)
c@61 174 :line-thickness 3 :ink (make-rgb-color 0.8 0.1 0.1))))
c@61 175 (t (score-pane:draw-notehead pane notehead x pos)))
c@60 176 (when (final-accidental note)
c@60 177 (score-pane:draw-accidental pane (final-accidental note) (final-absolute-accidental-xoffset note) pos))
c@60 178 (draw-dots pane nb-dots x dot-xoffset dot-pos)))
c@60 179
c@60 180 (in-package :clim-user)
c@60 181
c@60 182 (defun ocp-list (composition)
c@60 183 (flet ((sorter (x y)
c@60 184 (or (amuse:time< x y)
c@60 185 (and (amuse:time= x y)
c@60 186 (amuse:pitch< x y)))))
c@60 187 (loop for e being each element of composition
c@60 188 if (typep e 'amuse:pitched-event)
c@60 189 collect (cons e (make-array 2 :initial-contents
c@60 190 (list (slot-value e 'amuse::time)
c@60 191 (- (slot-value e 'amuse::number) 21)))) into result
c@60 192 finally (return (sort result #'sorter :key #'car)))))
c@60 193
c@60 194 (let ((accidental-conversions
c@60 195 '(("ss" . :double-sharp) ("s" . :sharp) ("n" . :natural)
c@60 196 ("f" . :flat) ("ff" . :double-flat))))
c@60 197 (defun annotate-misspellings (composition)
c@60 198 (do* ((ocp-list (ocp-list composition))
c@93 199 (note-sequence (ps13:ps13-new-imp (map 'list #'cdr ocp-list) 10 42 nil nil nil))
c@60 200 (list ocp-list (cdr list))
c@60 201 (spellings note-sequence (cdr spellings)))
c@60 202 ((null list))
c@60 203 (let* ((event (caar list))
csr21@62 204 (note (amuse-gsharp:note event))
c@61 205 (accidental (elt (second (car spellings)) 1))
c@61 206 (converted (cdr (assoc accidental accidental-conversions :test #'string=))))
c@61 207 (unless (eq (gsharp-buffer:accidentals note) converted)
c@61 208 ;; this pun is not to be preserved once we get into real
c@61 209 ;; code.
c@61 210 (setf (gsharp-measure::misspeltp note) (second (car spellings))))))))
c@60 211
c@60 212 (define-command (com-spellcheck :name t :command-table gsharp::global-gsharp-table)
c@60 213 ()
c@60 214 (let* ((segment (gsharp-cursor::segment (gsharp::current-cursor)))
c@60 215 (composition (amuse-gsharp::segment-composition segment)))
c@60 216 (annotate-misspellings composition)
c@60 217 #+nil
c@60 218 (esa:display-message "~A" (first (ocp-list composition)))))
c@61 219
c@61 220 (let ((accidental-conversions
c@61 221 '(("ss" . :double-sharp) ("s" . :sharp) ("n" . :natural)
c@61 222 ("f" . :flat) ("ff" . :double-flat))))
c@61 223 (define-command (com-correct-misspelt-note :name t :command-table gsharp::global-gsharp-table)
c@61 224 ((note 'gsharp::note))
c@61 225 (let ((spelling (gsharp-measure::misspeltp note))
c@61 226 (element (gsharp-buffer::cluster note))
c@61 227 (staff (gsharp-buffer::staff note))
c@61 228 (head (gsharp-buffer::head note))
c@61 229 (dots (gsharp-buffer::dots note)))
c@61 230 (let ((pitch (+ (mod (- (digit-char-p (char (elt spelling 0) 0) 17) 12) 7)
c@61 231 (* (parse-integer (elt spelling 2)) 7)))
c@61 232 (accidentals (cdr (assoc (elt spelling 1) accidental-conversions :test #'string=))))
c@61 233 (let ((new-note (gsharp-buffer::make-note pitch staff
c@61 234 :head head
c@61 235 :dots dots
c@61 236 :accidentals accidentals)))
c@61 237 (gsharp-buffer::remove-note note)
c@61 238 (gsharp-buffer::add-note element new-note))))))
c@61 239
c@61 240 (define-presentation-to-command-translator correct-misspelt-note-translator
c@61 241 (gsharp::note com-correct-misspelt-note gsharp::global-gsharp-table
c@61 242 :gesture :select
c@61 243 :tester ((object) (gsharp-measure::misspeltp object)))
c@61 244 (object)
c@61 245 (list object))
c@60 246
csr21@59 247 |#