From e05dfb628c1538474852a968adad74c1d518199a Mon Sep 17 00:00:00 2001 From: Dan Eble Date: Sun, 17 May 2015 15:53:22 -0400 Subject: [PATCH] Issue 4402: Part combiner: ignore skips coinciding with rests within a part --- .../regression/part-combine-silence-mixed.ly | 10 ++++---- scm/part-combiner.scm | 23 +++++++++++-------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/input/regression/part-combine-silence-mixed.ly b/input/regression/part-combine-silence-mixed.ly index 7d59777775..a399431a00 100644 --- a/input/regression/part-combine-silence-mixed.ly +++ b/input/regression/part-combine-silence-mixed.ly @@ -1,18 +1,18 @@ \version "2.19.16" \header { - texidoc = "Different kinds of silence are not merged into the shared voice even if they begin and end simultaneously." + texidoc = "Different kinds of silence are not merged into the shared voice even if they begin and end simultaneously; however, when rests and skips are present in the same part, the skips are ignored." } \score { << \new Staff { \partcombine - \relative f' { R1^"R" | s1^"s" | r1^"r" } - \relative f' { r1_"r" | R1_"R" | s1_"s" } + \relative f' { R1^"R" | s1^"s" | r1^"r" | << R1 s1 s4 >> | << r1 s2 s4 >> } + \relative f' { r1_"r" | R1_"R" | s1_"s" | << s4 s1 R1 >> | << s4 s2 r1 >> } } \new Staff { \partcombine - \relative f' { r1^"r" | R1^"R" | s1^"s" } - \relative f' { R1_"R" | s1_"s" | r1_"r" } + \relative f' { r1^"r" | R1^"R" | s1^"s" | << s4 s1 R1 >> | << s4 s2 r1 >> } + \relative f' { R1_"R" | s1_"s" | r1_"r" | << R1 s1 s4 >> | << r1 s2 s4 >> } } >> } diff --git a/scm/part-combiner.scm b/scm/part-combiner.scm index a2ebda492c..20b7b05cc5 100644 --- a/scm/part-combiner.scm +++ b/scm/part-combiner.scm @@ -63,11 +63,16 @@ (note-events vs)) note)) - (define (f? x) - (or (ly:in-event-class? x 'rest-event) - (ly:in-event-class? x 'skip-event))) - (filter f? (events vs))) +(define-method (rest-or-skip-events (vs )) + (define (filtered-events event-class) + (filter (lambda(x) (ly:in-event-class? x event-class)) + (events vs))) + (let ((result (filtered-events 'rest-event))) + ;; There may be skips in the same part with rests for various + ;; reasons. Regard the skips only if there are no rests. + (if (and (not (pair? result)) (not (any-mmrest-events vs))) + (set! result (filtered-events 'skip-event))) + result)) (define-method (any-mmrest-events (vs )) (define (f? x) @@ -477,8 +482,8 @@ Only set if not set previously. (vs2 (cdr (voice-states now-state)))) (define (analyse-synced-silence) - (let ((rests1 (if vs1 (rest-and-skip-events vs1) '())) - (rests2 (if vs2 (rest-and-skip-events vs2) '()))) + (let ((rests1 (if vs1 (rest-or-skip-events vs1) '())) + (rests2 (if vs2 (rest-or-skip-events vs2) '()))) (cond ;; multi-measure rests (probably), which the @@ -616,8 +621,8 @@ the mark when there are no spanners active. (let* ((now-state (vector-ref result result-idx)) (vs1 (current-voice-state now-state 1)) (vs2 (current-voice-state now-state 2)) - (rests1 (if vs1 (rest-and-skip-events vs1) '())) - (rests2 (if vs2 (rest-and-skip-events vs2) '())) + (rests1 (if vs1 (rest-or-skip-events vs1) '())) + (rests2 (if vs2 (rest-or-skip-events vs2) '())) (prev-state (if (> result-idx 0) (vector-ref result (- result-idx 1)) #f)) -- 2.39.5