• Willkommen im Forum „Archiviertes Lilypond Forum (2017)“.
 

Dies ist das Archiv des alten Forums (bis März 2017). Das aktuelle Forum ist unter lilypondforum.de zu finden.
This is the archive of the old forum (until March 2017). You can find the current forum at lilypondforum.de.

Hauptmenü

mehrere ganztaktige Pausen zusammenfassen

Begonnen von infranator, Mittwoch, 12. Dezember 2012, 15:35

Vorheriges Thema - Nächstes Thema

infranator

Hallo liebe Leute,

gibt es einen Weg, ganztaktige Pausen zusammenzufassen?
Mein Ziel ist, dass

{
  \compressFullBarRests
  R1 R1 R1
}

das gleiche Ergebnis erzeugt wie:

{
  \compressFullBarRests
  R1*3
}


Ich habe im Netz nichts dazu gefunden und bin für jede Hilfe Dankbar!

Be-3

Hallo infranator,

eigentlich ist es wünschenswert und beabischtigt, daß ganztaktige Pausen nur mit der *-Schreibweise zusammengefaßt werden, denn so ist es möglich, gezielt "Gruppen" von zusammengefaßten Pausen zu schreiben, um ein Stück klar zu untergliedern.
Üblicherweise schreibt man immer gleich bei der Eingabe R1*n - unabhängig von \compressFullBarRests - dann muß man auch nichts nachträglich umwandeln.

Viele Grüße
Torsten

infranator

Das Problem ist, dass ich viel mit "\parallelMusic" aufschreibe, da müssen die übereinander geschriebenen Stimmen gleich lang sein.
http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Multiple-voices.de.html#Writing-music-in-parallel

infranator

Ich habe mich ein bisschen in Scheme eingearbeitet (Vielen Dank an harm6! https://archiv.lilypondforum.de/index.php?topic=1428.0)
und eine Funktion geschrieben, die das macht was ich will.
Das geht wahrscheinlich alles noch viel Eleganter und übersichtlicher, aber dafür habe ich nicht mit Kommentaren im Code gespart.  ;)


\version "2.16.0"

#(define (skipEvent? music)
   (eq? (ly:music-property music 'name) 'SkipEvent))

#(define (multiRest? music)
   (eq? (ly:music-property music 'name) 'MultiMeasureRestMusic))

#(define (barCheck? music)
   (eq? (ly:music-property music 'name) 'BarCheck))

#(define (not-has-duration? music)
   (and (not (barCheck? music))
        (or (not (ly:duration? (ly:music-property music 'duration)))
            (ly:music? (ly:music-property music 'element)))))

#(define (sequentialMusic? music)
   (eq? (ly:music-property music 'name) 'SequentialMusic))

#(define (unnest-sequential-music music)
  "
   Unnest sequential music.
   This procedure returns a list, which should be applied with:
   (make-music 'SequentialMusic 'elements (unnest-sequential-music music))
  "
  (define (helper m lst)
    (let ((elts (ly:music-property m 'elements)))
;      (write (display-lily-music (make-music 'SequentialMusic 'elements elts) parser))
      (if (pair? elts)
          ;; lst = ..
          (set! lst
                (map
                 (lambda (y)
                   ;; .. lst +
                   (append
                    lst
                    ;; wenn y (bzw. elts) sequentialMusic enthält
                    (if (sequentialMusic? y)
                        ;; weiter in die Tiefe gehen
                        (helper y lst)
                        ;; nichts ändern
                        y)))
                 ;; (2) y = elts
                 elts)))
      (flatten-list lst)))
  ;; (1) helper aufrufen
   (helper music '()))


unnestSequentialMusic =
#(define-music-function (parser location mus)
   (ly:music?)
   (make-music 'SequentialMusic 'elements (unnest-sequential-music mus)))

#(define (silence-to-rest ls1)
   "
    Condenses SkipEvents surrounded by BarChecks to MultiMesureRests.
    Gives an error "Wrong type (expecting pair): ()" when list ends
    with a SkipEvent without a Barcheck after it.
    This procedure returns a list, which should be applied with:
    (make-music
  'ContextSpeccedMusic
  'context-type 'Score
  'element (make-music
  'PropertySet
  'value #t
  'symbol 'skipBars))
     "
   (define (helper e1 e2 ls2 n after-barcheck? before-barcheck?)
;     (write (display-lily-music (make-music 'SequentialMusic 'elements ls2) parser))
    (cond
     ;; wenn e1 letztes Element der Liste ist,
     ;; und keine Pausen zusammengefasst werden müssen
     ((and (not before-barcheck?) (null? e2))
      ;; e1 an Liste hängen
         (append ls2 (list e1)))
     ;; wenn e1 eine Unterliste ist (triolen e.t.c.) weitergehen
     ((not-has-duration? e1)
      (helper (car e2) (cdr e2)
        (append ls2 (list e1)) n
        after-barcheck? #f))
     ;; wenn e1 ein BarCheck ist,
     ;; weitergehen und after-barcheck? auf #t setzten
     ((barCheck? e1)
      (helper (car e2) (cdr e2)
        (append ls2 (list e1)) n
        #t #f))
     ;; wenn e1 ein SkipEvent ist und
     ((skipEvent? e1)
      (let* ((dur1 (ly:music-property e1 'duration))
             (len1 (ly:duration-log dur1))
             (dot1 (ly:duration-dot-count dur1))
             (sca1 (ly:duration-scale dur1)))
        (cond
         ;; .. das letzte Element
         ((and before-barcheck? (null? e2))
           ;; Liste mit MultiRest am Ende ausgeben
           (append ls2
             (list
              (make-music
               'MultiMeasureRestEvent
               'duration (ly:make-duration
                          len1 dot1 (+ n sca1)))
              (make-music (quote BarCheck)))))
         ;; wenn e1 ein SkipEvent ist und nächstes element ein BarCheck,
         ;; BarCheck löschen und before-barcheck? auf #t setzten
         ((and (barCheck? (car e2)) after-barcheck?)
          (helper e1 (cdr e2)
            ls2 n
            #t #t))
         ;; wenn e1 ein SkipEvent ist aber entweder direkt vorher, oder
         ;; nachher kein BarCheck ist, zu RestEvent umwandeln
         ((not before-barcheck?)
          (helper (car e2) (cdr e2)
            (append ls2
              (list
               (make-music
                'RestEvent
                'duration (ly:make-duration
                           len1 dot1 sca1)))) 0 ;; n
            #f #f))
         ;; wenn e1 auf ein BarCheck folgt,
         ;; ein SkipEvent ist und
         ;; nächstes (berreits gelöschtes) Element ein BarCheck ist:
         ;; und das Element nach dem BarCheck ein SkipEvent
         ;; mit darauf folgendem barcheck
         ;; (error ls1 nicht mit Barcheck aufhört)
         ((and before-barcheck?
               (skipEvent? (car e2))
               (barCheck? (cadr e2)))
          (let* ((dur2 (ly:music-property (car e2) 'duration))
                 (len2 (ly:duration-log dur2))
                 (dot2 (ly:duration-dot-count dur2)))
            ;; ..und die Längen übereinstimmen
            (if (and (eq? len1 len2)
                     (eq? dot1 dot2))
                ;; Pausen zusammen zusammenfassen und
                ;; after-barcheck auf #t setzen
                ;; before-barcheck auf #f setzten
                (helper (car e2) (cdr e2)
                  ls2 (+ n sca1)
                  #t #f)
                ;; ..und die Längen nicht übereinstimmen
                ;; Multirest ausgeben und
                ;; after-barcheck auf #t setzen
                ;; before-barcheck auf #f setzten
                (helper (car e2) (cdr e2)
                  (append ls2
                    (list
                     (make-music
                      'MultiMeasureRestEvent
                      'duration (ly:make-duration
                                 len1 dot1(+ n sca1)))
                     (make-music (quote BarCheck))))
                  0 ;; n
                  #t #f))))
         ;; wenn e1 auf ein BarCheck folgt,
         ;; ein SkipEvent ist und
         ;; nächstes (berreits gelöschtes) Element ein BarCheck ist:         
         ;; und das Element nach dem BarCheck KEIN! SkipEvent
         ((and before-barcheck?
               (or (not (skipEvent? (car e2)))
                   (not (barCheck? (cadr e2)))))
           ;; zu MultiRest umwandeln
           ;; after-barcheck auf #t setzen
           ;; before-barcheck auf #f setzten
           (helper (car e2) (cdr e2)
             (append ls2
               (list
                (make-music
                 'MultiMeasureRestEvent
                 'duration (ly:make-duration
                            len1 dot1 (+ n sca1)))
                (make-music (quote BarCheck))))
             0 ;; n
             #t #f)))))
    ;; keine besonderen Vorkommnisse, weiter in der Liste
    (else
     (helper (car e2) (cdr e2)
       (append ls2 (list e1)) 0
       #f #f))))
     ;; erster Aufruf
     (helper (car ls1) (cdr ls1) '() 0 #t #f))

silenceToRest =
#(define-music-function (parser location music)
   (ly:music?)
   (make-music 'SequentialMusic 'elements
     (cons (make-music
            'ContextSpeccedMusic
            'context-type 'Score
            'element (make-music
                      'PropertySet
                      'value #t
                      'symbol 'skipBars))
       (silence-to-rest (ly:music-property music 'elements)))))

compressSilentRests =
#(define-music-function (parser location music )
   (ly:music?)
   #{ \silenceToRest \unnestSequentialMusic $music #})



%%{

\compressSilentRests {
  d'1 |
  e'1 |
  { s8 d'4. s4 b'8 s | }
  \bar "||"
  s1 |
  s1 |
  s1 |
  s1 |
  s1 |
  \time 5/4
  s1*5/4 |
  {
    s1*5/4 |
    { s1*5/4 | }
  }
  \time 3/4
  s2. |
  s2.^"text" |
  s2. |
  \time 2/4
  \bar "||"
  s2 |
  s2*4 |
  s4 s4 |
  \time 1/4
  s4 |
  s4 |
 
}
%}


Vielleicht kann ja irgendwer was damit anfangen.
Viele Grüße,
Infranator