Allgemein > Allgemeine Diskussion
Scheme
iugin:
Hallo miteinander
erstens: danke infranator für die Links, die sind sehr hilfsreich :)
Ich komme jetzt mit einer konkreten Frage: ich möchte die Hemiolen in einem Stück mit Klammern markieren, und ich weiss, ich kann \startGroup und \stopGroup benutzen.
Ich habe mich alledings gefragt, ob ich eine Scheme-Funktion schreiben kann, mit der ich einfach z.B. \klammer{c d e} schreiben kann.
Das erste das ich gemacht habe ist zu schauen, wie die Musik in Scheme übersetzt wird.
Dieser Code
--- Code: ---\version "2.18.0"
\layout {
\context {
\Voice
\consists "Horizontal_bracket_engraver"
}
}
\displayMusic
\relative c'' {
c4\startGroup d
e\stopGroup
}
--- Ende Code ---
ergibt
--- Code: ---(make-music
'RelativeOctaveMusic
'element
(make-music
'SequentialMusic
'elements
(list (make-music
'NoteEvent
'articulations
(list (make-music
'NoteGroupingEvent
'span-direction
-1))
'duration
(ly:make-duration 2 0 1)
'pitch
(ly:make-pitch 1 0 0))
(make-music
'NoteEvent
'pitch
(ly:make-pitch 1 1 0)
'duration
(ly:make-duration 2 0 1))
(make-music
'NoteEvent
'articulations
(list (make-music
'NoteGroupingEvent
'span-direction
1))
'pitch
(ly:make-pitch 1 2 0)
'duration
(ly:make-duration 2 0 1)))))
--- Ende Code ---
Jetzt glaube ich, ich sollte, in meinem Befehl \klammer{c d e} die Musik durchlaufen können, so dass ich bei der ersten Note folgendes hinfügen kann:
--- Code: ---'articulations
(list (make-music
'NoteGroupingEvent
'span-direction
-1))
--- Ende Code ---
und bei der letzten dasselbe einfach mit dem Wert 'span-direction 1.
Wie ich eine Artikulation hinfügen kann, sehe ich hier: http://lilypond.org/doc/v2.19/Documentation/extending/adding-articulation-to-notes-_0028example_0029.de.html
Das funktioniert aber nur mit einer Note, und nicht mit einer Sequenz.
Erstens: Eine Note ist anscheinend ein music-event. Ist eine Sequenz eine List aus music-events? Es scheint aus dem obigen Code so zu sein: 'SequentialMusic hat 'elements der eine Liste aus NoteEvents ist.
Zweitens: Wenn schon, wie kann ich die Sequenz durchlaufen (ich habe hier http://lilypondblog.org/2014/04/music-functions-3-reusing-code/ von maps gelesen, und habe das Gefühl, es geht in die Richtung), und nur das erste und das letzte Element rausnehmen?
Ich wünsche der ganzen Scheme-Selbsthilfegruppe einen schönen Tag
Liebe Grüsse
Eugenio
infranator:
--- Zitat ---Erstens: Eine Note ist anscheinend ein music-event. Ist eine Sequenz eine List aus music-events? Es scheint aus dem obigen Code so zu sein: 'SequentialMusic hat 'elements der eine Liste aus NoteEvents ist.
--- Ende Zitat ---
Genauso ist es!
--- Zitat ---Zweitens: Wenn schon, wie kann ich die Sequenz durchlaufen (ich habe hier http://lilypondblog.org/2014/04/music-functions-3-reusing-code/ von maps gelesen, und habe das Gefühl, es geht in die Richtung), und nur das erste und das letzte Element rausnehmen?
--- Ende Zitat ---
Vielleicht geht es irgendwie mit maps, das habe ich bis jetzt aber noch nie benutzt. Ich glaube aber, maps ist eher dazu geeignet, music-events unabhängig voneinander zu bearbeiten.
Mit Rekursion weiß ich aber wie es geht.
--- Code: ---\version "2.19.5"
\layout {
\context {
\Voice
\consists "Horizontal_bracket_engraver"
}
}
#(define (add-grouping dir note-event)
"Add an NoteGroupingEvent to the articulations of `note-event',
which is supposed to be a NoteEvent expression."
(set! (ly:music-property note-event 'articulations)
(cons (make-music 'NoteGroupingEvent
'span-direction dir)
(ly:music-property note-event 'articulations)))
note-event)
#(define (helper ls1 ls2)
"Add a NoteGroupingEvent with the direction -1 to the first
and one with the direction 1 to the last NoteEvent of
a SequentialMusic expression"
(if (eq? 1 (length ls1))
; wenn ls1 nur noch aus einem element besteht
; Schluss mit der Selbstaufrufung, das Ende von der Klammer
; an die letzte Note hängen und das ganze umdrehen
(reverse (cons (add-grouping 1 (car ls1)) ls2))
(if (null? ls2)
; ls2 ist noch leer, das heißt (car ls1) ist das
; erste Element in der Liste. Start der klammer an die
; Note hängen und weiter
(helper
(cdr ls1)
(cons (add-grouping -1 (car ls1)) ls2))
; (car ls1) ist weder das letzte noch das erste
; Element in der Liste. Nichts verändern und ein
; Element weiter gehen
(helper
(cdr ls1)
(cons (car ls1) ls2)))))
klammer =
#(define-music-function (parser location music) (ly:music?)
(make-music
'SequentialMusic
'elements
(helper (ly:music-property music 'elements) '())))
{
c'4 \klammer { d' e' f' }
a' b'2.
}
--- Ende Code ---
Die Funktion add-grouping ist eine Bearbeitung von der add-accent Funktion aus dem Handbuch. Jetzt fügt sie aber den Start oder das Ende einer einer Grouping Klammer hinzu. Je nachdem, ob sie mit -1 oder 1 aufgerufen wird.
Die helper Funktion geht ein Element nach dem anderen in der Liste durch. Nur das erste und das letzte wird verändert.
Die klammer Funktion ruft die helper Funktion auf.
Man muss die Elemente von SequentialMusic mit (ly:music-property x 'elements) aufrufen, damit man die einzelnen music-events mit car und cdr e.t.c. ansteuern, und dann bearbeiten kann.
infranator:
Es geht auch viel einfacher..
https://liarchiv.joonet.de/index.php?topic=1747.0
mit (last LISTE) oder (car (reverse LISTE)) kann man natürlich auch das letzte element direkt ansteuern, ohne die ganze Geschichte mit der Rekursion.
Wie war das nochmal mit dem Wald und den Bäumen? ;-)
harm6:
--- Zitat von: infranator ---Es geht auch viel einfacher..
https://liarchiv.joonet.de/index.php?topic=1747.0
mit (last LISTE) oder (car (reverse LISTE)) kann man natürlich auch das letzte element direkt ansteuern, ohne die ganze Geschichte mit der Rekursion.
--- Ende Zitat ---
Hallo infranator,
ich finde Deinen Code richtig gut.
Das Problem ist jedoch, er funktioniert nicht immer:
--- Code: ---\version "2.18.0"
\layout {
\context {
\Voice
\consists "Horizontal_bracket_engraver"
}
}
#(define (add-grouping dir note-event)
"Add an NoteGroupingEvent to the articulations of `note-event',
which is supposed to be a NoteEvent expression."
(set! (ly:music-property note-event 'articulations)
(cons (make-music 'NoteGroupingEvent
'span-direction dir)
(ly:music-property note-event 'articulations)))
note-event)
#(define (helper ls1 ls2)
"Add a NoteGroupingEvent with the direction -1 to the first
and one with the direction 1 to the last NoteEvent of
a SequentialMusic expression"
(if (eq? 1 (length ls1))
; wenn ls1 nur noch aus einem element besteht
; Schluss mit der Selbstaufrufung, das Ende von der Klammer
; an die letzte Note hängen und das ganze umdrehen
(reverse (cons (add-grouping 1 (car ls1)) ls2))
(if (null? ls2)
; ls2 ist noch leer, das heißt (car ls1) ist das
; erste Element in der Liste. Start der klammer an die
; Note hängen und weiter
(helper
(cdr ls1)
(cons (add-grouping -1 (car ls1)) ls2))
; (car ls1) ist weder das letzte noch das erste
; Element in der Liste. Nichts verändern und ein
; Element weiter gehen
(helper
(cdr ls1)
(cons (car ls1) ls2)))))
klammer =
#(define-music-function (parser location music) (ly:music?)
(make-music
'SequentialMusic
'elements
(helper (ly:music-property music 'elements) '())))
\relative c' {
c4
\klammer { d \times 2/3 { c d c } }
\klammer { <d f>2 \repeat volta 2 { e4 f } }
b1
}
--- Ende Code ---
In diese Falle bin ich schon selbst gelaufen.
Siehe Diskussion hier.
Die Tipps die David Kastrup gab, führen hier zu folgendem:
--- Code: ---\version "2.19.4"
% see:
% http://lilypond.1069038.n5.nabble.com/review-of-a-Mutopia-file-why-TabStaff-gives-error-here-td136690.html
% http://lsr.dsi.unimi.it/LSR/Item?id=857
#(define (group-start-stop mus)
(let ((elts (extract-typed-music mus '(rhythmic-event event-chord))))
(for-each
(lambda (sel)
(let ((m (sel elts)))
(if (music-is-of-type? m 'event-chord)
(set! (ly:music-property m 'elements)
(cons (make-music 'NoteGroupingEvent
'span-direction (sel '(-1 1)))
(ly:music-property m 'elements)))
(set! (ly:music-property m 'articulations)
(cons (make-music 'NoteGroupingEvent
'span-direction (sel '(-1 1)))
(ly:music-property m 'articulations))))))
(list last first)))
mus)
grouping =
#(define-music-function (parser location music) (ly:music?)
(group-start-stop music))
\relative c' {
c4
\grouping { d4 \times 2/3 { c d c } }
\grouping { <d f>2 \repeat volta 2 { e4 f } }
b1
}
--- Ende Code ---
Zusätzlich habe ich im Falle eines EventChord das 'NoteGroupingEvent in die 'elements gepackt und nicht in die 'articulations.
Es macht tatsächlich keinen Unterschied, aber die manuelle Eingabe mit \startGroup, etc würde so verfahren.
Falls sich die interne Struktur von LilyPond mal ändern sollte, ist es auf jeden Fall richtig. ;)
Ich habe auch versucht
\grouping { \repeat unfold 4 c''4 }
möglich zu machen, bin aber bislang gescheitert.
Wäre schön, denn mit \repeat unfold ... klappt selbst die manuelle Eingabe via \startGroup, \stopGroup derzeit nicht.
HTH,
Harm
iugin:
Hallo miteinander
ihr werdet mich aus dem Forum rausschmeissen... ;D
Ich habe den Code von Infranator ziemlich genau angeschaut, und mit grosser Mühe habe etwas verstanden, auch dank den guten Kommentaren.
Jetzt, abgesehen davon, ob es immer funktioniert oder nicht, sind mir ein paar grundlegende Fragen in den Sinn gekommen.
- (define-music-function) ist nur die Funktion die vom normalen Lilypond Code aufgerufen wird, oder? Alle andere sind nur mit (define) definiert.
- (make-music) ist immer gefolgt von einem Namen gross geschrieben (wie zb. 'SequentialMusic) und 'elements oder 'articulations oder so. Das Apostroph bedeutet, dass sie Liste sind.
'SequentialMusic finde ich in der IR bei der Music expression, 'elements in den Music properties. Ungefähr sollte es heissen: Mach Sequentielle Musik mit folgenden Eigenschaften. Heisst es, dass (make-music) nur zwei Argumente (Listen) nimmt, eine Music Expression und eine Music property, wobei die properties sich auf die expressions beziehen?
Wie ihr seht, sind meine Probleme sehr grundlegend, ich bin aber schon froh, dass ich die Programme zu verstehen beginne (die einfache).
Liebe Grüsse und Danke :)
Eugenio
Navigation
[0] Themen-Index
[#] Nächste Seite
[*] Vorherige Sete
Zur normalen Ansicht wechseln