Autor Thema: Pausen auf mittlerer Höhe  (Gelesen 3452 mal)

stefanhuglfing

  • Member
Pausen auf mittlerer Höhe
« am: Mittwoch, 11. September 2013, 07:23 »
Die Pausen bei zweistimmigen Noten in einer Notenzeile nicht doppelt dargestellt werden, habe ich sie in der ersten Stimme unsichtbar geschrieben (s). Ich hätte die Pause aber gern in der Mitte der Notenzeile. Nicht weit unten oder weit oben. Wie gelingt das?

SopranNoten =  \relative c'
 { \autoBeamOff
   \compressFullBarRests s1*7   
   s2 g'8 a4.
 } 
       
AltNoten =  \relative c' 
 { \autoBeamOff
   \compressFullBarRests R1*7
   r2 g8 a4.
 } 
       
\score
{
 \new Staff 
  <<
   \new Voice = "first"
    {
      \voiceOne
      \SopranNoten
    }
  \new Voice= "second"
    { \voiceTwo 
      \AltNoten
    }
  >>

 \layout{}
}

eluze

  • Member
Re: Pausen auf mittlerer Höhe
« Antwort #1 am: Mittwoch, 11. September 2013, 10:22 »

RobUr

  • Member
Re: Pausen auf mittlerer Höhe
« Antwort #2 am: Mittwoch, 11. September 2013, 15:12 »
Das Snippet berücksichtigt allerdings keine Ganztaktpausen. Man muss diese für jede Stimme manuell zurückschieben:
\override MultiMeasureRest #'staff-position = #2 % Wert für LP 2.16.2

Gruß, Robert

harm6

  • Member
Re: Pausen auf mittlerer Höhe
« Antwort #3 am: Mittwoch, 11. September 2013, 21:35 »
Hallo,

wie Robert schon darlegte, kann das LSR-snippet keine Ganztaktpausen verarbeiten.
Ich habe vor einiger Zeit zwar mal den Code dahingehend erweitert, aber es gibt mittlerweile einen scheme-engraver der das viel eleganter regelt.
http://www.mail-archive.com/lilypond-user@gnu.org/msg69703.html
Dank an Jay Anderson.

\version "2.16.2"
%version "2.17.25"

%%  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{ "Merge Rests and MultiMeasureRests in both voices." }
       \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 }
     >>
  >>

}


HTH,
  Harm

stefanhuglfing

  • Member
Re: Pausen auf mittlerer Höhe
« Antwort #4 am: Donnerstag, 12. September 2013, 15:40 »
ich bin leider zu blöd, mir eine neue Version von lilypond zu installieren. Ich habe 2.14.2.
Aber trotzdem vielen Dank.

harm6

  • Member
Re: Pausen auf mittlerer Höhe
« Antwort #5 am: Donnerstag, 12. September 2013, 22:34 »
Zitat
ich bin leider zu blöd, mir eine neue Version von lilypond zu installieren. Ich habe 2.14.2.

Du hattest Deine Version nicht angegeben. Wenn das jemand ausläßt gehe ich halt von der aktuellen stable aus und das ist momentan 2.16.2.
Also: Bitte immer die Version angeben.

Tatsächlich wird hart daran gearbeitet 2.18. release-fertig zu machen. Insoweit solltest Du Dir Hilfe für das manuelle upgraden suchen (z.B. hier im Forum ;) ), falls Deine Distibution nur eine veraltete LilyPond-Version liefert.
(Aber bitte in einem anderen/neuen Thread.)

Zum eigentlichen Thema:
Der code für die engraver ist tatsächlich auch für 2.14.2 geeignet.
Mein Code kompiliert nur deshalb nicht, weil ich ein bißchen "syntactic sugar" in das Beispiel eingefügt habe. Den kann man aber rausnehmen.

2.14.2-Version:
%\version "2.16.1"
\version "2.14.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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                         
\score {
  <<
    \new Staff
      <<
        <>-\markup { "LilyPond-2.14.2 default, Rests in both voices." }
        \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 {
      \consists #merge-rests-engraver
      \consists #merge-mmrests-engraver
    }
     <<
       <>-\markup{ "Merge Rests and MultiMeasureRests in both voices." }
       \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 }
     >>
  >>

}

Gruß,
  Harm

Jolander

  • Member
Re: Pausen auf mittlerer Höhe
« Antwort #6 am: Dienstag, 12. November 2013, 13:13 »
Ich frage hier aus Unwissenheit:

Wann wende ich den vorstehenden Code an und wann den hier beschriebenen?

\version "2.16.2"
%% gemeinsame Pausen bei Zweistimmigkeit

#(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))))


\layout {
  \context {
    \Staff
    \override RestCollision #'positioning-done = #merge-rests-on-positioning
  }
}

Danke
Guido
« Letzte Änderung: Dienstag, 12. November 2013, 13:15 von Jolander »

RobUr

  • Member
Re: Pausen auf mittlerer Höhe
« Antwort #7 am: Mittwoch, 13. November 2013, 14:15 »
Ganz einfach: Das von dir beschriebene Snippet kann keine Ganztaktpausen vereinen, das von Harm tuts!

Gruß, Robert