-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbackend_cmn.lisp
537 lines (516 loc) · 29.7 KB
/
backend_cmn.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
;; -*- lisp -*-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;**************************************************************************************************
;; FOMUS
;; backend_cmn.lisp
;;**************************************************************************************************
(in-package :fomus)
(compile-settings)
#+sbcl (eval-when (:compile-toplevel :load-toplevel :execute) (require :sb-posix))
(eval-when (:load-toplevel :execute)
(defparameter *cmn-view-exe* +ghostview-exe+))
(defparameter *cmn-view-opts* #-(or darwin macos) nil #+(or darwin macos) '("/Applications/Preview.app"))
(defparameter +cmn-comment+ ";; -*- lisp -*-~%;; CMN score file~%;; ~A v~A.~A.~A~%~%")
(defparameter +cmn-num-note+ (vector "C" nil "D" nil "E" "F" nil "G" nil "A" nil "B"))
(defparameter +cmn-num-acc+ (vector 'double-flat 'flat 'natural 'sharp 'double-sharp))
(defparameter +cmn-num-accq+ (vector (vector nil 'double-flat) (vector 'flat-down 'flat 'natural-down) (vector 'natural-down 'natural 'natural-up)
(vector 'natural-up 'sharp 'sharp-up) (vector nil 'double-sharp)))
(defparameter +cmn-barlines+ '((nil . bar) (:single . bar) (:double . interior-double-bar) (:final . double-bar)
(:repeatleft . end-repeat-bar) (:repeatright . begin-repeat-bar) (:repeatleftright . begin-and-end-repeat-bar)
(:invisible . (bar invisible))))
(defparameter +cmn-durations+ '((1/16 . 64th) (3/32 . 64th.)
(1/8 . 32nd) (3/16 . 32nd.)
(1/4 . s) (3/8 . s.) (7/16 . s..)
(1/6 . ts)
(1/2 . e) (3/4 . e.) (7/8 . e..)
(1/3 . te)
(1 . q) (3/2 . q.) (7/4 . q..)
(2/3 . tq)
(2 . h) (3 . h.) (7/2 . h..)
(4/3 . th)
(4 . w) (6 . w.)
(8 . dw)))
(defparameter +cmn-restdurs+ '((1/32 . one-twenty-eighth-rest)
(1/16 . sixty-fourth-rest)
(1/8 . thirty-second-rest)
(1/4 . sixteenth-rest) (3/8 . dotted-sixteenth-rest)
(1/2 . eighth-rest) (3/4 . dotted-eighth-rest)
(1 . quarter-rest) (3/2 . dotted-quarter-rest)
(2 . half-rest) (3 . dotted-half-rest)
(4 . whole-rest) (6 . dotted-whole-rest)
(8 . double-whole-rest)))
(defparameter +cmn-restdursex+ '((1/128 . 'draw-128th-rest)
(1/64 . 'draw-64th-rest)
(1/32 . 'draw-32nd-rest)
(1/16 . 'draw-16th-rest)
(1/8 . 'draw-8th-rest)
(1/4 . 'draw-quarter-rest)
(1/2 . 'draw-half-rest)
(1 . 'draw-whole-rest)
(2 . 'draw-double-whole-rest)))
(defparameter +cmn-clefs+ '((:subbass-8dn . sub-bass) (:bass-8dn . double-bass) (:c-baritone-8dn . baritone-c) (:f-baritone-8dn . baritone-f) (:tenor-8dn . tenor)
(:subbass . sub-bass) (:alto-8dn . alto) (:bass . bass) (:mezzosoprano-8dn . mezzo-soprano) (:c-baritone . baritone-c) (:f-baritone . baritone-f)
(:soprano-8dn . soprano) (:tenor . tenor) (:subbass-8up . sub-bass) (:treble-8dn . tenor-treble) (:alto . alto) (:bass-8up . bass)
(:mezzosoprano . mezzo-soprano) (:c-baritone-8up . baritone-c) (:f-baritone-8up . baritone-f) (:soprano . soprano) (:tenor-8up . tenor)
(:treble . treble) (:alto-8up . alto) (:mezzosoprano-8up . mezzo-soprano) (:soprano-8up . soprano) (:treble-8up . double-treble)
(:percussion . percussion)))
(defparameter +cmn-textstyleexc+ '((font-name "Times-Bold") (font-scaler 1/2)))
(defparameter +cmn-textstyle+ '((font-name "Times-Italic") (font-scaler 1/2)))
(defparameter +cmn-textnotestyle+ '((font-name "Times-Italic") (font-scaler 1/2)))
(defparameter +cmn-texttempostyle+ '((font-name "Times-Bold") (font-scaler 1/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))))
(defparameter +cmn-options+ '((automatic-rests nil) (implicit-accidental-duration 1) (implicit-accidental-style :new-style)
(automatic-beams nil) (automatic-octave-signs nil) (automatic-ties nil) (automatic-bars nil)
(automatic-beat-subdivision-numbers nil) (automatic-naturals 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+
`((:accent . accent) (:marcato . marcato) (:staccatissimo . (text "!" ,@+cmn-textstyleexc+ ,+cmn-up+)) (:staccato . staccato) (:tenuto . tenuto)
(:portato . (text "|." ,@+cmn-textstyleexc+ ,+cmn-up+)) (:upbow . up-bow) (:downbow . down-bow)
(:thumb . thumb) (:open . open-note) (:stopped . stopped-note) ((:breath :after) . breath-mark) (:fermata . fermata)
(:leftheel . (text "l heel" ,@+cmn-textstyleexc+ ,+cmn-up+)) (:rightheel . (text "r heel" ,@+cmn-textstyleexc+ ,+cmn-up+))
(:lefttoe . (text "l toe" ,@+cmn-textstyleexc+ ,+cmn-up+)) (:righttoe . (text "r toe" ,@+cmn-textstyleexc+ ,+cmn-up+))))
(defparameter +cmn-noteheads+
'((:harmonic . (note-head :artificial-harmonic)) (:diamond . (note-head :diamond-1)) (:x . (note-head :x)) (:xcircle . (note-head :circled-x))
(:triangle . (note-head :triangle)) (:slash . (note-head :slash))
(:touched . (note-head :artificial-harmonic)) (:sounding . open-note)))
;; (: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-keysigs+
'((:cmaj . c-major) (:amin . a-minor)
(:gmaj . g-major) (:emin . e-minor)
(:dmaj . d-major) (:bmin . b-minor)
(:amaj . a-major) (:f+min . fs-minor)
(:emaj . e-major) (:c+min . cs-minor)
(:bmaj . b-major) (:g+min . gs-minor) (:c-maj . cf-major) (:a-min . af-minor)
(:f+maj . fs-major) (:d+min . ds-minor) (:g-maj . gf-major) (:e-min . ef-minor)
(:c+maj . cs-major) (:a+min . as-minor) (:d-maj . df-major) (:b-min . bf-minor)
(:a-maj . af-major) (:fmin . f-minor)
(:e-maj . ef-major) (:cmin . c-minor)
(:b-maj . bf-major) (:gmin . g-minor)
(:fmaj . f-major) (:dmin . d-minor)))
(defun internalize (x)
(typecase x
(keyword x)
(symbol (intern (symbol-name x)))
(list (mapcar #'internalize x))
(otherwise x)))
(defparameter +cmn-out-ext+ "eps")
(defun view-cmn (filename options view)
(when (not *cmn-exists*) ;; for viewing only
(format t ";; ERROR: Common Music Notation required for CMN compiling/viewing~%")
(return-from view-cmn))
(when (>= *verbose* 1) (out (if view ";; Compiling/opening ~S for viewing...~%" ";; Compiling ~S...~%") filename))
(destructuring-bind (&key view-exe view-opts out-ext &allow-other-keys) options
(flet ((er (str)
(format t ";; ERROR: Error ~A CMN file~%" str)
(return-from view-cmn)))
(ignore-errors (delete-file (change-filename filename :ext (or out-ext +cmn-out-ext+))))
(#+cmu unix:unix-chdir #+sbcl sb-posix:chdir #+openmcl ccl:cwd #+allegro excl:chdir #+lispworks hcl:change-directory #+clisp ext:cd
(change-filename filename :name nil :ext nil))
(if (ignore-errors (load filename))
(progn
(unless (probe-file (change-filename filename :ext (or out-ext +cmn-out-ext+))) (er "compiling"))
(when view
(unless #+(or cmu sbcl openmcl) (ignore-errors
(#+cmu extensions:run-program #+sbcl sb-ext:run-program #+openmcl ccl:run-program
(or view-exe *cmn-view-exe*)
(append (or view-opts *cmn-view-opts*)
(list (change-filename filename :ext (or out-ext +cmn-out-ext+))))
:wait nil))
#+clisp (eql (ignore-errors
(ext:run-program
(or view-exe *cmn-view-exe*)
:arguments
(append (or view-opts *cmn-view-opts*)
(list (change-filename filename :ext (or out-ext +cmn-out-ext+))))
:output nil
:wait nil)) 0)
#+lispworks (ignore-errors
(system:call-system (format nil "~A~{ ~A~}" (or view-exe *cmn-view-exe*)
(append (or view-opts *cmn-view-opts*)
(list (change-filename filename :ext (or out-ext +cmn-out-ext+))))
:wait nil)))
#+allegro (eql (run-allegro-cmd
(apply #'vector (cons (or view-exe *cmn-view-exe*)
(cons (or view-exe *cmn-view-exe*)
(append (or view-opts *cmn-view-opts*)
(list (change-filename filename :ext (or out-ext +cmn-out-ext+))))))) nil nil)
0)
(er "viewing"))))
(er "compiling")))))
;; multinote trems???
(defun save-cmn (parts header filename options process view)
(when (>= *verbose* 1) (out ";; Saving CMN file ~S...~%" filename))
(with-open-file (f filename :direction :output :if-exists :supersede)
(destructuring-bind (&key score-attr out-ext &allow-other-keys) options
(format f "~A" header)
(let ((de 0) (phash (make-hash-table :test 'equal)))
(flet ((cmndur (val m) (* val (timesig-beat* (meas-timesig m)) 4))
(cmnnote (wnum acc1 acc2 dur hide show caut #|grace|# #|harmt harms|# tl) ;; wdur is actual dur * beat * 4
(let ((acc (unless (or hide tl) (if *quartertones* (svref (svref +cmn-num-accq+ (+ acc1 2)) (1+ (* acc2 2))) (svref +cmn-num-acc+ (+ acc1 2))))))
(when (and acc caut) (setf acc (list acc 'in-parentheses)))
(when (and (equal acc 'natural) (not show)) (setf acc nil))
(nconc ;;(when (and grace (< grace 0)) (list 'grace-note))
;;(when (and grace (>= grace 0)) (list 'appoggiatura))
(list (intern (conc-strings (svref +cmn-num-note+ (mod wnum 12))
(case acc (flat "F") (natural "N") (sharp "S") (otherwise ""))
(format nil "~D" (1- (truncate wnum 12))))))
(when dur (list (or (lookup dur +cmn-durations+) (list 'rq dur))))
(unless (member acc '(nil flat natural sharp)) (list acc)))))
(cmnname (p)
(incf de)
(intern
(conc-strings
(string-upcase
(conc-stringlist (when (part-name p)
(loop for x across (part-name p)
when (alpha-char-p x)
collect (string x)))))
"-"
(string (code-char (+ 64 de)))))))
(let ((bv -1) (gv -1) (pv -1) (sv -1) (ouv -1) (odv -1) (w<v -1) (w>v -1) (tv -1) (rv -1) (iv -1) (uv -1) (rfun nil))
(let ((cmp (loop for p in parts nconc
(destructuring-bind (&key (cmn-partname (cmnname p)) &allow-other-keys) (part-opts p)
(loop with nvce = (mloop for e in (part-meas p) maximize (length (meas-voices e)))
and bbb = (make-hash-table :test 'eq)
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)
and iii = (make-hash-table :test 'equal)
and uuu = (make-hash-table :test 'equal)
for vi from 0 below nvce nconc ; loop through voices
(loop with pna = (if (> nvce 1) (format nil "~A~D" cmn-partname (1+ vi)) (format nil "~A" cmn-partname)) ;; name-let voice
and ns = (instr-staves (part-instr p)) ; number of staves
for si from 1 to ns
for ipna = (intern (if (> ns 1)
(if (> nvce 1)
(format nil "~A~D" pna si)
(format nil "~A1~D" pna si))
pna))
do (setf (gethash p phash) (nconc (gethash p phash) (list ipna)))
collect
`(,ipna
(staff bar
,@(when (and (<= si 1) (part-name p)) (list (list 'staff-name (part-name p))))
,@(when (> vi 0)
(list (list 'tied-to (intern (if (> ns 1)
(format nil "~A1~D" cmn-partname si)
(if (> nvce 1) (format nil "~A1" cmn-partname) (format nil "~A" cmn-partname)))))))
,(lookup (second (find si (getprops p :clef) :key #'third)) +cmn-clefs+)
,@(loop with o = 0 and st = 1 and gg = (cons nil nil) and pg = (cons nil nil) 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 and ug = (make-hash-table)
and pre and tipl and gra1 and gra2 and tra = 0
for (m nxm) on (part-meas p)
and stoff = 0 then (+ stoff lmdur)
for lmdur = (cmndur (- (meas-endoff m) (meas-off m)) m)
when (getprop m :startkey) nconc (let ((x (lookup (second (getprop (meas-timesig m) :keysig)) +cmn-keysigs+)))
(when x (list `(key ,x))))
when (getprop m :startsig) collect `(meter ,(timesig-num (meas-timesig m)) ,(timesig-den (meas-timesig m)))
nconc
(loop
with bb and ee ;;for (pre e nxe) on (cons nil (nth vi (meas-events m))) ;;while e
for (e nxe0) on (nth vi (meas-events m))
for nxe = (or nxe0 (when nxm (first (nth vi (meas-events nxm)))))
for co = (+ stoff (cmndur (- (event-off e) (meas-off m)) m))
;; and (wr . do) = (multiple-value-bind (wr0 do0) (event-writtendur* e (meas-timesig m)) (cons wr0 do0))
;; for enb0 = (if (and (or (getmark e :starttremolo) (getmark e :endtremolo))
;; ;;(< (cmndur (event-dur* e) m) 1) ;; correct, i think
;; (or (< (cmndur (event-dur* e) m) 1/2)
;; (> (nth-value 1 (event-writtendur* e (meas-timesig m))) 0)))
;; (event-nbeams e (meas-timesig m) 1) (event-nbeams e (meas-timesig m)))
for enb = (if (or (getmark e :starttremolo) (getmark e :endtremolo))
(event-nbeams e (meas-timesig m) 1) (event-nbeams e (meas-timesig m)))
for l = (and (notep e) (or (> (event-beamlt e) 0) #|(getmark e :endtremolo)|# (and (> enb 0) (getmark e :endtremolo))))
and r = (and (notep e) (or (> (event-beamrt e) 0) #|(getmark e :starttremolo)|# (and (> enb 0) (getmark e :starttremolo))))
and tipr = (or (and (chordp e) (some #'truep (event-tiert e)) (some #'null (event-tiert e)))
(and nxe (chordp nxe) (some #'truep (event-tielt nxe)) (some #'null (event-tielt nxe))))
do (setf st (or (third (getmark e '(:staff :voice))) st))
unless (or l (event-grace e)) do
(when ee (setf (car ee) '-beam ee nil)) ;;(event-off e)
(when r (setf bb e))
when (getmark e '(:glissando :before)) do (setf (car gg) (cdr gg))
when (getmark e '(:portamento :before)) do (setf (car pg) (cdr pg))
when (getmark e '(:glissando :after)) do (setf (cdr gg) e)
when (getmark e '(:portamento :after)) do (setf (cdr pg) e)
when (getmark e :start8up-) do (setf oug e tra -12)
when (getmark e :start8down-) do (setf odg e tra 12)
when (getmark e :starttremolo-) do (setf rg e)
when (and wvy (getmark e :endlongtrill-)) do (setf (second wvy) (+ co (cmndur (event-dur e) m)))
do
(loop for (xxx lvl) in (getmarks e :startslur-) do (setf (gethash lvl sg) e))
(loop for (xxx lvl) in (getmarks e :startwedge<) do (setf (gethash lvl w<g) e))
(loop for (xxx lvl) in (getmarks e :startwedge>) do (setf (gethash lvl w>g) e))
(loop for (xxx lvl) in (getmarks e :starttup) do (setf (gethash lvl ug) e))
when (= st si) nconc
(let ((not (if (getmark e :measrest)
(if (event-inv e) '(whole-measure-rest invisible) 'whole-measure-rest)
(multiple-value-bind (wr do) (event-writtendur* e (meas-timesig m))
(let ((cd (cmndur (if (event-grace e) (event-gracedur e) (event-dur* e)) m))
(hq `(head-quarters ,(let ((wr0 (if (or (getmark e :starttremolo) (getmark e :endtremolo))
(* wr 2) wr)))
(cond ((>= wr0 1) 4) ((>= wr0 1/2) 3) (t 1))))))
(flet ((doti (ee no)
(let ((h (gethash (cons ee no) iii)))
(list (if h
`(end-tie (svref tvect ,h))
`(setf (svref tvect ,(setf (gethash (cons ee no) iii) (incf iv))) (begin-tie)))))))
(nconc (if (restp e)
(let ((x (lookup cd +cmn-restdurs+)))
(if x (list x)
(progn (setf rfun t) (list 'restex (lookup wr +cmn-restdursex+) `(rq ,cd)))))
(let ((tcd (if (or (getmark e :starttremolo) (getmark e :endtremolo)) ;; correct
(* cd 2) cd)))
(if (chordp e)
(cons 'chord
(nconc
(loop
for n in (event-notes* e)
and w in (event-writtennotes e)
and a in (event-accs e)
and a2 in (event-addaccs e)
and tr in (event-tiert e)
and tl in (event-tielt e)
;;for ha = (getmark e (list :harmonic :touched n))
;;and hs = (getmark e (list :harmonic :sounding n))
for cl = (nconc
(cmnnote (+ w tra) a a2 nil
(getmark e (list :hideacc n))
(getmark e (list :showacc n))
(getmark e (list :cautacc n))
#|(event-grace e)|#
tl
#|(getmark e (list :harmonic :touched n))|#
#|(getmark e (list :harmonic :sounding n))|#)
(list hq)
(when (and tipl tl) (doti pre n))
(when (and tipr tr) (doti e n))
(loop for (xxx ty no) in (append (getmarks e :notehead)
(getmarks e :harmonic))
when (= no n)
collect (lookup ty +cmn-noteheads+)))
if (list1p cl) nconc cl else collect cl)
(list (or (lookup tcd +cmn-durations+) `(rq ,tcd)))))
(cmnnote (+ (event-writtennote e) tra)
(event-acc e) (event-addacc e)
tcd
(getmark e (list :hideacc (event-note* e)))
(getmark e (list :showacc (event-note* e)))
(getmark e (list :cautacc (event-note* e)))
#|(event-grace e)|#
(event-tielt e)
#|(getmark e (list :harmonic :touched (event-writtennote e)))|#
#|(getmark e (list :harmonic :sounding (event-writtennote e)))|#))))
(list `(dots ,do)) ;; SPELLING
(when (and (notep e) (not (chordp e))) (list hq)) ;; SPELLING
(when (notep e) (list `(flags ,enb))) ;; SPELLING
(loop for (xxx lvl) in (nconc (getmarks e :starttup) (getmarks e :endtup)) collect
(let* ((h0 (gethash lvl ug)) ; h0 is event-obj
(h (gethash (cons h0 lvl) uuu)))
(if h
`(-beat-subdivision (svref uvect ,h))
(let ((f0 (getmark h0 (list :starttup lvl))))
`(setf (svref uvect ,(setf (gethash (cons h0 lvl) uuu) (incf uv)))
(beat-subdivision-
(subdivision
,(let ((f (third f0)))
(if (eq *tuplet-style* :ratio)
(format nil "~A:~A" (car f) (cdr f))
(format nil "~A" (car f)))))
,@(unless (fourth f0) (list '(bracketed nil)))))))))
(when (and (notep e) (not (and tipl (chordp e)))
(if (chordp e) (some #'truep (event-tielt e)) (event-tielt e)))
(doti pre (unless (chordp e) (event-note* e))))
(when (and (notep e) (not (and tipr (chordp e)))
(if (chordp e) (some #'truep (event-tiert e)) (event-tiert e)))
(doti e (unless (chordp e) (event-note* e))))
(unless (or (chordp e) (restp e))
(loop with n = (event-note* e)
for (xxx ty no) in (append (getmarks e :notehead)
(getmarks e :harmonic))
when (= no n)
collect (lookup ty +cmn-noteheads+)))
(when (and (> co o) (not (event-grace e))) (list `(onset ,co)))
(when (and (or l r) (not (event-grace e)))
(let ((h (gethash bb bbb)))
(list (if h
(setf ee (list '-beam- `(svref bvect ,h))) ;; -beam- will be resetfed
`(setf (svref bvect ,(setf (gethash bb bbb) (incf bv))) (beam-))))))
(loop for i in
(sort (delete-duplicates
(loop for (a1 . a2) in +cmn-marks+
nconc (mapcar (lambda (x) (cons a2 (force-list x))) (getmarks e a1)))
:key #'cdr :test #'equal)
(lambda (x y) (cond
((find (cadr x) +marks-withacc+) nil)
((find (cadr y) +marks-withacc+) t)
(t (let ((x2 (caddr x)) (y2 (caddr y)))
(cond ((and (numberp x2) (numberp y2)) (< x2 y2))
(x2 t)))))))
collect (car i))
(loop for i in
(delete-duplicates
(loop for (a1 . a2) in +cmn-trmarks+
nconc (mapcar (lambda (x)
(let ((f (force-list x)))
(cons a2 (if (eq (first f) :startlongtrill-) (fifth f) (third f)))))
(getmarks e a1)))
:key #'cdr :test #'equal)
collect
`(,(if (listp (car i)) (caar i) (car i))
,@(when (cdr i)
(list `(ornament-sign
(,(ecase (cdr i)
(-2 'double-flat)
(-3/2 'flat-down)
(-1 'flat)
(-1/2 'natural-down)
(0 'natural)
(1/2 'natural-up)
(1 'sharp)
(3/2 'sharp-up)
(2 'double-sharp))
(scale 1/2 1/2)))))
,@(when (listp (car i))
(list '(wavy-line t)
(setf wvy (list 'wavy-time nil))))))
(when (or (getmark e :start8up-) (getmark e :end8up-))
(let ((h (gethash oug ouuu)))
(list (if h
`(end-octave-up (svref ouvect ,h))
`(setf (svref ouvect ,(setf (gethash oug ouuu) (incf ouv))) (begin-octave-up))))))
(when (or (getmark e :start8down-) (getmark e :end8down-))
(let ((h (gethash odg oddd)))
(list (if h
`(end-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 #|enb|#))))))
(let ((x (or (getmark e :endtremolo) (getmark e :starttremolo))))
(when x (list (let ((h (gethash rg rrr)))
(if h
`(end-tremolo (svref rvect ,h))
`(setf (svref rvect ,(setf (gethash rg rrr) (incf rv)))
(begin-tremolo (tremolo-beams ,(- (roundint (log (third x) 1/2)) 2 enb)))))))))
(cond ((getmark e '(:arpeggio :up)) (list '(arpeggio arrow-up)))
((getmark e '(:arpeggio :down)) (list '(arpeggio arrow-down)))
((getmark e :arpeggio) (list 'arpeggio)))
(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>))
nconc (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<))
nconc (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-)) nconc
(let ((h (gethash (gethash lvl tg) ttt)))
(list (if h
`(-text (svref xvect ,h) ,.(when (eq m :starttext-) (list txt))
,(case dir (:up +cmn-up+) (:down +cmn-down+)))
`(setf (svref xvect ,(setf (gethash (gethash lvl tg) ttt) (incf tv)))
(text- ,.(when (eq m :starttext-) (list txt))
,(case dir (:up +cmn-up+) (:down +cmn-down+))))))))
(loop
for (xxx lvl) in (nconc (getmarks e :startslur-) (getmarks e :endslur-))
nconc (let ((h (gethash (gethash lvl sg) sss)))
(list (if h
`(-slur (svref svect ,h))
`(setf (svref svect ,(setf (gethash (gethash lvl sg) sss) (incf sv))) (slur-))))))
(loop
for (xxx wh) in (getmarks e :glissando)
nconc (let* ((gg0 (ecase wh (:before (car gg)) (:after (cdr gg))))
(h (gethash gg0 ggg)))
(list (if h
`(-glissando (svref gvect ,h))
`(setf (svref gvect ,(setf (gethash gg0 ggg) (incf gv))) (glissando-))))))
(loop
for (xxx wh) in (getmarks e :portamento)
nconc (let* ((pg0 (ecase wh (:before (car pg)) (:after (cdr pg))))
(h (gethash pg0 ppp)))
(list (if h
`(-portamento (svref pvect ,h))
`(setf (svref pvect ,(setf (gethash pg0 ppp) (incf pv))) (portamento-))))))
(when (and (restp e) (event-inv e)) (list 'invisible))
(when (and gra1 (not (event-grace e)))
(prog1 (list `(grace-note ,@(nreverse gra1))) (setf gra1 nil)))
(when (and gra2 (not (event-grace e)))
(prog1 (list `(grace-note (slashed nil) ,@(nreverse gra2))) (setf gra2 nil)))))))))) ;; support rests
(if (event-grace e) (progn (if (< (event-grace e) 0) (push not gra1) (push not gra2)) nil) (list not)))
and do (unless (event-grace e) (setf o (+ co (cmndur (event-dur* e) m))))
do (setf pre e tipl tipr)
when (getmark e :end8up-) do (setf tra 0)
when (getmark e :end8down-) do (setf tra 0)
finally (when ee (setf (car ee) '-beam)))
collect (let ((b (getprop m :barline)))
(if (>= o (+ stoff lmdur))
(lookup (second b) +cmn-barlines+)
(list (lookup (second b) +cmn-barlines+)
`(onset ,(setf o (+ stoff lmdur)))))))))))))))
(setprints
(prin1 (internalize '(in-package cmn)) f)
(fresh-line f)
(prin1
(internalize
`(cmn ,@(remove-duplicates (append +cmn-options+ score-attr +cmn-changeableopts+
(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 ((x `(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 (>= iv 0) (list `(tvect (make-array ,(1+ iv)))))
(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 `(xvect (make-array ,(1+ tv)))))
(if (>= uv 0) (list `(uvect (make-array ,(1+ uv)))))
(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)
(system ,.(mapcan (lambda (e) (gethash e phash)) parts))
;; ,@(labels ((pfn (pps &optional (grp 0))
;; (loop for e = (pop pps) ; e = part
;; while e
;; for gr = (delete-if (lambda (x) (< (second x) grp)) (getprops e :startgroup)) ; startgroups = grp or greater
;; if gr nconc (let* ((gg (first (sort gr #'< :key #'second)))
;; (gl (second gg)) ; gl = level
;; (ps (pfn (loop for i = e then (pop pps) collect i until (getprop i (list :endgroup gl))) (1+ gl))))
;; (case (third gg)
;; ((:group :choirgroup) (list (append '(system bracket) ps)))
;; (:grandstaff (list (append '(system brace) ps)))
;; (otherwise (list (append '(system) ps)))))
;; else nconc (gethash e phash))))
;; (pfn parts))
)))
(if rfun `(flet ((restex (draw &rest args) (let ((r (apply (quote rest) args))) (setf (draw-func r) draw) r))) ,x) x))))
f)
(fresh-line f))))))))
(when process (view-cmn filename options view)))