Autor Thema: automatische Pausensetzung  (Gelesen 6473 mal)

Manuela

  • Member
Re: automatische Pausensetzung
« Antwort #15 am: Montag, 13. Juni 2016, 06:33 »
Aus irgendeinem Grund sind anscheinend eine Menge Beiträge aus diesem Thread verschwunden, schade  :(

Ich fand die Diskussion interessant, auch wenn sie sich nicht mehr um das eigentliche Thema drehte. Vll. hätte man sie in einen eigenen Thread verschieben sollen.

Manuela

  • Member
Re: automatische Pausensetzung
« Antwort #16 am: Dienstag, 26. Juli 2016, 07:07 »
Ein Code Snippet, auf das ich gestoßen bin:

When two (or more) voices on a staff share common rests, common engraving practice merges these rests into one. The following snippet takes care of that, automatically. Please note that multi-measure rests are not automatically combined

%% http://lsr.dsi.unimi.it/LSR/Item?id=336
%% see also http://code.google.com/p/lilypond/issues/detail?id=1228

%% Usage:
%%   \new Staff \with {
%%     \override RestCollision.positioning-done = #merge-rests-on-positioning
%%   } << \somevoice \\ \othervoice >>
%% or (globally):
%%   \layout {
%%     \context {
%%       \Staff
%%       \override RestCollision.positioning-done = #merge-rests-on-positioning
%%     }
%%   }
%%
%% Limitations:
%% - only handles two voices
%% - does not handle multi-measure/whole-measure rests

#(define (rest-score r)
  (let ((score 0)
(yoff (ly:grob-property-data r 'Y-offset))
(sp (ly:grob-property-data r 'staff-position)))
    (if (number? yoff)
(set! score (+ score 2))
(if (eq? yoff 'calculation-in-progress)
    (set! score (- score 3))))
    (and (number? sp)
(<= 0 2 sp)
(set! score (+ score 2))
(set! score (- score (abs (- 1 sp)))))
    score))

#(define (merge-rests-on-positioning grob)
  (let* ((can-merge #f)
(elts (ly:grob-object grob 'elements))
(num-elts (and (ly:grob-array? elts)
(ly:grob-array-length elts)))
(two-voice? (= num-elts 2)))
    (if two-voice?
(let* ((v1-grob (ly:grob-array-ref elts 0))
       (v2-grob (ly:grob-array-ref elts 1))
       (v1-rest (ly:grob-object v1-grob 'rest))
       (v2-rest (ly:grob-object v2-grob 'rest)))
  (and
   (ly:grob? v1-rest)
   (ly:grob? v2-rest)          
   (let* ((v1-duration-log (ly:grob-property v1-rest 'duration-log))
  (v2-duration-log (ly:grob-property v2-rest 'duration-log))
  (v1-dot (ly:grob-object v1-rest 'dot))
  (v2-dot (ly:grob-object v2-rest 'dot))
  (v1-dot-count (and (ly:grob? v1-dot)
     (ly:grob-property v1-dot 'dot-count -1)))
  (v2-dot-count (and (ly:grob? v2-dot)
     (ly:grob-property v2-dot 'dot-count -1))))
     (set! can-merge
   (and
    (number? v1-duration-log)
    (number? v2-duration-log)
    (= v1-duration-log v2-duration-log)
    (eq? v1-dot-count v2-dot-count)))
     (if can-merge
;; keep the rest that looks best:
(let* ((keep-v1? (>= (rest-score v1-rest)
      (rest-score v2-rest)))
(rest-to-keep (if keep-v1? v1-rest v2-rest))
(dot-to-kill (if keep-v1? v2-dot v1-dot)))
   ;; uncomment if you're curious of which rest was chosen:
   ;;(ly:grob-set-property! v1-rest 'color green)
   ;;(ly:grob-set-property! v2-rest 'color blue)
   (ly:grob-suicide! (if keep-v1? v2-rest v1-rest))
   (if (ly:grob? dot-to-kill)
       (ly:grob-suicide! dot-to-kill))
   (ly:grob-set-property! rest-to-keep 'direction 0)
   (ly:rest::y-offset-callback rest-to-keep)))))))
    (if can-merge
#t
(ly:rest-collision::calc-positioning-done grob))))


\score {
  \new Score <<
    \new Staff  <<
      s4-\markup{ LilyPond default, rests in both voices. }
      \relative c'' { c4 d e r | r2  e4 g | R1 }
      \\
      \relative c'' { c4 b a r | r a g2   | R1 }
    >>       
    \new Staff \with {
      \override RestCollision.positioning-done = #merge-rests-on-positioning
    }
    <<
      s4-\markup{Merge rests as per standard notation practice.}
      \relative c'' { c4 d e r | r2  e4 g | R1 }
      \\
      \relative c'' { c4 b a r | r a g2   | R1 }
    >>   
  >>
  \layout {}
}