From 446589a643517817e436465c7875413ff918c543 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Wed, 4 Feb 2004 01:38:31 +0000 Subject: [PATCH] * input/regression/new-part-combine-solo-global.ly: new file. * scm/part-combiner.scm: rewrite. --- ChangeLog | 6 + .../new-part-combine-solo-global.ly | 18 + input/regression/new-part-combine-solo.ly | 3 +- scm/part-combiner.scm | 333 +++++++++++------- 4 files changed, 229 insertions(+), 131 deletions(-) create mode 100644 input/regression/new-part-combine-solo-global.ly diff --git a/ChangeLog b/ChangeLog index 61449e48d6..24b24a023e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-02-04 Han-Wen Nienhuys + + * input/regression/new-part-combine-solo-global.ly: new file. + + * scm/part-combiner.scm: rewrite. + 2004-02-03 Jan Nieuwenhuizen * scripts/filter-lilypond-book.py: Handle @include. Add progress diff --git a/input/regression/new-part-combine-solo-global.ly b/input/regression/new-part-combine-solo-global.ly new file mode 100644 index 0000000000..3e6dfd6098 --- /dev/null +++ b/input/regression/new-part-combine-solo-global.ly @@ -0,0 +1,18 @@ + +\header { texidoc = "Solo/Solo2 also is global: In this example, solo1 + should not printed over the 1st note, because the voice + switch would kill the slur." + +} + + +\score { + \new Staff + \newpartcombine \notes \relative c'' { + bes2( + a4) + } + \notes \relative c' { + r2 cis4 + } +} diff --git a/input/regression/new-part-combine-solo.ly b/input/regression/new-part-combine-solo.ly index 8b96e7df68..be212b8a0d 100644 --- a/input/regression/new-part-combine-solo.ly +++ b/input/regression/new-part-combine-solo.ly @@ -18,7 +18,8 @@ vone = \notes \relative a' { g4 r8 g8 g8 r8 g8 r8 g2 ~ g2 ~ g4 } vtwo = \notes \relative g' { e4. e8 r2 e4 r4 r2 e4 } \score { - << \property Score.skipBars = ##t + + << \property Score.skipBars = ##t \newpartcombine \vone \vtwo >> } diff --git a/scm/part-combiner.scm b/scm/part-combiner.scm index a5cf9f595c..44da6ab139 100644 --- a/scm/part-combiner.scm +++ b/scm/part-combiner.scm @@ -5,22 +5,47 @@ (use-modules (oop goops)) +;; todo: make module. + (define-class () (event-list #:init-value '() #:accessor events #:init-keyword #:events) (when-moment #:accessor when #:init-keyword #:when) - (split-idx #:accessor split-idx ) + (split-idx #:accessor split-idx) + (vector-index) + (state-vector) (spanner-state #:init-value '() #:accessor span-state) ) +(define-method (note-events (vs )) + (define (f? x) + (equal? (ly:get-mus-property x 'name) 'NoteEvent)) + (filter f? (events vs))) (define-class () (configuration #:init-value '() #:accessor configuration) (when-moment #:accessor when #:init-keyword #:when) - (is #:init-keyword #:indexes #:accessor indexes) + (is #:init-keyword #:voice-states #:accessor voice-states) (synced #:init-keyword #:synced #:init-value #f #:getter synced?) ) +(define-method (previous-voice-state (vs )) + (let* ((i (slot-ref vs 'vector-index)) + (v (slot-ref vs 'state-vector)) + ) + (if (< 0 i) + (vector-ref v (1- i)) + #f) + )) + +(define (previous-span-state vs) + (let* + ((p (previous-voice-state vs))) + + (if p (span-state p) + '()) + )) + (define-method (write (x ) file) (display (when x) file) (display " evs = " file) @@ -39,16 +64,26 @@ (display "\n" f) ) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (make-voice-states evl) - (list->vector - (map - (lambda (v) - (make - #:when (car v) - #:events (map car (cdr v)) - )) - evl))) + (let + ((vec + (list->vector + (map + (lambda (v) + (make + #:when (car v) + #:events (map car (cdr v)) + )) + evl)))) + + (do ( (i 0 (1+ i)) ) + ( (= i (vector-length vec)) vec) + (slot-set! (vector-ref vec i) 'vector-index i) + (slot-set! (vector-ref vec i) 'state-vector vec) + ))) + (define (moment-min a b) (if (ly:moment #:when min - #:indexes (cons idx1 idx2) + #:voice-states (cons s1 s2) #:synced (= inc1 inc2) ) #f)) ) - (if m1 - (set! (split-idx (vector-ref vs1 idx1)) ss-idx)) - (if m2 - (set! (split-idx (vector-ref vs2 idx2)) ss-idx)) + (if s1 + (set! (split-idx s1) ss-idx)) + (if s2 + (set! (split-idx s2) ss-idx)) (if min (helper (1+ ss-idx) @@ -217,14 +252,13 @@ Voice-state objects -;; -;; todo: this function is rather too hairy and too long. -;; (define-public (determine-split-list evl1 evl2) "EVL1 and EVL2 should be ascending" + + (let* - ((pc-debug #f) + ((pc-debug #t) (chord-threshold 8) (voice-state-vec1 (make-voice-states evl1)) (voice-state-vec2 (make-voice-states evl2)) @@ -250,10 +284,6 @@ Only set if not set previously. )) )) - (define (get-note-evs vs) - (define (f? x) - (equal? (ly:get-mus-property x 'name) 'NoteEvent)) - (filter f? (events vs))) (define (copy-state-from state-vec vs) (define (copy-one-state key-idx) @@ -272,16 +302,14 @@ Only set if not set previously. (define (analyse-notes now-state) (let* ( - (i1 (car (indexes now-state))) - (i2 (cdr (indexes now-state))) - (vs1 (vector-ref voice-state-vec1 i1)) - (vs2 (vector-ref voice-state-vec2 i2)) + (vs1 (car (voice-states now-state))) + (vs2 (cdr (voice-states now-state))) - (notes1 (get-note-evs vs1)) + (notes1 (note-events vs1)) (durs1 (sort (map (lambda (x) (ly:get-mus-property x 'duration)) notes1) ly:duration i1 0) - (copy-state-from voice-state-vec1 (vector-ref voice-state-vec1 (1- i1)))) - (if (> i2 0) - (copy-state-from voice-state-vec2 (vector-ref voice-state-vec2 (1- i2)))) + (if (previous-voice-state vs1) + (copy-state-from voice-state-vec1 + (previous-voice-state vs1))) + (if (previous-voice-state vs2) + (copy-state-from voice-state-vec2 + (previous-voice-state vs2))) (if (and (null? (span-state vs1)) (null? (span-state vs2))) (put 'chords)) @@ -323,26 +353,17 @@ Only set if not set previously. (if (< ri (vector-length result)) (let* ((now-state (vector-ref result ri)) - (i1 (car (indexes now-state))) - (i2 (cdr (indexes now-state)))) + (vs1 (car (voice-states now-state))) + (vs2 (cdr (voice-states now-state)))) (cond - ((= i1 (vector-length voice-state-vec1)) (put 'apart)) - ((= i2 (vector-length voice-state-vec2)) (put 'apart)) + ((not vs1) (put 'apart)) + ((not vs2) (put 'apart)) (else (let* ( - (vs1 (vector-ref voice-state-vec1 i1)) - (vs2 (vector-ref voice-state-vec2 i2)) - - (active1 - (if (> i1 0) - (span-state (vector-ref voice-state-vec1 (1- i1))) - '())) - (active2 - (if (> i2 0) - (span-state (vector-ref voice-state-vec2 (1- i2))) - '())) + (active1 (previous-span-state vs1)) + (active2 (previous-span-state vs2)) (new-active1 (span-state vs1)) (new-active2 (span-state vs2)) @@ -350,7 +371,7 @@ Only set if not set previously. ) (if pc-debug - (display (list (when now-state) i1 i2 ri + (display (list (when now-state) ri active1 "->" new-active1 active2 "->" new-active2 "\n"))) @@ -372,95 +393,147 @@ Only set if not set previously. (analyse-time-step (1+ ri)) ))))) - + (define (analyse-a2 ri) + (if (< ri (vector-length result)) + (let* + ((now-state (vector-ref result ri)) + (vs1 (car (voice-states now-state))) + (vs2 (cdr (voice-states now-state))) + ) + + (if (and (equal? (configuration now-state) 'chords) + vs1 vs2) + + (let* + ((notes1 (note-events vs1)) + (notes2 (note-events vs2)) + ) + + (cond + ((and + (= 1 (length notes1)) + (= 1 (length notes2)) + (equal? (ly:get-mus-property (car notes1) 'pitch) + (ly:get-mus-property (car notes2) 'pitch))) + + (set! (configuration now-state) 'unisono)) + ((and + (= 0 (length notes1)) + (= 0 (length notes2))) + (set! (configuration now-state) 'unisilence))) + + (analyse-a2 (1+ ri)) + ))))) + (define (analyse-solo12 ri) - (define (put x) - (set-cdr! (vector-ref result ri) x) ) - - (if (< ri (vector-length result)) - - (let* - ((now (when result ri)) - (m1 (when ev1 i1)) - (m2 (when ev2 i2)) - (notes1 (get-note-evs ev1 - (if (ly:moment i b)) + (set! (configuration (vector-ref result i) x)) + )) + (define (put x) + (set! (configuration (vector-ref result ri)) x)) + + (define (try-solo type start-idx current-idx) + (if (< current-idx (vector-length result)) + (let* + ((now-state (vector-ref result current-idx)) + (solo-state ((if (equal? type 'solo1) car cdr) (voice-states now-state))) + (silent-state ((if (equal? type 'solo1) cdr car) (voice-states now-state))) + (silent-notes (note-events silent-state)) + (solo-notes (note-events solo-state)) + (soln (length solo-notes)) + (siln (length silent-notes))) - - (if (equal? (what result ri) 'apart) (cond - ((and (= 0 n1) - (< 0 n2) - (equal? now m2) - ) - (put 'solo2)) - ((and (< 0 n1) - (= 0 n2) - (equal? now m1) - ) - (put 'solo1)) - ((and (= 0 n1) - (= 0 n2)) - (put 'apart-silence)) + ((not (equal? (configuration now-state) 'apart)) + current-idx) + ((= soln 0) current-idx) + ((> siln 0) current-idx) + ((null? (span-state solo-state)) + (put-range type start-idx current-idx) + current-idx) + (else + (try-solo type start-idx (1+ current-idx))) + )) + (1- current-idx))) + + (define (analyse-moment ri) + "Analyse 'apart starting at RI. Return next index. +" + + (let* + ((now-state (vector-ref result ri)) + (vs1 (car (voice-states now-state))) + (vs2 (cdr (voice-states now-state))) + + (notes1 (note-events vs1)) + (notes2 (note-events vs2)) + (n1 (length notes1)) + (n2 (length notes2)) + ) - (if (and - (equal? (what result ri) 'chords) - (equal? pitches1 pitches2)) - (put (if (pair? pitches2) - 'unisono 'unisilence) )) - - (cond - ((ly:momentlist result))) -; (if pc-debug (display result)) + (if pc-debug (display result)) result)) -- 2.39.2