Deutsches Lilypond Forum (Archiv)
Allgemein => Fragen zu Funktionen => Thema gestartet von: barrio am Freitag, 25. März 2016, 09:47
-
Hallo zusammen,
ich versuche mit meinem langsam wachsenden Guileverständnis einige snippets aus den docs nachzuvollsziehen, darunter folgendes wie o.g.:
%Association list of pitches to colors.
#(define color-mapping
(list
(cons (ly:make-pitch 0 0 NATURAL) (x11-color 'red))
(cons (ly:make-pitch 0 0 SHARP) (x11-color 'green))
(cons (ly:make-pitch 0 1 FLAT) (x11-color 'green))
(cons (ly:make-pitch 0 2 NATURAL) (x11-color 'red))
(cons (ly:make-pitch 0 2 SHARP) (x11-color 'green))
(cons (ly:make-pitch 0 3 FLAT) (x11-color 'red))
(cons (ly:make-pitch 0 3 NATURAL) (x11-color 'green))
(cons (ly:make-pitch 0 4 SHARP) (x11-color 'red))
(cons (ly:make-pitch 0 5 NATURAL) (x11-color 'green))
(cons (ly:make-pitch 0 5 FLAT) (x11-color 'red))
(cons (ly:make-pitch 0 6 SHARP) (x11-color 'red))
(cons (ly:make-pitch 0 1 NATURAL) (x11-color 'blue))
(cons (ly:make-pitch 0 3 SHARP) (x11-color 'blue))
(cons (ly:make-pitch 0 4 FLAT) (x11-color 'blue))
(cons (ly:make-pitch 0 5 SHARP) (x11-color 'blue))
(cons (ly:make-pitch 0 6 FLAT) (x11-color 'blue))))
%Compare pitch and alteration (not octave).
#(define (pitch-equals? p1 p2)
(and
(= (ly:pitch-alteration p1) (ly:pitch-alteration p2))
(= (ly:pitch-notename p1) (ly:pitch-notename p2))))
#(define (pitch-to-color pitch)
(let ((color (assoc pitch color-mapping pitch-equals?)))
(if color
(cdr color))))
#(define (color-notehead grob)
(pitch-to-color
(ly:event-property (event-cause grob) 'pitch)))
\score {
\new Staff \relative c' {
\override NoteHead.color = #color-notehead
c8 b d dis ees f g aes
}
}
Fragen:
1) Wozu braucht man überhaupt "pitch-equals?" (der Kommentar hilft mir leider nichtweiter) ? Ich habe es mal probeweise rausgelöscht, das Resultat ist unverändert?!? Assoc wirft mir doch ein (pitch . color) pair aus color-mapping raus, wenn es eines findet, oder? Wenn man dahinter einfach den Aufruf pitch-equals? ohne Parameter schreibt, wieso schmeißt das keinen Fehler? Rätsel über Rätsel...:-)
2) Ist color-notehead sowas wie ein event-hook, nach dem Motto: Wenn ein (in diesem Fall NoteHead) grob erstellt wird, rufe pitch-to-color mit der entsprechenden pitch des zu erstellenden grobs auf?
Herzlichen Dank schon mal im voraus für Eure Mühe.
barrio
-
1) Wozu braucht man überhaupt "pitch-equals?" (der Kommentar hilft mir leider nichtweiter) ? Ich habe es mal probeweise rausgelöscht, das Resultat ist unverändert?!? Assoc wirft mir doch ein (pitch . color) pair aus color-mapping raus, wenn es eines findet, oder? Wenn man dahinter einfach den Aufruf pitch-equals? ohne Parameter schreibt, wieso schmeißt das keinen Fehler? Rätsel über Rätsel...:-)
Das Resultat bleibt in diesem Beispiel gleich, ja. Wie hier (https://www.gnu.org/software/guile/manual/html_node/SRFI_002d1-Association-Lists.html) dokumentiert, hat assoc außer nem Schlüssel und ner Alist auch ein drittes optionales Argument; wird dieses nicht angegeben, wird für die Gleichheitsprüfung equal? verwendet. pitch-equals? testet nur auf Alteration und Notenname, nicht aber auf Oktavlage. Somit wird z. B. jedes C rot eingefärbt. Mit equal? würde nur das eingestrichene c rot und die anderen Cs blieben schwarz; im Beispiel kommen halt keine Töne aus anderen Oktaven vor, deshalb fällts nicht auf.
2) Ist color-notehead sowas wie ein event-hook, nach dem Motto: Wenn ein (in diesem Fall NoteHead) grob erstellt wird, rufe pitch-to-color mit der entsprechenden pitch des zu erstellenden grobs auf?
Fast. Statt NoteHead.color auf einen festen Wert wie #red zu setzen, wird es hier auf eine Funktion gesetzt, die als Argument ein Grob (nämlich besagten NoteHead) bekommt und eine Farbe zurückgibt. Um jetzt an den pitch zu kommen, muss erstmal das NoteEvent herausgefunden werden, welches für den NoteHead verantwortlich ist; dafür gibts die Funktion event-cause.
Ganz kurz sieht also der Ablauf folgendermaßen aus:
NoteHead → Argument „grob“ in color-notehead → verursachendes NoteEvent → pitch → color
statt
NoteHead → color
-
zu 1) o.k. das hatte ich vermutet, wollte nur sicher gehen
zu 2) So ganz hats noch nicht klick gemacht. Wo kriegt denn color-notehead sein Argument grob überhaupt her? Holt es sich das im Funktionsrumpf etwa selber? Und wozu muss es dann als Parameter angegeben werden?
-
Es gibt zwei Möglichkeiten, einer grob property etwas zuzuweisen:
1. Eine Konstante. Kennt man ja, z. B. \override NoteHead.color = #red
2. Eine Funktion, die ein Grob erwartet und einen Wert zurückliefert, z. B. \override NoteHead.color = #(lambda (grob) …)
Im zweiten Fall wird an diese zugewiesene Funktion eben das Grob übergeben, auf den sich der override bezieht. Bzw. die Funktion wird mit jedem auftretenden Grob dieser Sorte neu aufgerufen (also hier für jede folgende NoteHead-Instanz).