Autor Thema: Pausen automatisch runterziehen in der 1. Stimme  (Gelesen 1896 mal)

iugin

  • Member
Pausen automatisch runterziehen in der 1. Stimme
« am: Freitag, 8. Mai 2015, 20:25 »
Liebe alle

nach langer Zeit melde ich mich wieder :)
Ich beziehe mich auf diese Diskussion.
Ich finde dieser Snippet super, funktioniert aber nicht in dem Fall, dass es in der 2. Stimme eine unsichtbare Pause gibt.
Ich habe den Scheme-Code studiert, komme aber nicht draus...
Ist es mit wenig Aufwand machbar?

\version "2.18.2"

%%  http://www.mail-archive.com/lilypond-user@gnu.org/msg69703.html
%% Thanks to Jay Anderson

#(define has-one-or-less (lambda (lst) (or (null? lst) (null? (cdr lst)))))

#(define has-at-least-two (lambda (lst) (not (has-one-or-less lst))))

#(define (all-equal lst pred)
  (or (has-one-or-less lst)
      (and (pred (car lst) (cadr lst)) (all-equal (cdr lst) pred))))

#(define merge-rests-engraver
   (lambda (context)
     (let ((rest-same-length
             (lambda (rest-a rest-b)
               (eq? (ly:grob-property rest-a 'duration-log)
                    (ly:grob-property rest-b 'duration-log))))
           (rests '()))
     `((start-translation-timestep . ,(lambda (trans)
                                        (set! rests '())))
       (stop-translation-timestep . ,(lambda (trans)
                                       (if (and (has-at-least-two rests)
                                                (all-equal rests rest-same-length))
                                         (for-each
                                           (lambda (rest)
                                             (ly:grob-set-property! rest 'Y-offset 0))
                                           rests))))
       (acknowledgers
         (rest-interface . ,(lambda (engraver grob source-engraver)
                              (if (eq? 'Rest (assoc-ref (ly:grob-property grob 'meta) 'name))
                                (set! rests (cons grob rests))))))))))

#(define merge-mmrests-engraver
   (lambda (context)
     (let* ((mmrest-same-length
              (lambda (rest-a rest-b)
                (eq? (ly:grob-property rest-a 'measure-count)
                     (ly:grob-property rest-b 'measure-count))))
            (merge-mmrests
              (lambda (rests)
                (if (all-equal rests mmrest-same-length)
                  (let ((offset (if (eq? (ly:grob-property (car rests) 'measure-count) 1) 1 0)))
                    (for-each
                      (lambda (rest) (ly:grob-set-property! rest 'Y-offset offset))
                      rests)))))
            (curr-rests '())
            (rests '()))
     `((start-translation-timestep . ,(lambda (trans)
                                        (set! curr-rests '())))
       (stop-translation-timestep . ,(lambda (trans)
                                       (if (has-at-least-two curr-rests)
                                         (set! rests (cons curr-rests rests)))))
       (finalize . ,(lambda (translator)
                      (for-each merge-mmrests rests)))
       (acknowledgers
         (rest-interface . ,(lambda (engraver grob source-engraver)
                              (if (eq? 'MultiMeasureRest (assoc-ref (ly:grob-property grob 'meta) 'name))
                                (set! curr-rests (cons grob curr-rests))))))))))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                               
consist-r-mmr-engraver =
\with {
  \consists #merge-rests-engraver
  \consists #merge-mmrests-engraver
}
                           
\score {
  <<
    \new Staff
      <<
        <>-\markup{ #(format "LilyPond-~a default, Rests in both voices." (lilypond-version))}
        \relative c'' { c4 d e r | r2  e4 g | R1 \compressFullBarRests R1*9 }
        \\
        \relative c'' { c4 b a r | r a g2   | R1 \compressFullBarRests R1*9 }
      >>
   
    \new Staff \with { \consist-r-mmr-engraver }
     <<
       <>-\markup{ "Mit unsichtbaren Pausen" }
       \relative c'' { c4 d e r | r2  e4 g | R1 \compressFullBarRests R1*9 } \\
       \relative c'' { c4 b a s | r a g2   | R1 \compressFullBarRests R1*9 }
     >>
  >>

}
Besten Dank für die Hilfe und einen lieben Gruss

Eugenio

harm6

  • Member
Re: Pausen automatisch runterziehen in der 1. Stimme
« Antwort #1 am: Freitag, 8. Mai 2015, 23:55 »
Hallo Eugenio,

der code unten scheint für einfache Pausen und SkipEvents zu funktionieren. Ich hab aber nur das Beispiel geprüft, weiteres testen überlass ich Dir ;)
Um MultiMeasureRest habe ich mich noch nicht gekümmert ...

\version "2.18.2"

%%  http://www.mail-archive.com/lilypond-user@gnu.org/msg69703.html
%% Thanks to Jay Anderson

#(define has-one-or-less (lambda (lst) (or (null? lst) (null? (cdr lst)))))

#(define has-at-least-two (lambda (lst) (not (has-one-or-less lst))))

#(define (all-equal lst pred)
  (or (has-one-or-less lst)
      (and (pred (car lst) (cadr lst)) (all-equal (cdr lst) pred))))

#(define merge-rests-engraver
   (lambda (context)
     (let ((rest-same-length
             (lambda (rest-a rest-b)
               (let* ((dur-a
                        (if (ly:grob? rest-a)
                            (ly:grob-property rest-a 'duration-log)
                            (ly:duration-log (ly:event-property rest-a 'duration)))
                            )
                      (dur-b
                        (if (ly:grob? rest-b)
                            (ly:grob-property rest-b 'duration-log)
                            (ly:duration-log (ly:event-property rest-b 'duration))))
                      )
               (eq? dur-a dur-b))))
           (rests '()))
     `((listeners
        (skip-event
          .
          ,(lambda (engraver event)
            (set! rests (cons event rests)))))

       (start-translation-timestep . ,(lambda (trans)
                                        (set! rests '())))
       (stop-translation-timestep . ,(lambda (trans)
                                       (if (and (has-at-least-two rests)
                                                (all-equal rests rest-same-length))
                                         (for-each
                                           (lambda (rest)
                                            (if (ly:grob? rest)
                                              (ly:grob-set-property! rest 'Y-offset 0)))
                                           rests))))
       (acknowledgers
         (rest-interface . ,(lambda (engraver grob source-engraver)
                              (if (eq? 'Rest (assoc-ref (ly:grob-property grob 'meta) 'name))
                                (set! rests (cons grob rests))))))))))

#(define merge-mmrests-engraver
   (lambda (context)
     (let* ((mmrest-same-length
              (lambda (rest-a rest-b)
                (eq? (ly:grob-property rest-a 'measure-count)
                     (ly:grob-property rest-b 'measure-count))))
            (merge-mmrests
              (lambda (rests)
                (if (all-equal rests mmrest-same-length)
                  (let ((offset (if (eq? (ly:grob-property (car rests) 'measure-count) 1) 1 0)))
                    (for-each
                      (lambda (rest) (ly:grob-set-property! rest 'Y-offset offset))
                      rests)))))
            (curr-rests '())
            (rests '()))
     `((start-translation-timestep . ,(lambda (trans)
                                        (set! curr-rests '())))
       (stop-translation-timestep . ,(lambda (trans)
                                       (if (has-at-least-two curr-rests)
                                         (set! rests (cons curr-rests rests)))))
       (finalize . ,(lambda (translator)
                      (for-each merge-mmrests rests)))
       (acknowledgers
         (rest-interface . ,(lambda (engraver grob source-engraver)
                              (if (eq? 'MultiMeasureRest (assoc-ref (ly:grob-property grob 'meta) 'name))
                                (set! curr-rests (cons grob curr-rests))))))))))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                               
consist-r-mmr-engraver =
\with {
  \consists #merge-rests-engraver
  \consists #merge-mmrests-engraver
}
                           
\score {
  <<
    \new Staff
      <<
        <>-\markup{ #(format "LilyPond-~a default, Rests in both voices." (lilypond-version))}
        \relative c'' { c4 d e r | r2  e4 g | R1 \compressFullBarRests R1*9 }
        \\
        \relative c'' { c4 b a r | r a g2   | R1 \compressFullBarRests R1*9 }
      >>
   
    \new Staff \with { \consist-r-mmr-engraver }
     <<
       <>-\markup{ "Mit unsichtbaren Pausen" }
       \relative c'' { c4 d e r | r2  e4 g | R1 \compressFullBarRests R1*9 } \\
       \relative c'' { c4 b a s | r a g2   | R1 \compressFullBarRests R1*9 }
     >>
  >>

}

HTH,
  Harm

iugin

  • Member
Re: Pausen automatisch runterziehen in der 1. Stimme
« Antwort #2 am: Samstag, 9. Mai 2015, 14:16 »
Lieber Harm

das funktioniert prima, besten Dank :-)
Und das mit dem MultiMeasureRest ist im Moment unwichtig. So reicht es völlig...

Einen lieben Gruss

Eugenio

iugin

  • Member
Re: Pausen automatisch runterziehen in der 1. Stimme
« Antwort #3 am: Sonntag, 10. Mai 2015, 19:10 »
Lieber Harm

eine Frage: ist es möglich (mit wenig Aufwand) den Code so zu ändern, dass die Pausen runtergezogen werden, auch wenn die skipEvents eine andere Dauer haben?
\version "2.18.2"

%%  http://www.mail-archive.com/lilypond-user@gnu.org/msg69703.html
%% Thanks to Jay Anderson

#(define has-one-or-less (lambda (lst) (or (null? lst) (null? (cdr lst)))))

#(define has-at-least-two (lambda (lst) (not (has-one-or-less lst))))

#(define (all-equal lst pred)
   (or (has-one-or-less lst)
       (and (pred (car lst) (cadr lst)) (all-equal (cdr lst) pred))))

#(define merge-rests-engraver
   (lambda (context)
     (let ((rest-same-length
            (lambda (rest-a rest-b)
              (let* ((dur-a
                      (if (ly:grob? rest-a)
                          (ly:grob-property rest-a 'duration-log)
                          (ly:duration-log (ly:event-property rest-a 'duration)))
                      )
                     (dur-b
                      (if (ly:grob? rest-b)
                          (ly:grob-property rest-b 'duration-log)
                          (ly:duration-log (ly:event-property rest-b 'duration))))
                     )
                (eq? dur-a dur-b))))
           (rests '()))
       `((listeners
          (skip-event
           .
           ,(lambda (engraver event)
              (set! rests (cons event rests)))))

         (start-translation-timestep . ,(lambda (trans)
                                          (set! rests '())))
         (stop-translation-timestep . ,(lambda (trans)
                                         (if (and (has-at-least-two rests)
                                                  (all-equal rests rest-same-length))
                                             (for-each
                                              (lambda (rest)
                                                (if (ly:grob? rest)
                                                    (ly:grob-set-property! rest 'Y-offset 0)))
                                              rests))))
         (acknowledgers
          (rest-interface . ,(lambda (engraver grob source-engraver)
                               (if (eq? 'Rest (assoc-ref (ly:grob-property grob 'meta) 'name))
                                   (set! rests (cons grob rests))))))))))

#(define merge-mmrests-engraver
   (lambda (context)
     (let* ((mmrest-same-length
             (lambda (rest-a rest-b)
               (eq? (ly:grob-property rest-a 'measure-count)
                    (ly:grob-property rest-b 'measure-count))))
            (merge-mmrests
             (lambda (rests)
               (if (all-equal rests mmrest-same-length)
                   (let ((offset (if (eq? (ly:grob-property (car rests) 'measure-count) 1) 1 0)))
                     (for-each
                      (lambda (rest) (ly:grob-set-property! rest 'Y-offset offset))
                      rests)))))
            (curr-rests '())
            (rests '()))
       `((start-translation-timestep . ,(lambda (trans)
                                          (set! curr-rests '())))
         (stop-translation-timestep . ,(lambda (trans)
                                         (if (has-at-least-two curr-rests)
                                             (set! rests (cons curr-rests rests)))))
         (finalize . ,(lambda (translator)
                        (for-each merge-mmrests rests)))
         (acknowledgers
          (rest-interface . ,(lambda (engraver grob source-engraver)
                               (if (eq? 'MultiMeasureRest (assoc-ref (ly:grob-property grob 'meta) 'name))
                                   (set! curr-rests (cons grob curr-rests))))))))))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



\score {
  \new Staff
  <<
    <>-\markup{ "Mit unsichtbaren Pausen" }
    \relative c'' { c4 r } \\
    \relative c'' { s2 }
  >>
  \layout {
    \context {
      \Staff
      \consists #merge-rests-engraver
      \consists #merge-mmrests-engraver
    }
  }
}
Aber so reicht es mir vollkommend, deswegen, wenn zu viel Arbeit gibt, lass es :-)

Einen lieben Gruss und danke

Eugenio

harm6

  • Member
Re: Pausen automatisch runterziehen in der 1. Stimme
« Antwort #4 am: Montag, 11. Mai 2015, 23:38 »
Vielleicht so, weiteres testen ist aber nötig (kann sein, daß die Bedigungen jetzt zu weit gefasst sind)

\version "2.18.2"

%%  http://www.mail-archive.com/lilypond-user@gnu.org/msg69703.html
%% Thanks to Jay Anderson

#(define has-one-or-less (lambda (lst) (or (null? lst) (null? (cdr lst)))))

#(define has-at-least-two (lambda (lst) (not (has-one-or-less lst))))

#(define (all-equal lst pred)
  (or (has-one-or-less lst)
      (and (pred (car lst) (cadr lst)) (all-equal (cdr lst) pred))))

#(define merge-rests-engraver
   (lambda (context)
     (let ((rest-same-length
             (lambda (rest-a rest-b)
               (or (ly:stream-event? rest-a)
                   (ly:stream-event? rest-b)
                   (eq? (ly:grob-property rest-a 'duration-log)
                        (ly:grob-property rest-b 'duration-log)))))
           (rests '()))
     `((listeners
        (skip-event
          .
          ,(lambda (engraver event)
            (set! rests (cons event rests)))))

       (start-translation-timestep . ,(lambda (trans)
                                        (set! rests '())))
       (stop-translation-timestep . ,(lambda (trans)
                                       (if (and (has-at-least-two rests)
                                                (all-equal rests rest-same-length))
                                         (for-each
                                           (lambda (rest)
                                            (if (ly:grob? rest)
                                              (ly:grob-set-property! rest 'Y-offset 0)))
                                           rests))))
       (acknowledgers
         (rest-interface . ,(lambda (engraver grob source-engraver)
                              (if (eq? 'Rest (assoc-ref (ly:grob-property grob 'meta) 'name))
                                (set! rests (cons grob rests))))))))))

#(define merge-mmrests-engraver
   (lambda (context)
     (let* ((mmrest-same-length
              (lambda (rest-a rest-b)
                (eq? (ly:grob-property rest-a 'measure-count)
                     (ly:grob-property rest-b 'measure-count))))
            (merge-mmrests
              (lambda (rests)
                (if (all-equal rests mmrest-same-length)
                  (let ((offset (if (eq? (ly:grob-property (car rests) 'measure-count) 1) 1 0)))
                    (for-each
                      (lambda (rest) (ly:grob-set-property! rest 'Y-offset offset))
                      rests)))))
            (curr-rests '())
            (rests '()))
     `((start-translation-timestep . ,(lambda (trans)
                                        (set! curr-rests '())))
       (stop-translation-timestep . ,(lambda (trans)
                                       (if (has-at-least-two curr-rests)
                                         (set! rests (cons curr-rests rests)))))
       (finalize . ,(lambda (translator)
                      (for-each merge-mmrests rests)))
       (acknowledgers
         (rest-interface . ,(lambda (engraver grob source-engraver)
                              (if (eq? 'MultiMeasureRest (assoc-ref (ly:grob-property grob 'meta) 'name))
                                (set! curr-rests (cons grob curr-rests))))))))))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                               
consist-r-mmr-engraver =
\with {
  \consists #merge-rests-engraver
  \consists #merge-mmrests-engraver
}
                           
\score {
  <<
    \new Staff
      <<
        <>-\markup{ #(format "LilyPond-~a default, Rests in both voices." (lilypond-version))}
        \relative c'' { c4 d e r | r2  e4 g | R1 \compressFullBarRests R1*9 }
        \\
        \relative c'' { c4 b a r | r a g2   | R1 \compressFullBarRests R1*9 }
      >>
   
    \new Staff \with { \consist-r-mmr-engraver }
     <<
       <>-\markup{ "Mit unsichtbaren Pausen" }
       \relative c'' { c4 d e r | r2  e4 g | R1 \compressFullBarRests R1*9 } \\
       \relative c'' { c4 b a s8 a8 | r4 a g2   | R1 \compressFullBarRests R1*9 }
     >>
  >>

}


HTH,
  Harm

iugin

  • Member
Re: Pausen automatisch runterziehen in der 1. Stimme
« Antwort #5 am: Dienstag, 12. Mai 2015, 12:45 »
Lieber Harm

besten Dank! Es funktioniert sicher, ich kann es aber im Moment nicht (gründlich) testen. Vielleicht komme ich erst morgen dazu.
Auf jeden Fall danke vielmals und einen schönen Tag :)

Eugenio