[gsharp-cvs] CVS gsharp/Mxml
crhodes
crhodes at common-lisp.net
Sat Feb 9 18:43:13 UTC 2008
Update of /project/gsharp/cvsroot/gsharp/Mxml
In directory clnet:/tmp/cvs-serv21297
Modified Files:
mxml.lisp
Log Message:
MusicXML support for staccato and tenuto import and export.
--- /project/gsharp/cvsroot/gsharp/Mxml/mxml.lisp 2008/02/09 18:21:00 1.7
+++ /project/gsharp/cvsroot/gsharp/Mxml/mxml.lisp 2008/02/09 18:43:13 1.8
@@ -201,6 +201,8 @@
(remove-if #'(lambda (s) (not (typep s 'fiveline-staff))) staves)))
(elt melody-staves (parse-mxml-note-staff-number note))))
+(defvar *parsing-in-cluster*)
+
(defun parse-mxml-pitched-note (note staves)
(let* ((staff (parse-mxml-note-staff note staves))
(step (named-pcdata note "step"))
@@ -213,11 +215,16 @@
(estringcase (dom:get-attribute tie "type")
("start" (setf tie-right t))
("stop" (setf tie-left t))))
+ (for-named-elements ("staccato" stacc note)
+ (declare (ignore stacc))
+ (pushnew :staccato (annotations *parsing-in-cluster*)))
+ (for-named-elements ("tenuto" ten note)
+ (declare (ignore ten))
+ (pushnew :tenuto (annotations *parsing-in-cluster*)))
(make-instance 'note :pitch pitch :staff staff :accidentals accidentals
:tie-left tie-left :tie-right tie-right)))
(defvar *parsing-duration-gmeasure-position*)
-(defvar *parsing-in-cluster*)
(defvar *mxml-divisions*)
(defun parse-mxml-note (xnote bars staves lyrics-layer-hash)
;; TODO: There is nothing in MusicXML that stops you from having
@@ -1011,18 +1018,14 @@
(defmethod make-xml-element ((cluster cluster) voice)
;; this maybe should get called earlier. or later. i don't know.
(gsharp-measure::compute-final-accidentals (notes cluster))
- (let ((duration (calculate-duration cluster))
- (type (rhythmic-element-type cluster))
- (dots (dots cluster)))
-
+ (let ((duration (calculate-duration cluster)))
(loop for note in (notes cluster)
- for x from 0
- do (make-xml-note note (> x 0) type dots duration voice))
-
+ for x from 0
+ do (make-xml-note note (> x 0) duration voice cluster))
(when (null (notes cluster))
- ;; it's an empty cluster, a "space"
+ ;; it's an empty cluster, a "space"
(cxml:with-element "forward"
- (cxml:text (write-to-string duration))))))
+ (cxml:text (write-to-string duration))))))
(defmethod make-xml-element ((lyric lyrics-element) voice)
(let ((duration (calculate-duration lyric))
@@ -1067,29 +1070,47 @@
(let ((step (mod pitch 7)))
(list (car (rassoc step *step-to-basenote*)) (/ (- pitch step) 7))))
-(defun make-xml-note (note in-chord type dots duration voice)
- (let ((pitch (gshnote-to-xml (pitch note)))
- (accidental (ecase (final-accidental note)
- ((nil))
- (:sharp "sharp")
- (:natural "natural")
- (:flat "flat")
- (:double-sharp "double-sharp")
- (:sesquisharp "three-quarters-sharp")
- (:semisharp "quarter-sharp")
- (:semiflat "quarter-flat")
- (:sesquiflat "three-quarters-flat")
- (:double-flat "flat-flat")))
- (alter (ecase (accidentals note)
- (:sharp "1")
- (:natural nil)
- (:flat "-1")
- (:double-sharp "2")
- (:sesquisharp "1.5")
- (:semisharp "0.5")
- (:semiflat "-0.5")
- (:sesquiflat "-1.5")
- (:double-flat "-2"))))
+(defun note-accidental (note)
+ (ecase (final-accidental note)
+ ((nil))
+ (:sharp "sharp")
+ (:natural "natural")
+ (:flat "flat")
+ (:double-sharp "double-sharp")
+ (:sesquisharp "three-quarters-sharp")
+ (:semisharp "quarter-sharp")
+ (:semiflat "quarter-flat")
+ (:sesquiflat "three-quarters-flat")
+ (:double-flat "flat-flat")))
+
+(defun note-alter (note)
+ (ecase (accidentals note)
+ (:sharp "1")
+ (:natural nil)
+ (:flat "-1")
+ (:double-sharp "2")
+ (:sesquisharp "1.5")
+ (:semisharp "0.5")
+ (:semiflat "-0.5")
+ (:sesquiflat "-1.5")
+ (:double-flat "-2")))
+
+(defun note-notations-p (note cluster)
+ (or (tie-left note)
+ (tie-right note)
+ (note-articulations-p note cluster)))
+
+(defun note-articulations-p (note cluster)
+ (let ((annotations (annotations cluster)))
+ (or (member :staccato annotations)
+ (member :tenuto annotations))))
+
+(defun make-xml-note (note in-chord duration voice cluster)
+ (let ((type (rhythmic-element-type cluster))
+ (dots (dots cluster))
+ (pitch (gshnote-to-xml (pitch note)))
+ (accidental (note-accidental note))
+ (alter (note-alter note)))
(cxml:with-element "note"
(when in-chord
(cxml:with-element "chord"))
@@ -1113,12 +1134,15 @@
(when (> (hash-table-count *staff-hash*) 1)
(cxml:with-element "staff"
(cxml:text (write-to-string (gethash (staff note) *staff-hash*)))))
-
- ;; Small temptation here to put the if clause on the attribute,
- ;; but remember that a note can have ties in both directions.
- (when (or (tie-left note) (tie-right note))
+ (when (note-notations-p note cluster)
(cxml:with-element "notations"
(when (tie-left note)
(cxml:with-element "tied" (cxml:attribute "type" "stop")))
(when (tie-right note)
- (cxml:with-element "tied" (cxml:attribute "type" "start"))))))))
+ (cxml:with-element "tied" (cxml:attribute "type" "start")))
+ (when (note-articulations-p note cluster)
+ (cxml:with-element "articulations"
+ (when (member :staccato (annotations cluster))
+ (cxml:with-element "staccato"))
+ (when (member :tenuto (annotations cluster))
+ (cxml:with-element "tenuto")))))))))
More information about the Gsharp-cvs
mailing list