Autor Thema: mehrere ganztaktige Pausen zusammenfassen  (Gelesen 1989 mal)

infranator

  • Member
mehrere ganztaktige Pausen zusammenfassen
« am: Mittwoch, 12. Dezember 2012, 15:35 »
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

  • Member
Re: mehrere ganztaktige Pausen zusammenfassen
« Antwort #1 am: Mittwoch, 12. Dezember 2012, 20:28 »
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

  • Member
Re: mehrere ganztaktige Pausen zusammenfassen
« Antwort #2 am: Mittwoch, 12. Dezember 2012, 22:26 »
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

  • Member
Re: mehrere ganztaktige Pausen zusammenfassen
« Antwort #3 am: Samstag, 15. Juni 2013, 20:09 »
Ich habe mich ein bisschen in Scheme eingearbeitet (Vielen Dank an harm6! https://liarchiv.joonet.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