Musikobjekte#
Der erste Schritt in LilyPonds Arbeitsprozess besteht darin, die Musik einzulesen, in Musikobjekte umzuwandeln und Musikfunktionen anzuwenden.
Musikfunktionen definieren#
Musikfunktionen sind das Hauptwerkzeug, um Musikobjekte zu erstellen und zu modifizieren. Das Grundgerüst zum Definieren einer Musikfunktion lautet:
meineFunktion =
#(define-music-function (arg1 arg2 ...) (type1? type2? ...)
body...)
Damit wird eine Funktion definiert, die mittels \meineFunktion
aufgerufen wird. Die Parameter, die für die Argumente arg1
, arg2
usw. übergeben werden, müssen dabei jeweils die Typenprädikate typ1?
, typ2?
usw. erfüllen. Der Funktionsrumpf („body“) ist eine Folge von Scheme-Ausdrücken; wie immer bei Scheme-Funktionen, werden diese Ausdrücke der Reihe nach ausgewertet, und der Wert des letzten Ausdrucks wird als Funktionswert zurückgegeben. Eine einfache Musikfunktion wäre:
\version "2.25.8"
vorlesen =
#(define-music-function (music) (ly:music?)
#{
<<
\new Voice $music
\new NoteNames $music
>>
#})
\vorlesen \relative c' { c d e c e f g e }
Output
Parameter-Typprüfung#
Alle Parameter, die einer Musikfunktion übergeben werden, werden darauf überprüft, ob sie den erwarteten Typ haben. Da Scheme latent typisiert ist (d.h. man kann den Typ eines gegebenen Objekts nicht direkt ablesen, sondern nur fragen, ob es zu einem bestimmten Typ gehört), sind typ1?
, typ2?
usw. Typenprädikate.
\version "2.25.8"
n-mal =
#(define-music-function (n music) (index? ly:music?)
#{ \repeat unfold #n { #music } #})
\n-mal 4 aes
Output
Diese (ziemlich langweilige) Musikfunktion liefert ein Kürzel für \repeat unfold ...
. Sie benötigt zwei Argumente, die hier n und music heißen. Das erste muss eine nicht-negative ganze Zahl sein, das zweite ein Musikobjekt. Wenn die Funktion aufgerufen wird, werden zur Typ-Prüfung die Ausdrücke (index? n)
und (ly:music? music)
getestet.
Besonders interessant wird das in einem Beispiel wie dem folgenden:
\version "2.25.8"
kurzeTonart =
#(define-music-function (duration pitch) (ly:duration? ly:pitch?)
#{ \key #pitch \major s $duration \key c \major #})
\new Staff <<
{ c'4 c' c' c' }
{ s2 \kurzeTonart 4 aes s4 }
>>
Output
Hier definieren wir eine weitere Musikfunktion namens \kurzeTonart
, wieder mit zwei Argumenten. Sie liefert einen Musikausdruck, der mit unsichtbaren Pausen dafür sorgt, dass die verlangte Dur-Tonart für eine bestimmte Dauer eingestellt und danach nach C-Dur zurückgekehrt wird.
Wir haben nun zwei verschiedene Funktionsaufrufe verwendet:
\n-mal 4 aes
\kurzeTonart 4 aes
Even though the arguments are exactly the same, they were obtained with
different types. The \nrepeats
function got an integer and a music expression.
The \keyDuring
function, in contrast, got a duration and a pitch! This is
thanks to the capabilities of the parser, coupled to the type predicates. When
4
and aes
are encountered, different rules are tried, until one is found
that allows for a successful match against the type predicate.
Vordefinierte Typenprädikate sind in der Notationsreferenz aufgeführt. Eine Tabelle der häufigsten findet sich im Abschnitt Das Wichtigste über Musikfunktionen.
Optionale Parameter#
Ein Funktionsargument wird als optional markiert, indem man sein Prädikat in Klammern (...)
setzt. Wenn die Funktion ohne dieses Argument aufgerufen wird, hat der Parameter den Wert FALSCH (#f
). Die folgende Funktion beispielsweise erzeugt eine Metronomangabe mit einem der häufigsten Werte, die jeder über ihren italienische Namen („Allegro“, „Andante“ usw.) ausgewählt werden. Der gedruckte Text ist optional; wird er nicht angegeben, so wird der italienische Name selbst verwendet.
\version "2.25.8"
tempi =
#'(("Largo" . 50)
("Lento" . 60)
("Adagio" . 70)
("Andante" . 90)
("Moderato" . 100)
("Allegro" . 140)
("Presto" . 170))
standardTempo =
#(define-music-function (gedruckter-name dauer name) ((markup?) ly:duration? string?)
#{
\tempo $(or gedruckter-name name) $dauer = $(assoc-ref tempi name)
#})
\relative c' {
\standardTempo 4 Adagio
c8 d e4 d c
\standardTempo "Allegro con brio" 4 Allegro
g'4 e'2 g,4
}
Output
Es ist auch möglich, innerhalb der Klammern einen anderen Standardwert als #f
für den optionalen Parameter festzulegen.
\version "2.25.8"
hintergrundCluster =
#(define-music-function (grauwert mus) ((number? 0.5) ly:music?)
#{
<<
$mus
{
\once \override ClusterSpanner.layer = 0
\once \override ClusterSpanner.color = #(rgb-color grauwert grauwert grauwert)
\makeClusters $mus
}
>>
#})
\new Voice \hintergrundCluster { <g' b''>2 <c''' g'''> }
\new Voice \hintergrundCluster 0.3 { <g' b''>2 <c''' g'''> }
Output
Obwohl optionale Parameter gelegentlich nützlich sind, haben sie auch ihre Grenzen.
Wenn der Parser bei einer Musikfunktion mit einem optionalen Argument rechnet, testet er den nächsten Parameter gegen das Typenprädikat für dieses optionale Argument. Wenn dieses Prädikat anschlägt, dann wird der Wert des Parameters für das optionale Argument benutzt. Andernfalls erhält das optionale Argument seinen Standardwert, und der Parameterwert wird für das nächste Argument getestet. Zu beachten ist die wichtige Einschränkung, dass ein Wert, der nicht das Prädikat des optionalen Parameters erfüllt hat, für eines der nachfolgenden Argumente des gleichen Funktionsaufrufs stehen muss, nicht für einen ganz anderen Ausdruck nach dem Funktionsaufruf. Falls das kompliziert klingt: Merken muss man sich nur, dass ein optionaler Parameter nur dann wirklich optional ist, wenn nach ihm noch erforderliche Argumente kommen, aber nicht, wenn er das letzte Argument ist. Versuchen wir, die Argumente der obigen Funktion \hintergrundCluster
zu tauschen:
\version "2.25.8"
hintergrundCluster =
#(define-music-function (mus grauwert) (ly:music? (number? 0.5))
#{
<<
$mus
{
\once \override ClusterSpanner.layer = 0
\once \override ClusterSpanner.color = #(rgb-color grauwert grauwert grauwert)
\makeClusters $mus
}
>>
#})
\new Voice \hintergrundCluster { <g' b''>2 <c''' g'''> } 0.3
% \new Voice \hintergrundCluster { <g' b''>2 <c''' g'''> } % funktioniert nicht
\new Voice \hintergrundCluster { <g' b''>2 <c''' g'''> } \default % funktioniert!
Output
Die letzte Zeile dieses Beispiels zeigt, wie man die beschriebene Einschränkung umgehen kann: Das Schlüsselwort \default
kann als Platzhalter angegeben werden, wenn der Parser das Weglassen des Parameters nicht akzeptiert.
Beachten Sie auch, dass Funktionsparameter gierig eingelesen werden. Das kann man am besten an einem Beispiel erklären, indem wir die Argumente dauer
und name
der oben vorgestellten Funktion standardTempo
vertauschen:
tempi =
#'(("Largo" . 50)
("Lento" . 60)
("Adagio" . 70)
("Andante" . 90)
("Moderato" . 100)
("Allegro" . 140)
("Presto" . 170))
standardTempo =
#(define-music-function (gedruckter-name name dauer) ((markup?) string? ly:duration?)
#{
\tempo $(or gedruckter-name name) $dauer = $(assoc-ref tempi name)
#})
\relative c' {
\standardTempo Adagio 4 % Fehler
c8 d e4 d c
}
Wir Menschen verstehen, dass \standardTempo
zwei Parameter übergeben werden (Adagio
und 4
), und da die Funktion drei Argumente hat, von denen eines optional ist, sollte dieses optionale Argument seinen Standardwert bekommen. Stattdessen aber produziert der obige Code einen Fehler! Der Grund dafür ist, dass der Parser zuerst überprüft, ob der String Adagio
ein möglicher Wert für das erste, optionale Argument ist. Dieses hat den Typ markup?
, und da Strings als Markup gelten, trifft dies zu: Also wird Adagio
als Wert des optionalen Arguments gedruckter-name
genommen. Als nächstes folgt der Wert 4
, aber dies ist kein zulässiger Wert für das folgende Argument name
, das ja als string?
definiert ist. Das bedeutet: Wenn nach einem optionalen Argument ein verpflichtendes Argument kommt, dann darf ein Parameterwert für das verpflichtende Argument nicht auch als Wert für das optionale Argument interpretierbar sein.
Schließlich noch ein Wort zu mehrfachen optionalen Argumenten: Wenn mehrere optionale Argumente hintereinander auftreten, bedeutet das Weglassen eines einzelnen von ihnen automatisch, dass alle weggelassen sind.
All that being said, optional arguments are still very useful, and many of
LilyPond’s built-in functions use them (e.g., \relative { ... }
or
\relative c' { ... }
, \time 9/8
or \time 2,2,2,3 9/8
). However, it may
take some thinking to write your functions in a way that accommodates their
restrictions. If you are running into trouble, a good strategy is to split out
the function into several functions. For example, instead of injecting
\override
s in the result if an optional argument is given, drop the optional
argument, and make a separate function that does the \override
s.
Andere Typen von Funktionen#
Eine Musikfunktion liefert stets Musik. Es gibt andere Arten von Funktionen, die jeweils auf einen bestimmten Rückgabe-Typ festgelegt sind. Ihr Vorteil ist, dass sie in anderen syntaktischen Kontexten eingesetzt werden können, weil der Parser den Typ des Funktionswerts im Voraus weiß. (TODO: überprüfen)
Funktionstyp |
Makro zum Definieren |
Typ des Rückgabewerts |
---|---|---|
Musikfunktion |
|
Musik ( |
Eventfunktion |
|
Angehängtes Event [im deutschen Lilypond-Handbuch: „Nachereignis“] ( |
Scheme-Funktion |
|
beliebig ( |
Funktion ohne Rückgabewert |
|
beliebig; ein eventueller Rückgabewert wird ignoriert |
BAUSTELLE: Hier fehlt noch ein Beispiel.
Das Kürzel \etc
#
Mit dem speziellen Syntaxelement \etc
kann man besonders bequem Musikfunktionen definieren. Das Prinzip ist, dass \etc
als Platzhalter für ein oder mehrere Parameter ganz am Ende einer Folge von Funktionsaufrufen verwendet werden kann. Ein Beispiel erklärt es am besten:
\version "2.25.8"
fürKlarinette = \compressMMRests \transpose bes c' \etc
\fürKlarinette { c' d' e' }
Output
\etc
funktioniert auch in einigen anderen Situationen:
\version "2.25.8"
textAbstand = \once \override TextScript.padding = \etc
{ \textAbstand 1.8 c'4^"piu mosso" }
Output
\version "2.25.8"
\markup rötlich = \markup \with-color "LightCoral" \etc
\markup \rötlich "Hallo"
Output
Musikausdrücke#
In den bisherigen Beispielen wurden einfach die Parameter einer Musikfunktion dazu benutzt, um Ausdrücke in LilyPond-Syntax zu bilden. Das ist nützlich als syntaktischer Zucker. In Wirklichkeit sind Musikfunktionen aber viel mächtiger – man denke nur an \transpose
: Sie erlauben es, Musikobjekte zu analysieren und neu zu konstruieren.
Der einfachste Weg, um zu sehen, wie eine bestimmte Musikfunktion aufgebaut ist, ist die Musikfunktion \displayMusic
oder, gleichwertig, die Scheme-Funktion display-scheme-music
. Sie versuchen, einen gültigen Scheme-Code auszugeben, der eine zur übergebenen Musik gleichwertigen Musikausdruck konstruiert. Betrachten wir ein erstes Beispiel:
\version "2.25.8"
\displayMusic { c' d'-> }
Output
Dies liefert die folgende Ausgabe auf der Konsole:
(make-music
'SequentialMusic
'elements
(list (make-music
'NoteEvent
'pitch
(ly:make-pitch 0 0)
'duration
(ly:make-duration 2))
(make-music
'NoteEvent
'articulations
(list (make-music
'ArticulationEvent
'midi-extra-velocity
20
'articulation-type
"accent"))
'duration
(ly:make-duration 2)
'pitch
(ly:make-pitch 0 1))))
Every music object has a type. Possible types are listed in the Internals
Reference at Music expressions. Moreover, it holds properties
that describe it. NoteEvent
objects, for instance, typically have a pitch and
a duration (pitch
and duration
properties). Optionally, they may contain
articulations (articulations
property). Note that the music type does not
prescribe the set of properties; music objects are structured by conventions,
not rules. It is allowed to read, define and set arbitrary music properties on
arbitrary music objects, although the most common case is defining/setting
properties that are understood by LilyPond’s built-in functions and engravers.
Jeder Musiktyp gehört außerdem zu gewissen Klassen von Musik. Diese dienen dazu, bestimmte Ereignistypen zusammenzufassen, die auf ähnliche Art verarbeitet werden müssen. Sie sind im Interna-Handbuch unter Music classes verzeichnet.
Die Namen von Musiktypen werden in GroßUndKleinschreibung (CamelCase) geschrieben, die von Musik-Klassen in kleinbuchstaben-mit-bindestrichen
- (music-is-of-type? music class)
Testet, ob music zur Musikklasse class gehört.
Eigenschaften von Musik#
Sobald man ein Musikobjekt vorliegen hat, kann man tolle Dinge anstellen, indem man seine Eigenschaften manipuliert. Die einschlägigen Funktionen sind ly:music-property
und ly:music-set-property!
(vgl. Probs).
Manche Musikausdrücke enthalten andere Musikausdrücke. Diese sind dann normalerweise in einer der folgenden Eigenschaften enthalten:
elements
ist eine Liste von Musikobjekten, etwa für die inSequentialMusic
,SimultaneousMusic
und anderen Behältern enthaltene Musik.articulations
ist ebenfalls eine Liste. Sie enthält alle an eine Note oder Pause angehängten Events.element
ist ein einzelnes Musikobjekt. Diese Eigenschaft ist relevant für Musikobjekte, die ihrer Aufgabe gemäß nur ein einziges Musikobjekt enthalten können. Ein Beispiel wäreRelativeOctaveMusic
: Dieses Objekt enthält ein einzigeselement
, nämlich die in ihr enthaltene Musik (in der im Fall vonRelativeOctaveMusic
die Konvertierung von relativen in absolute Tonhöhen als abgeschlossen angesehen wird).
Die Eigenschaft name
eines Musikobjekts enthält seinen Typ (etwa NoteEvent
) als Symbol. In den meisten Fällen sollte man Musiktypen aber anhand von Ereignisklassen erkennen, nicht anhand des Namens.
Konstruieren von Musikobjekten#
Man kann Musikobjekte auch direkt erzeugen, etwa für algorithmisches Komponieren, oder einfach zum Hinzufügen von Artikulationen.
- (make-music name eigenschaft1 wert1 eigenschaft2 wert2 ...)
Erzeugt ein Musikobjekt.
name ist der Musiktyp, gegeben als Symbol. Die übrigen Argumente treten paarweise auf: Auf den Namen einer Eigenschaft (als Symbol) folgt jeweils der Wert, den diese Eigenschaft im Musikobjekt haben soll.
Werden Eigenschaften mehrfach genannt, überschreiben die späteren Werte die früheren.
Anstelle eines Paars aus Eigenschaft und Wert kann man der Funktion auch ein Musikobjekt übergeben. In diesem Fall werden die Eigenschaften dieses Objekts übernommen. Etwaige weitere Eigenschaft-Wert-Paare überschreiben dann ggf. diese übernommenen Eigenschaften. Beispielsweise könnte man ein
NoteEvent
folgendermaßen in einClusterNoteEvent
verwandeln:(make-music 'ClusterNoteEvent ein-note-event)
Werkzeuge zum Transformieren von Musik#
Musikobjekte sind tief verschachtelte Strukturen, und oftmals weiß man im voraus nicht, wie tief die Verschachtelung reicht. Beispielsweise können Noten in beliebiger Tiefe innerhalb von SequentialMusic
, RelativeOctaveMusic
, SimultaneousMusic
usw. enthalten sein.
Die in diesem Abschnitt vorgestellten Funktionen erlauben das rekursive Verarbeiten von Musik.
- (music-map function music)
Erstellt ein neues Musik-Objekt, indem die Funktion function auf die in music enthaltene Musik „von unten nach oben“ angewandt wird. Die Funktion wird also zuerst auf die ganz unten in der Verschachtelungs-Hierarchie stehenden Musikobjekte angewandt, die selbst keine weiteren Musikobjekte enthalten. Sie werden in den sie enthaltenen (eine Hierarchiestufe höher gelegenen) Musikobjekten durch die Musik, die durch das Anwenden der Funktion function entsteht. Dann wird die Funktion auf die Musik der nächsthöheren Schicht angewandt, und immer weiter, bis zuletzt der oberste Musikausdruck music selbst an der Reihe ist.
Aus Effizienzgründen arbeitet
music-map
destruktiv mit dem Musikobjekt music. Das bedeutet, dass man in manchen Fällen Musik kopieren muss.Das folgende Beispiel ersetzt alle Wiederholungen in der Musik durch Faulenzerzeichen [Lilypond-Handbuch: „Prozent-Wiederholungen“]. Dazu werden alle Arten von Wiederholungen, die allesamt charakteristiert sind durch ihre gemeinsame Musikklasse
repeated-music
, in den TypPercentRepeatedMusic
verwandelt.\version "2.25.8" faulenzen = #(define-music-function (music) (ly:music?) (music-map (lambda (m) (if (music-is-of-type? m 'repeated-music) (make-music 'PercentRepeatedMusic m) m)) music)) musik = \relative { \clef bass \repeat unfold 2 << { s4 <g a c ees> s <gis b d f> s <a c ees g> s <gis b d f> } \\ { c, s g s c s g s } >> } { \musik } \faulenzen \musik
Output
- (music-filter predicate? music)
Entfernt alle Musikausdrücke aus music, die nicht das Prädikat predicate? erfüllen.
- (for-some-music function music)
Diese Funktion arbeitet ähnlich wie
music-map
, allerdings wird die Funktion function hier zunächst auf den obersten Musikausdruck music angewandt, dann auf dessen direkte Kinder, usw. Außerdem liefertfor-some-music
nicht die veränderte Musik zurück: Die Funktion function sollte die ihr übergebene Musik direkt verändert. Das ist oft nützlich, um Musik-Eigenschaften festzulegen, währendmusic-map
besser geeignet ist, um neue Musikobjekte zu konstruieren.Weiter steigt
for-some-music
nur dann rekursiv zur Kinder-Ebene hinab, wenn function den Wert#f
zurückgegeben hat. Man kann sich also vorstellen, dass function erstens die Musik verändert und zweitens die Frage „Aufhören?“ beantwortet.Ein einfaches Beispiel wäre eine Funktion, die eine bestimmte Artikulation zu allen Noten hinzufügt. Hier wird die Stopp-Bedingung benutzt, um zu verhindern, dass im Falle von Akkorden die Artikulation nicht nur zum Akkord selbst, sondern auch zu allen seinen einzelnen Noten hinzugefügt wird, was sonst zu doppelten Artikulationszeichen führen würde.
\version "2.25.8" mitStaccato = #(define-music-function (music) (ly:music?) (for-some-music (lambda (m) (if (or (music-is-of-type? m 'note-event) (music-is-of-type? m 'event-chord)) (begin (ly:music-set-property! m 'articulations (cons (make-music 'ArticulationEvent 'articulation-type 'staccato) (ly:music-property m 'articulations))) #t) #f)) music) music) \mitStaccato { c' d' <e' f'> }
Output
- (map-some-music function music)
Wie
for-some-music
, aber Einträge inelements
undarticulations
, die nach dem Anwenden von function keine Musikobjekte mehr sind, werden entfernt. Das ermöglicht das Konstruieren von Filtern.
Musik kopieren#
Weil music-map
und verwandte Funktionen die ihnen übergebene Musik direkt verändern, muss man manchmal Musikobjekte kopieren.
- (ly:music-deep-copy music)
Erstellt rekursiv („tief“) eine Kopie von music.
Tonhöhen#
Tonhöhen sind der wichtigste Teil der Noteneingabe. Sie sind in jedem NoteEvent
(d.h. in jeder Note) enthalten, aber auch beispielsweise in jedem KeyChangeEvent
(also einem Tonartwechsel). Viele Musikfunktionen arbeiten direkt mit ihnen.
Die wichtigste Methode, Tonhöhen einzugeben, ist das Verwenden derjenigen Notennamen, die durch die Spracheinstellung mittels \language
festgelegt werden. Das funktioniert auch beim Zuweisen von Tonhöhen an Variablen und in #{ ... #}
-Konstrukten.
\version "2.25.8"
meineTonhöhe = ces
\transpose c \meineTonhöhe { c' e' g' c'' }
$(let ((noch-eine-tonhöhe #{ bes, #}))
#{ \transpose c #noch-eine-tonhöhe { c' e' g' c'' } #})
Output
Man kann aber Tonhöhen auch direkt in Scheme erzeugen, und zwar mit der unten vorgestellten Funktion ly:make-pitch
.
Eine Tonhöhe in LilyPond besteht aus drei Teilen: Einer Oktavangabe, dem Notennamen und der Alteration. Wichtig ist, dass Tonhöhen nicht identisch sind nicht Frequenzen: Cis und Des sind verschiedene Tonhöhen!
LilyPond stellt eine ganze Anzahl von Funktionen bereit, um mit Tonhöhen zu arbeiten. Sie alle sind im Internals-Handbuch unter Scheme functions aufgeführt; wir stellen hier nur die wichtigsten vor:
- (ly:make-pitch octave note alteration)
Konstruiert ein Tonhöhen-Objekt.
octave ist eine ganze Zahl. Null steht dabei für die Oktave, die das eingestrichene c („mittleres c“) enthält.
note (in LilyPond auch öfters notename genannt) ist ein Index innerhalb der Stammtonreihe, von 0 (c) bis 6 (h).
Der optionale Parameter alteration ist ein Bruch: 0 bezeichnet den Stammton, 1/2 die Erhöhung um einen Halbton (♯), -1/2 die Erniedrigung um einen Halbton (♭). Es können aber auch beliebige andere Brüche übergeben werden, so dass auch doppelte oder mikrotonale Alterationen möglich sind.
Nützlich sind die Konstanten
SHARP
undFLAT
, die global als 1/2 bzw. -1/2 definiert sind. Es gibt aber auchSEMI-SHARP
,SEMI-FLAT
und weitere; sie alle finden sich am Beginn der Quelltext-Datei [scm/lily-library.scm
][lily-library].
- (ly:pitch-octave pitch)
- (ly:pitch-notename pitch)
- (ly:pitch-alteration pitch)
Diese Funktionen extrahieren jeweils eine der drei Komponenten aus der Tonhöhe pitch.
- (ly:pitch-steps pitch)
Liefert die Anzahl der (diatonischen) Tonschritte vom c¹ zur Tonhöhe pitch. Hier werden also nur octave und notename genutzt, nicht jedoch alteration: Beispielsweise liegt dis² acht Schritte oberhalb von c¹, es² dagegen neun Schritte.
- (ly:pitch-tones pitch)
Abstand zwischen c¹ und der Tonhöhe pitch in Ganztönen, angegeben als rationale Zahl. Hier werden octave, notename und alteration berücksichtigt.
- (ly:pitch-transpose pitch delta)
- (+ pitch delta)
Liefert die Tonhöhe, die sich ergibt, wenn man die Tonhöhe pitch um delta transponiert. Mit
\transpose c' #delta
wird genau diese Operation auf alle Tonhöhen der Musik angewandt.Das Resultat des Transpositionsvorgangs ist durch folgende zwei Eigenschaften definiert:
(ly:pitch-steps ergebnis)
ist die Summe von(ly:pitch-steps pitch)
und(ly:pitch-steps delta)
,(ly:pitch-steps ergebnis)
ist die Summe von(ly:pitch-steps pitch)
und(ly:pitch-steps delta)
,
Dass die tones-Zahlen addiert werden (Tonhöhen, gemessen in Ganztönen, als rationale Zahl), sorgt dafür, dass die Transposition die richtige klingende Tonhöhe ergibt. Dass die steps-Zahlen (Anzahl der diatonischen Tonschritte) addiert werden, sorgt für enharmonische Korrektheit der Transposition, also dass z.B. mit delta = ais um eine übermäßige Sexte transponiert wird, mit delta = b um eine kleine Septime.
The form with
+
is new in version 2.25.7.
- (ly:pitch-diff pitch root)
- (- pitch root)
Liefert die Differenz delta, um die man den Grundton root transponieren muss, um pitch zu erhalten.
\transpose #p1 #p2 ...
verändert jede Tonhöhe pitch aus der Musik zu(ly:pitch-transpose pitch (ly:pitch-diff p2 p1))
.The form with
-
is new in version 2.25.7.
Dauern und Momente#
Jede Note hat eine Dauer (duration), die das Druckbild der Note bestimmt. Normalerweise wird sie in LilyPond direkt nach der Tonhöhe angegeben: Beispielsweise sind 8
oder 4..*3/8
Dauern. Genauer gesagt besteht eine Dauer aus einer Hauptlänge, einer Anzahl von (Augmentations-)Punkten und einem optionalen Faktor. Die Hauptlänge in den gerade genannten Beispielen ist 8
bzw. 4
. Intern wird sie, mathematisch gesprochen, durch ihren negativen Zweierlogarithmus repräsentiert: 0 bezeichnet eine ganze Note, 1 eine halbe Note, 2 eine Viertelnote etc. Der optionale Faktor ist eine rationale Zahl, beispielsweise *3/8
in 4..*3/8
. Wenn er angegeben ist, verändert sich die effektive Länge der Note, ohne dass sich ihr optisches Erscheinungsbild ändert. Die Länge spielt eine Rolle für die Synchronisierung mehrerer Stimmen, für die horizontale Positionierung, und für die MIDI-Wiedergabe. Die Auswirkung von Längenfaktoren kann man im folgenden Beispiel gut studieren:
\version "2.25.8"
<< { c''4 4*1/2 4*1/2 4..*4/7 4 } \\ { c'4 4 4 4 } >>
Output
Ein Moment ist eine Längenangabe oder ein Zeitpunkt (wie ihn etwa MIDI-Töne haben). Man kann ihn sich grob als rationale Zahl vorstellen; verkompliziert wird die Angelegenheit aber durch das Problem von Vorschlagnoten: Sie hätten in einer solchen gewöhnlichen Zeitskala die Länge Null. Aus diesem Grund besteht ein Moment in Wirklichkeit aus zwei rationalen Zahlen, nämlich einem Hauptteil und einem Vorschlagteil.
You can obtain the length of a duration as a moment. The reverse conversion is
not possible, simply because several different durations can have the same
length. A moment lasting 7/8 of an eighth note is the length of the duration
16..
, but also the length of 8*7/8
. In the output, the first is reflected by
a double-dotted sixteenth note while the second is an eighth note (perhaps part
of a Baroque score where complex tuplets are written without too much care for
exact values).
Dauern werden meist in der vertrauten LilyPond-Syntax eingegeben. Das funktioniert auch innerhalb #{ ... #}
:
\version "2.25.8"
meineDauer = ##{ 4.. #}
{ c' $meineDauer }
Output
Dauern können aber auch mit einem Scheme-Interface konstruiert werden. Für Momente ist das Konstruieren in Scheme die einzige Möglichkeit, da sie normalerweise nicht von den Anwendern eingegeben werden.
- (ly:make-duration längen-logarithmus punktierung faktor)
Erzeugt eine Dauer.
- (ly:duration-length duration)
Liefert die effektive Länge der Dauer duration (als Moment).
- (ly:duration-log duration)
- (ly:duration-dot-count duration)
- (ly:duration-scale duration)
Diese drei Funktionen extrahieren die drei Komponenten einer Dauer.
- (ly:make-moment haupt vorschlag)
Erzeugt einen Moment, dessen Haupt- und Vorschlags-Anteil durch die rationalen Zahlen haupt und vorschlag gegeben sind.
- (ly:music-length music)
Liefert die Gesamtlänge der Musik music als Moment.
- (ly:moment-main moment)
- (ly:moment-grace moment)
Extrahiert den Haupt- bzw. Vorschlaganteil des Moments moment.
- (ly:moment-add moment1 moment2)
- (+ moment1 moment2)
- (ly:moment-sub moment1 moment2)
- (- moment1 moment2)
- (ly:moment-mul moment rational)
- (* moment rational)
- (ly:moment-div moment rational)
- (/ moment rational)
- (ly:moment-mod moment rational)
Arithmetic on moments.
Addition and subtraction simply add and subtract the main and grace parts, respectively. Multiplication and division work between a moment and a rational number (meaning a Scheme fraction like
5/6
; integers are a special case of fractions). If you understand and like this formulation, moments are simply the isomorphically unique 2-dimensional vector space over ℚ.The forms with standard Scheme operators (
+
,-
,*
and/
) are new in version 2.25.7.