Deutsches Lilypond Forum (Archiv)
Allgemein => Fragen zu Funktionen => Thema gestartet von: infranator 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!
-
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
-
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
-
Ich habe mich ein bisschen in Scheme eingearbeitet (Vielen Dank an harm6! https://liarchiv.joonet.de/index.php?topic=1428.0 (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