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 @@
,@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"