[fomus-cvs] CVS fomus

dpsenicka dpsenicka at common-lisp.net
Sat Feb 11 22:39:40 UTC 2006


Update of /project/fomus/cvsroot/fomus
In directory common-lisp:/tmp/cvs-serv2217

Modified Files:
	accidentals.lisp backend_cmn.lisp classes.lisp data.lisp 
	main.lisp marks.lisp other.lisp test.lisp util.lisp 
	version.lisp 
Log Message:
bugs/cmn

--- /project/fomus/cvsroot/fomus/accidentals.lisp	2006/01/31 08:19:57	1.16
+++ /project/fomus/cvsroot/fomus/accidentals.lisp	2006/02/11 22:39:40	1.17
@@ -21,45 +21,6 @@
 (defparameter *auto-cautionary-accs* nil)
 
 ;; NOKEY!
-
-(declaim (type (vector boolean) +nokey-quality+))
-(defparameter +nokey-quality+ (vector nil t t nil nil t t))
-
-;; return a white note or nil if not possible
-(defun nokey-spell (note acc)		; acc = -2/-1/0/1/2
-  (declare (type rational note) (type (integer -2 2) acc))
-  (multiple-value-bind (o n) (floor (- note acc) 12)
-    (let ((x (svref +note-to-white+ n)))
-      (when x (values x o)))))
-(defun nokeyq-spell (note acc)		; acc = -2/-1/0/1/2
-  (declare (type rational note) (type (cons (integer -2 2) (rational -1/2 1/2)) acc))
-  (multiple-value-bind (o n) (floor (- note (car acc) (cdr acc)) 12)
-    (let ((x (when (integerp n) (svref +note-to-white+ n))))
-      (when x (values x o)))))
-
-;; return values: int-value (0 - 6), int-quality (0 = perfect, -1/1 = min./maj., -2/2... = dim./aug., nil = ???)
-(defun nokey-int (note1 acc1 note2 acc2)
-  (declare (type rational note1 note2) (type (integer -2 2) acc1 acc2))
-  (multiple-value-bind (s1 o1) (nokey-spell note1 acc1)
-    (multiple-value-bind (s2 o2) (nokey-spell note2 acc2)
-      (multiple-value-bind (sp1 sp2 n1 n2)
-	  (let ((p1 (+ s1 (* o1 7)))
-		(p2 (+ s2 (* o2 7))))
-	    (if (= p1 p2)
-		(if (< note1 note2)
-		    (values p1 p2 note1 note2)
-		    (values p2 p1 note2 note1))
-		(if (< p1 p2)
-		    (values p1 p2 note1 note2)
-		    (values p2 p1 note2 note1))))
-	(let ((b (mod (- sp2 sp1) 7)))
-	  (values b
-		  (let ((x (- (- n2 n1) (svref +white-to-note+ b) (* (floor (- sp2 sp1) 7) 12))))
-		    (if (svref +nokey-quality+ b)
-			(if (>= x 0) (1+ x) x) ; maj./min.
-			(cond ((> x 0) (1+ x)) ; aud./dim.
-			      ((< x 0) (1- x))
-			      (t 0))))))))))
 ;; (declaim (inline nokeyq-int))
 ;; (defun nokeyq-int (note1 acc1 accq1 note2 acc2 accq2)
 ;;   (nokeyint (- note1 accq1) acc1 (- note2 accq2) acc2))
@@ -103,12 +64,12 @@
 (defun nokey-notepen (n a)
   (declare (type rational n) (type (or (integer -2 2) (integer -2 2)) a))
   (* (loop
-      for e of-type (integer -1 1) in (cons 0 (svref +nokey-penalty+ (nokey-spell n a)))
+      for e of-type (integer -1 1) in (cons 0 (svref +nokey-penalty+ (notespelling n a)))
       minimize (diff a e)) *acc-spelling-penalty*))
 (defun nokeyq-notepen (n a)
   (declare (type rational n) (type (or (integer -2 2) (cons (integer -2 2) (rational -1/2 1/2))) a))
   (* (loop
-      for e of-type (integer -1 1) in (cons 0 (svref +nokey-penalty+ (nokeyq-spell n a)))
+      for e of-type (integer -1 1) in (cons 0 (svref +nokey-penalty+ (qnotespelling n a)))
       minimize (diff (car a) e)) *acc-spelling-penalty*))
 
 ;; scores of 1 are perfect
@@ -124,7 +85,7 @@
 	      (values note1 acc1 off1 eoff1 note2 acc2 off2 eoff2)
 	      (values note2 acc2 off2 eoff2 note1 acc1 off1 eoff1)))
     (declare (ignorable o1 eo1 o2 eo2))
-    (multiple-value-bind (i q) (nokey-int n1 a1 n2 a2)
+    (multiple-value-bind (i q) (interval n1 a1 n2 a2)
       (let ((v (- (cond ((and tie (/= i (svref +nokey-harmints+ (mod (diff n1 n2) 12))) #|(or (and (< acc1 0) (> acc2 0)) (and (> acc1 0) (< acc2 0)))|#) 0.0)
 			((find q (svref +nokey-niceints1+ i)) *acc-diatonic-int-score*)
 			((and (= i 0)	; unisons special case
@@ -148,7 +109,7 @@
 	    (min (max (if (or (and (> a1 0) (< a2 0)) (and (< a1 0) (> a2 0)))
 			  (if tie 0.0
 			      (let ((m (if (and (/= qa1 0) (/= qa2 0)) *acc-similar-qtone-score* (/ *acc-similar-qtone-score* 2.0))))
-				(if (= (nokeyq-spell note1 acc1) (nokeyq-spell note2 acc2)) (+ s m) (- s m)))) ; penalize different accs on different written notes
+				(if (= (qnotespelling note1 acc1) (qnotespelling note2 acc2)) (+ s m) (- s m)))) ; penalize different accs on different written notes
 			  s)
 		      0.0) 1.0))))))
 
@@ -275,16 +236,6 @@
 (declaim (type boolean *use-double-accs*))
 (defparameter *use-double-accs* nil)
 
-(declaim (type cons +acc-single+ +acc-double+ +acc-qtones-single+ +acc-qtones-double+))
-(defparameter +acc-single+ '(-1 0 1))
-(defparameter +acc-double+ '(-2 -1 0 1 2))
-(defparameter +acc-qtones-single+ '(-1 0 1 (-1 . -1/2) (0 . -1/2) #|(1 . -1/2) (-1 . 1/2)|# (0 . 1/2) (1 . 1/2)))
-(defparameter +acc-qtones-double+ '(-2 -1 0 1 2 (-1 . -1/2) (0 . -1/2) #|(1 . -1/2) (-1 . 1/2)|# (0 . 1/2) (1 . 1/2)))
-
-(defun nokey-convert-qtone (x)
-  (declare (type (or (cons (integer -2 2) (rational -1/2 1/2)) (integer -2 2)) x))
-  (if (consp x) x (cons x 0)))
-
 ;; Processed before chords exist and before voices are separated
 ;; events in parts are sorted--function must return them sorted
 (defun accidentals (keysigs parts)
@@ -298,9 +249,9 @@
 			   (case (auto-accs-fun)
 			     (:nokey1 (if *quartertones*
 					  (acc-nokey evs (if *use-double-accs* +acc-qtones-double+ +acc-qtones-single+)
-						     #'nokeyq-spell #'nokeyq-notepen #'nokeyq-intscore (part-name e) #'nokey-convert-qtone)
+						     #'qnotespelling #'nokeyq-notepen #'nokeyq-intscore (part-name e) #'convert-qtone)
 					  (acc-nokey evs (if *use-double-accs* +acc-double+ +acc-single+)
-						     #'nokey-spell #'nokey-notepen #'nokey-intscore (part-name e) #'identity)))
+						     #'notespelling #'nokey-notepen #'nokey-intscore (part-name e) #'identity)))
 			     (otherwise (error "Unknown accidental assignment function ~S" *auto-accs-mod*))))
 		    #'sort-offdur)))))
 
@@ -312,26 +263,25 @@
     , at forms))
      
 (defun accidentals-generic (parts)
-  (loop for p of-type partex in parts
-	unless (is-percussion p)
-	do (loop with cho = (if *quartertones*
-				(mapcar #'nokey-convert-qtone +acc-qtones-double+)
-				+acc-double+)
-		 for e of-type (or noteex restex) in (part-events p)
-		 for n = (event-note* e) ;;and a of-type (integer -2 2) = (event-acc e) and q of-type (rational -1/2 1/2) = (event-addacc e)
-		 for ua = (let ((u (event-useracc e)))
-			    (if (list1p u) (if (consp (first u)) (first u) (cons (first u) 0))
-				(if u (error "Only one accidental allowed when :AUTO-ACCIDENTALS is NIL in note at offset ~S, part ~S" (event-foff e) (part-name p))
-				    (cons 0 0))))
-		 unless (and (if *quartertones*
-				 (find ua cho :test #'equal)
-				 (find (car ua) cho))
-			     (nokeyq-spell n ua))
-		 do (error "Invalid note spelling ~S at offset ~S, part ~S" (cond ((/= (cdr ua) 0) (list n (car ua) (cdr ua)))
-										  ((/= (car ua) 0) (list n (car ua)))
-										  (t (list n)))
-			   (event-foff e) (part-name p))
-		 do (setf (event-note e) (cons n ua)))))
+  (flet ((so (d)
+	   (lambda (x y)
+	     (let ((ax (if (consp x) (car x) x))
+		   (ay (if (consp y) (car y) y)))
+	       (if (= (abs ax) (abs ay)) 
+		   (funcall d ax ay)
+		   (< (abs ax) (abs ay)))))))
+    (loop with cho = (if *quartertones*
+			 (mapcar #'convert-qtone +acc-qtones-double+)
+			 +acc-double+)
+	  with chof = (stable-sort (copy-list cho) (so #'<))
+	  and chos = (stable-sort (copy-list cho) (so #'>))
+	  for p of-type partex in parts
+	  unless (is-percussion p)
+	  do (loop for e of-type (or noteex restex) in (part-events p)
+		   do (let ((n (event-note* e)))
+			(setf (event-note e)
+			      (cons n (find-if (lambda (a) (if (consp a) (qnotespelling n a) (notespelling n a)))
+					       (append (event-useracc e) (let ((m (mod n 12))) (if (and (>= m 9/2) (<= m 7)) chos chof)))))))))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; CAUTIONARY ACCIDENTALS
--- /project/fomus/cvsroot/fomus/backend_cmn.lisp	2006/02/05 04:57:33	1.7
+++ /project/fomus/cvsroot/fomus/backend_cmn.lisp	2006/02/11 22:39:40	1.8
@@ -5,6 +5,11 @@
 ;; backend_cmn.lisp
 ;;**************************************************************************************************
 
+;   Unused lexical variable HA, in SAVE-CMN.
+;   Unused lexical variable HS, in SAVE-CMN.
+;   Unused lexical variable XXX (6 references), in SAVE-CMN.
+;   Unused lexical variable TU, in SAVE-CMN.
+
 (in-package :fomus)
 (compile-settings)
 
@@ -55,8 +60,9 @@
 			    (:percussion . percussion)))
 
 (defparameter +cmn-options+ '((automatic-rests nil) (implicit-accidental-duration 1) (implicit-accidental-style :new-style)
-			      (automatic-beams nil) (automatic-octave-signs nil)))
-(defparameter +cmn-changeableopts+ '((all-output-in-one-file t) (size 24)))
+			      (automatic-beams nil) (automatic-octave-signs nil) (automatic-ties nil) (automatic-bars nil)
+			      (automatic-beat-subdivision-numbers nil)))
+(defparameter +cmn-changeableopts+ '((all-output-in-one-file t) (size 24) (text-connecting-pattern '(5 10))))
 
 ;; left out: (:leftheel . ...) (:rightheel . ...) (:lefttoe . ...) (:righttoe . ...)|
 (defparameter +cmn-marks+
@@ -67,9 +73,21 @@
 ;; (:arpeggio . ...) (:pizz . ...) (:arco . ...)
 ;; ((:glissando :after) . ...) ((:portamento :after) . ...) <-- begin/end marks, use setf gliss- and -gliss
 
+(defparameter +cmn-dynamics+
+  '((:pppppp . (dynamic "pppppp")) (:ppppp . (dynamic "ppppp")) (:pppp . pppp) (:ppp . ppp) (:pp . pp) (:p . p) (:mp . mp)
+    (:ffffff . (dynamic "ffffff")) (:fffff . (dynamic "fffff")) (:ffff . ffff) (:fff . fff) (:ff . ff) (:f . f) (:mf . mf)
+    (:sff . sff) (:spp . spp) (:sf . sf) (:sp . sp) (:fp . fp) (:rfz . rfz) (:sfz . sfz)))
+
 (defparameter +cmn-trmarks+
   '((:prall . inverted-mordent) (:trill . trill) (:mordent . mordent) (:startlongtrill- . trill)))
 
+(defparameter +cmn-textstyle+ '((font-name "Times-Italic")))
+(defparameter +cmn-textnotestyle+ '((font-name "Times-Italic")))
+(defparameter +cmn-texttempostyle+ '((font-name "Times-Bold") (font-scaler 2)))
+
+(defparameter +cmn-up+ '(y (lambda (ma no sc &optional ju) (declare (ignore ma sc ju)) (- (staff-y0 no) 1))))
+(defparameter +cmn-down+ '(y (lambda (ma no sc &optional ju) (declare (ignore ma sc ju)) (+ (staff-y0 no) 1))))
+
 (defun internalize (x)
   (typecase x
     (keyword x)
@@ -137,7 +155,7 @@
 					   collect (string x))))
 		   "-"
 		   (string (code-char (+ 64 de)))))))
-	  (let* ((bv -1) (gv -1) (pv -1) (sv -1)
+	  (let* ((bv -1) (gv -1) (pv -1) (sv -1) (ouv -1) (odv -1) (w<v -1) (w>v -1) (tv -1) (rv -1)
 		 (cmp (loop for p in parts nconc
 			    (destructuring-bind (&key (cmn-partname (cmnname p)) &allow-other-keys) (part-opts p)
 			      (loop with nvce = (loop for e in (part-meas p) maximize (length (meas-voices e)))
@@ -145,6 +163,12 @@
 				    and ggg = (make-hash-table :test 'eq)
 				    and ppp = (make-hash-table :test 'eq)
 				    and sss = (make-hash-table :test 'eq)
+				    and ouuu = (make-hash-table :test 'eq)
+				    and oddd = (make-hash-table :test 'eq)
+				    and w<<< = (make-hash-table :test 'eq)
+				    and w>>> = (make-hash-table :test 'eq)
+				    and ttt = (make-hash-table :test 'eq)
+				    and rrr = (make-hash-table :test 'eq)
 				    for vi from 0 below nvce nconc ; loop through voices
 				    (loop with pna = (if (> nvce 1) (format nil "~A~D" cmn-partname (1+ vi)) cmn-partname)
 					  and ns = (instr-staves (part-instr p)) ; number of staves
@@ -166,7 +190,8 @@
 										      (format nil "~A1~D" pna si)
 										      (format nil "~A1" pna)))))) 
 					     ,(lookup (second (find si (getprops p :clef) :key #'third)) +cmn-clefs+)
-					     ,@(loop with o = 0 and st = 1 and gg and pg and sg and wvy
+					     ,@(loop with o = 0 and st = 1 and gg and pg and sg = (make-hash-table) and wvy and oug and odg
+						     and w>g = (make-hash-table) and w<g = (make-hash-table) and tg = (make-hash-table) and rg
 						     for m in (part-meas p) 
 						     and stoff = 0 then (+ stoff lmdur)
 						     for lmdur = (cmndur (- (meas-endoff m) (meas-off m)) m)
@@ -185,7 +210,12 @@
 						      (setf bb e)
 						      when (getmark e '(:glissando :after)) do (setf gg e)
 						      when (getmark e '(:portamento :after)) do (setf pg e)
-						      when (and wvy (getmark e :endlongtrill-)) do (setf (second wvy) co) 
+						      when (getmark e :start8up) do (setf oug e)
+						      when (getmark e :start8down) do (setf odg e)
+						      when (and wvy (getmark e :endlongtrill-)) do (setf (second wvy) co)
+						      do (loop for (xxx lvl) in (getmarks e :startslur-) do (setf (gethash lvl sg) e))
+						      do (loop for (xxx lvl) in (getmarks e :startwedge<) do (setf (gethash lvl w<g) e))
+						      do (loop for (xxx lvl) in (getmarks e :startwedge>) do (setf (gethash lvl w>g) e))
 						      when (= st si) collect
 						      (let ((cd (cmndur (event-dur* e) m)))
 							(nconc (if (restp e)
@@ -257,23 +287,64 @@
 								       ,@(when (eq (car i) :startlongtrill-)
 									       (list '(wavy-line t)
 										     (setf wvy (list 'wavy-time nil))))))
-							       ;; ottavas
+							       (when (or (getmark e :start8up) (getmark e :end8up))
+								 (let ((h (gethash oug ouuu)))
+								   (list (if h
+									     `(begin-octave-up (svref ouvect ,h))
+									     `(setf (svref ouvect ,(setf (gethash oug ouuu) (incf ouv))) (end-octave-up))))))
+							       (when (or (getmark e :start8down) (getmark e :end8down))
+								 (let ((h (gethash odg oddd)))
+								   (list (if h
+									     `(begin-octave-down (svref odvect ,h))
+									     `(setf (svref odvect ,(setf (gethash odg oddd) (incf odv))) (begin-octave-down))))))
 							       (let ((x (getmark e :tremolo)))
 								 (when x (list `(tremolo (tremolo-slashes ,(- (roundint (log (third x) 1/2)) 2))))))
-							       ;;; start/end tremolos
+							       (let ((x (or (getmark e :endtremolo) (getmark e :starttremolo))))
+								 (when x (let* ((tb (- (roundint (log (third x) 1/2)) 2))
+										(bm (max (min (- (roundint (log (event-writtendur* e (meas-timesig m)) 1/2)) 2) tb) 0)))
+									   (list (let ((h (gethash rg rrr)))
+										   (list (if h
+											     `(begin-tremolo (svref rvect ,h) (tremolo-slashes ,(- tb bm)) (tremolo-beams ,bm))
+											     `(setf (svref rvect ,(setf (gethash rg rrr) (incf rv)))
+											       (end-tremolo (tremolo-slashes ,(- tb bm)) (tremolo-beams ,bm))))))))))
 							       (cond ((getmark e '(:arpeggio :up)) (list '(arpeggio arrow-up)))
 								     ((getmark e '(:arpeggio :down)) (list '(arpeggio arrow-down)))
 								     ((getmark e :arpeggio) (list 'arpeggio)))
-							       ;;; dynamics
-							       ;;; wedges
-							       ;;; text
-							       ;;; slur svect
+							       (loop for i in
+								     (loop for a in +cmn-dynamics+ nconc (mapcar #'force-list (getmarks e (car a))))
+								     collect (lookup (first i) +cmn-dynamics+))
+							       (loop
+								for (xxx lvl) in (nconc (getmarks e :startwedge>) (getmarks e :endwedge>))
+								collect (let ((h (gethash (gethash lvl w>g) w>>>)))
+									  (list (if h
+										    `(-diminuendo (svref wvect> ,h))
+										    `(setf (svref wvect> ,(setf (gethash (gethash lvl w>g) w>>>) (incf w>v))) (diminuendo-))))))
+							       (loop
+								for (xxx lvl) in (nconc (getmarks e :startwedge<) (getmarks e :endwedge<))
+								collect (let ((h (gethash (gethash lvl w<g) w<<<)))
+									  (list (if h
+										    `(-crescendo (svref wvect< ,h))
+										    `(setf (svref wvect< ,(setf (gethash (gethash lvl w<g) w<<<) (incf w<v))) (crescendo-))))))
+							       (loop for x in (nconc (getmarks e :text) (getmarks e :textdyn) (getmarks e :textnote) (getmarks e :texttempo)) collect
+								     (if (eq (first x) :textdyn)
+									 `(dynamic ,(third x))
+									 `(text ,(third x)
+									   ,@(case (first x) (:text +cmn-textstyle+) (:textnote +cmn-textnotestyle+) (:texttempo +cmn-texttempostyle+))
+									   ,(ecase (second x) (:up +cmn-up+) (:down +cmn-down+)))))
+							       (loop for (m lvl dir txt) in (nconc (getmarks e :starttext-) (getmarks e :endtext-)) collect
+								     (let ((h (gethash (gethash lvl tg) ttt)))
+								       (list (if h
+										 `(-text (svref tvect ,h) ,(when (eq m :starttext-) (list txt))
+										   ,(ecase dir (:up +cmn-up+) (:down +cmn-down+)))
+										 `(setf (svref tvect ,(setf (gethash (gethash lvl tg) ttt) (incf tv)))
+										   (text- ,(when (eq m :starttext-) (list txt))
+										    ,(ecase dir (:up +cmn-up+) (:down +cmn-down+))))))))
 							       (loop
-								for xxx in (nconc (getmarks e :startslur-) (getmarks e :endslur-))
-								collect (let ((h (gethash sg sss)))
+								for (xxx lvl) in (nconc (getmarks e :startslur-) (getmarks e :endslur-))
+								collect (let ((h (gethash (gethash lvl sg) sss)))
 									  (list (if h
 										    `(-slur (svref svect ,h))
-										    `(setf (svref svect ,(setf (gethash sg sss) (incf sv))) (slur-))))))
+										    `(setf (svref svect ,(setf (gethash (gethash lvl sg) sss) (incf sv))) (slur-))))))
 							       (when (getmark e :glissando)
 								 (let ((h (gethash gg ggg)))
 								   (list (if h
@@ -299,10 +370,16 @@
 						 (list (list 'output-file (change-filename filename :ext (or out-ext +cmn-out-ext+)))))
 					 :key (lambda (x) (if (consp x) (first x) x)) :from-end t)
 		(let* ,(nconc
-			(if (> bv 0) (list `(bvect (make-array ,(1+ bv)))))
-			(if (> gv 0) (list `(gvect (make-array ,(1+ gv)))))
-			(if (> pv 0) (list `(pvect (make-array ,(1+ pv)))))
-			(if (> sv 0) (list `(svect (make-array ,(1+ sv)))))
+			(if (>= bv 0) (list `(bvect (make-array ,(1+ bv)))))
+			(if (>= gv 0) (list `(gvect (make-array ,(1+ gv)))))
+			(if (>= pv 0) (list `(pvect (make-array ,(1+ pv)))))
+			(if (>= sv 0) (list `(svect (make-array ,(1+ sv)))))
+			(if (>= ouv 0) (list `(ouvect (make-array ,(1+ ouv)))))
+			(if (>= odv 0) (list `(odvect (make-array ,(1+ odv)))))
+			(if (>= tv 0) (list `(tvect (make-array ,(1+ tv)))))
+			(if (>= rv 0) (list `(rvect (make-array ,(1+ rv)))))
+			(if (>= w<v 0) (list `(wvect< (make-array ,(1+ w<v)))))
+			(if (>= w>v 0) (list `(wvect> (make-array ,(1+ w>v)))))
 			cmp) 
 		  ,@(labels ((pfn (pps &optional (grp 1))
 				  (loop for e = (pop pps) ; e = part
--- /project/fomus/cvsroot/fomus/classes.lisp	2006/01/19 00:02:35	1.15
+++ /project/fomus/cvsroot/fomus/classes.lisp	2006/02/11 22:39:40	1.16
@@ -427,7 +427,7 @@
      (type* +dur-base-type+)
      (class* note
       (note (check* (type* +notesym-type+)
-		    "Found ~S, expected REALS or valid note/accidental symbols in the form X, (X X ...) or (X (X X) ...) in NOTE slot" t))
+		    "Found ~S, expected REAL or valid note/accidental symbols in the form X, (X X ...) or (X (X X) ...) in NOTE slot" t))
       (marks (or* null (with-error* ("~~A in MARKS slot") (type* +notemarks-type+))))))))
 
 (defparameter +rest-type+
--- /project/fomus/cvsroot/fomus/data.lisp	2006/02/03 07:17:18	1.31
+++ /project/fomus/cvsroot/fomus/data.lisp	2006/02/11 22:39:40	1.32
@@ -89,8 +89,8 @@
   (let ((a (when (consp no) (rest no)))
 	(no (note-to-num (if (consp no) (first no) no))))
     (if a
-	(cons no (mapcar (lambda (x) (if (and (listp x) (list>1p x))
-					 (cons (acc-to-num (first x) 1) (acc-to-num (second x) 1/2))
+	(cons no (mapcar (lambda (x) (if (listp x)
+					 (if (list>1p x) (cons (acc-to-num (first x) 1) (acc-to-num (second x) 1/2)) (acc-to-num (first x) 1))
 					 (acc-to-num x 1)))
 			 a))
 	no)))
@@ -102,7 +102,7 @@
   (if (symbolp acc) (lookup (symbol-name acc) +accnum+ :test #'string=)
       (roundto acc prec)))
 (defun is-acc (acc)
-  (typecase acc (real acc) (symbol (find (symbol-name acc) +accnum+ :key #'car :test #'string=))))
+  (typecase acc (integer (<= (abs acc) 2)) (symbol (find (symbol-name acc) +accnum+ :key #'car :test #'string=))))
 
 (defun dur-to-num (dur bt)
   (if (and *cm-rhythmfun* *use-cm* (symbolp dur))
@@ -116,7 +116,7 @@
 (defparameter +notesym-type+
   '(or* real symbol
     (cons* (satisfies is-note)
-     (list-of* (or* (satisfies is-acc) (list* (satisfies is-acc) (satisfies is-acc)))))))
+     (or* null (list-of* (or* (satisfies is-acc) (list* (satisfies is-acc)) (list* (satisfies is-acc) (member -1/2 0 1/2))))))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; CLEFS
@@ -343,7 +343,7 @@
 	  (make-instr :ef-trumpet :clefs :treble :tpose 3 :minp 57 :maxp 87 :midiprgch-ex 56)
 	  (make-instr :d-trumpet :clefs :treble :tpose 2 :minp 56 :maxp 86 :midiprgch-ex 56)
 	  (make-instr :c-trumpet :clefs :treble :minp 52 :maxp 84 :midiprgch-ex 56)
-	  (make-instr :bf-trumpet :clefs :treble :tpose -2 :minp 50 :maxp 82 :midiprgch-im '(56 59) :midiprgch-ex 56)
+	  (make-instr :bf-trumpet :clefs :treble :tpose -2 :minp 52 :maxp 82 :midiprgch-im '(56 59) :midiprgch-ex 56)
 	  (make-instr :flugelhorn :clefs :treble :tpose -2 :minp 52 :maxp 82 :midiprgch-ex 56)
 	  (make-instr :ef-bass-trumpet :clefs :treble :tpose -26 :minp 33 :maxp 63 :midiprgch-ex 56)
 	  (make-instr :bf-bass-trumpet :clefs :treble :tpose -26 :minp 28 :maxp 58 :midiprgch-ex 56)
--- /project/fomus/cvsroot/fomus/main.lisp	2006/01/19 00:02:35	1.20
+++ /project/fomus/cvsroot/fomus/main.lisp	2006/02/11 22:39:40	1.21
@@ -114,6 +114,7 @@
 		   (check-ranges pts) #+debug (fomus-proc-check pts 'ranges))	     
 		 (preproc-noteheads pts)
 		 (check-mark-accs pts)
+		 (check-useraccs pts)
 		 (when *transpose*
 		   (when (>= *verbose* 2) (out "~&; Transpositions..."))
 		   (transpose pts) #+debug (fomus-proc-check pts 'transpose))
--- /project/fomus/cvsroot/fomus/marks.lisp	2006/02/03 07:17:18	1.16
+++ /project/fomus/cvsroot/fomus/marks.lisp	2006/02/11 22:39:40	1.17
@@ -53,7 +53,7 @@
   (loop for (startsym contsym endsym xxx symlvl) of-type (symbol symbol symbol t (or symbol (integer 1))) in spanners
 	do (loop for p of-type partex in pts do
 		 (loop
-		  with ss = (make-hash-table :test 'eql) and nu of-type (integer 0) = 0 and sta and mor of-type list
+		  with ss = (make-hash-table :test 'eql) and nu of-type (integer 0) = 0 and sta and staa and mor of-type list
 		  for (e nxe) of-type ((or noteex restex) (or noteex restex null)) on (reverse (part-events p)) do ; go backwards, find endsyms
 		  (setf mor nil)
 		  (loop
@@ -89,10 +89,12 @@
 					 (decf nu))
 				  (error "Levels for marks ~S, ~S and ~S are out of order at offset ~S, part ~S" startsym contsym endsym (event-foff e) (part-name p)))
 			      (progn 
-				(loop for (a b) of-type ((or noteex restex) (or noteex restex null)) on sta
+				(loop for (a b) of-type ((or noteex restex) (or noteex restex null)) on (or (lookup n sta) staa)
 				      if b do (addmark a (list contsym 1)) else do (addmark a (list endsym 1))
 				      (addmark e (nconc (list startsym 1) (when a3 (list a3)) (when a2 (list a2))
-							(when (and a1 symlvl) (list a1))))))))))
+							(when (and a1 symlvl) (list a1)))))
+				(let ((x (assoc n sta)))
+				  (if x (setf (cdr x) nil) (push (cons n nil) sta))))))))
 		  (loop for lv of-type (integer 1) in mor do
 			(unless (gethash lv ss)
 			  (setf (gethash lv ss) (incf nu))
@@ -100,7 +102,8 @@
 		  (loop for l of-type (integer 1) being each hash-value in ss
 			if nxe do (unless (getmark e (list endsym l)) (addmark e (list contsym l)))
 			else do (addmark e (list startsym l)))
-		  (push e sta)) 
+		  (map nil (lambda (x) (push e (cdr x))) sta)
+		  (push e staa)) 
 		 (print-dot))))
 
 (defun expand-marks (pts)
--- /project/fomus/cvsroot/fomus/other.lisp	2005/11/30 23:51:37	1.12
+++ /project/fomus/cvsroot/fomus/other.lisp	2006/02/11 22:39:40	1.13
@@ -30,13 +30,50 @@
 		    (format t "~&;; WARNING: Note ~S is out of range at offset ~S, part ~S" n (event-foff e) (part-name p))
 		    (return))))) (print-dot)))
 
+(defun check-useraccs (pts)
+  (declare (type list pts))
+  (loop for p of-type partex in pts
+	unless (is-percussion p)
+	do (loop with cha
+		 for e of-type (or noteex restex) in (part-events p)
+		 when (notep e) do (when (event-useracc e)
+				     (loop with n = (event-note* e) and ch
+					   for a of-type (or cons (integer -2 2)) in (event-useracc e)
+					   if (if (and *quartertones* (consp a))
+						  (qnotespelling n a)
+						  (and (numberp a) (notespelling n a))) collect a into re else do (setf ch t cha t)
+					   finally (when ch (setf (event-note e) (cons n re)))))
+		 finally (when cha (format t "~&;; WARNING: Bad note spellings removed in part ~S" (part-name p))))
+	(print-dot)))
+
 (defun transpose (pts)
   (declare (type list pts))
   (loop for p of-type partex in pts
 	unless (is-percussion p)
 	do (let ((r (or (instr-tpose (part-instr p)) 0)))
 	     (when r (loop for e of-type (or noteex restex) in (part-events p)
-			   when (notep e) do (decf (event-note* e) r)))) (print-dot)))
+			   when (notep e) do
+			   (if (event-useracc e)
+			       (let* ((n (event-note* e))
+				      (n2 (- n r)))
+				 (setf (event-note e)
+				       (cons n2
+					     (delete-duplicates
+					      (loop for a0 of-type (or cons (integer -2 2)) in (event-useracc e)
+						    for a = (if (consp a0) (car a0) a0)
+						    and aa = (when *quartertones* (if (consp a0) (cdr a0) 0))
+						    nconc (if *quartertones*
+							      (loop for (a2 . aa2) of-type ((integer -2 2) . (rational -1/2 1/2)) in
+								    (mapcar #'convert-qtone +acc-qtones-double+)
+								    when (and (qnotespelling n2 (cons a2 aa2))
+									      (< (abs (nth-value 1 (interval (+ n aa) a (+ n2 aa2) a2))) 2))
+								    collect (if (= aa2 0) a2 (cons a2 aa2)))
+							      (loop for a2 of-type (integer -2 2) in +acc-double+
+								    when (and (notespelling n2 a2) (< (abs (nth-value 1 (interval n a n2 a2))) 2))
+								    collect a2)))
+					      :test #'equal))))
+			       (decf (event-note* e) r)))))
+	(print-dot)))
 
 (defun preproc-noteheads (parts)
   (declare (type list parts))
--- /project/fomus/cvsroot/fomus/test.lisp	2006/02/03 07:17:18	1.23
+++ /project/fomus/cvsroot/fomus/test.lisp	2006/02/11 22:39:40	1.24
@@ -1,11 +1,10 @@
 ;; EXAMPLES
 ;; The majority of these will eventually be part of the documentation as usage examples
-;; It's also a list of what works or almost works
 
 ;; Example 1
 
 (fomus
- :backend '((:data) (:lilypond :view t) (:cmn :view t) (:midi :tempo 120 :delay 1 :play nil))
+ :backend '((:data) (:lilypond :view t) #|(:cmn :view t) (:midi :tempo 120 :delay 1 :play nil)|#)
  :ensemble-type :orchestra
  :parts
  (list
@@ -18,8 +17,8 @@
     collect (make-note :off off
 		       :dur (if (< off 10) 1/2 1)
 		       :note (+ 48 (random 25))
-		       :marks (when (= (mod off 1) 0)
-				'(:ppp*)))))))
+		       :marks (when (= (random 3) 0)
+				'(:staccato)))))))
 
 (fomus
  :backend '((:data) (:lilypond :view t) :musicxml)
@@ -729,7 +728,7 @@
 (fomus					; :auto-ottavas
  :backend '((:data) (:lilypond :view t))
  :ensemble-type :orchestra
- :auto-ottavas nil
+ :auto-ottavas t
  :parts
  (list
   (make-part
--- /project/fomus/cvsroot/fomus/util.lisp	2006/01/31 08:19:57	1.21
+++ /project/fomus/cvsroot/fomus/util.lisp	2006/02/11 22:39:40	1.22
@@ -62,6 +62,12 @@
 (defparameter +note-to-white+ (vector 0 nil 1 nil 2 3 nil 4 nil 5 nil 6))
 (defparameter +white-to-note+ (vector 0 2 4 5 7 9 11))
 
+(declaim (type cons +acc-single+ +acc-double+ +acc-qtones-single+ +acc-qtones-double+))
+(defparameter +acc-single+ '(0 -1 1))
+(defparameter +acc-double+ '(0 -1 1 -2 2))
+(defparameter +acc-qtones-single+ '(0 -1 1 (0 . -1/2) (0 . 1/2) (-1 . -1/2) (1 . 1/2)))
+(defparameter +acc-qtones-double+ '(0 -1 1 -2 2 (0 . -1/2) (0 . 1/2) (-1 . -1/2) (1 . 1/2)))
+
 (defun notetowhite (p)
   (declare (type integer p))
   (multiple-value-bind (o n) (floor p 12)
@@ -71,6 +77,49 @@
   (multiple-value-bind (o n) (floor w 7)
     (+ (* o 12) (svref +white-to-note+ n))))
 
+(declaim (type (vector boolean) +nokey-quality+))
+(defparameter +interval-quality+ (vector nil t t nil nil t t))
+
+;; return a white note or nil if not possible
+(defun notespelling (note acc)		; acc = -2/-1/0/1/2
+  (declare (type rational note) (type (integer -2 2) acc))
+  (multiple-value-bind (o n) (floor (- note acc) 12)
+    (let ((x (svref +note-to-white+ n)))
+      (when x (values x o)))))
+(defun qnotespelling (note acc)		; acc = -2/-1/0/1/2
+  (declare (type rational note) (type (cons (integer -2 2) (rational -1/2 1/2)) acc))
+  (multiple-value-bind (o n) (floor (- note (car acc) (cdr acc)) 12)
+    (let ((x (when (integerp n) (svref +note-to-white+ n))))
+      (when x (values x o)))))
+
+(defun convert-qtone (x)
+  (declare (type (or (cons (integer -2 2) (rational -1/2 1/2)) (integer -2 2)) x))
+  (if (consp x) x (cons x 0)))
+
+;; return values: int-value (0 - 6), int-quality (0 = perfect, -1/1 = min./maj., -2/2... = dim./aug., nil = ???)
+(defun interval (note1 acc1 note2 acc2)
+  (declare (type rational note1 note2) (type (integer -2 2) acc1 acc2))
+  (multiple-value-bind (s1 o1) (notespelling note1 acc1)
+    (multiple-value-bind (s2 o2) (notespelling note2 acc2)
+      (multiple-value-bind (sp1 sp2 n1 n2)
+	  (let ((p1 (+ s1 (* o1 7)))
+		(p2 (+ s2 (* o2 7))))
+	    (if (= p1 p2)
+		(if (< note1 note2)
+		    (values p1 p2 note1 note2)
+		    (values p2 p1 note2 note1))
+		(if (< p1 p2)
+		    (values p1 p2 note1 note2)
+		    (values p2 p1 note2 note1))))
+	(let ((b (mod (- sp2 sp1) 7)))
+	  (values b
+		  (let ((x (- (- n2 n1) (svref +white-to-note+ b) (* (floor (- sp2 sp1) 7) 12))))
+		    (if (svref +interval-quality+ b)
+			(if (>= x 0) (1+ x) x) ; maj./min.
+			(cond ((> x 0) (1+ x)) ; aud./dim.
+			      ((< x 0) (1- x))
+			      (t 0))))))))))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; UTILITY
 
--- /project/fomus/cvsroot/fomus/version.lisp	2006/02/05 04:57:33	1.30
+++ /project/fomus/cvsroot/fomus/version.lisp	2006/02/11 22:39:40	1.31
@@ -12,7 +12,7 @@
 (declaim (type string +title+)
 	 (type cons +version+ +banner+))
 (defparameter +title+ "FOMUS")
-(defparameter +version+ '(0 1 35))
+(defparameter +version+ '(0 1 36))
 (defparameter +banner+
   `("Lisp music notation formatter"
     "Copyright (c) 2005, 2006 David Psenicka, All Rights Reserved"




More information about the Fomus-cvs mailing list