Text/Rehearsal Marks über den Akkordnamen ausrichten

Begonnen von Chris, Montag, 22. Juli 2019, 12:47

« vorheriges - nächstes »

Chris

Guten Tag!

Vor wenigen Tagen habe ich Lilypond entdeckt und bin begeistert. Also versuche ich mich gerade daran, einige Lieder nachzubauen, um ein eigenes kleines Liedheft zusammenzustellen. Im Detail ergeben sich dann aber doch einige Schwierigkeiten für mich.

Da ich inzwischen das Internet leergesucht habe und mir alles, was ich gefunden habe, nicht geholfen hat, frage ich nochmal direkt, wo ich auf dem Schlauch stehe. Ich habe ein Lied gesetzt, darüber die Akkorde. So weit so gut. Nun möchte ich, dass über dem Beginn der Strophen sowie über dem Beginn des Refrains die Texte "Strophen" und "Refrain" stehen - und zwar über den Akkordnamen.

Mit "Strophen" klappt das einigermaßen, denn dieses Wort kann sich in den akkordlosen Auftakt einfügen. Nicht so jedoch "Refrain". Das G-Dur schiebt, so scheint es mir, den "Refrain" wild in der Gegend umher. Kann mir hierbei bitte jemand helfen? "Refrain soll einfach nur linksbündig über dem "G" bzw. über der Note "h" nach Beginn der Wiederholung stehen.


\version "2.18.2"

#(set! paper-alist (cons '("a5 angepasst" . (cons (* 123 mm) (* 160 mm))) paper-alist))
#(set-global-staff-size 16)


\paper {
  #(set-paper-size "a5 angepasst")
  indent = #0
  left-margin = #0
  right-margin = #0
  top-margin = #0
  bottom-margin = #0
  myStaffSize = #10
  #(define fonts
     (make-pango-font-tree
      "Aller"
      "Aller"
      "Aller"
      (/ myStaffSize 12)
      ))
}

\layout {
  \context {
    \Score
    \remove "Bar_number_engraver"
    \override RehearsalMark.font-size = #-1
    \override RehearsalMark.font-series = #'bold
    \override RehearsalMark.Y-offset = #2
    \override RehearsalMark.self-alignment-X = #0
  }
  \context {
    \Voice
    \consists "Melody_engraver"
    \override Stem #'neutral-direction = #'()
  }
}

global = {
  \key g \major
  \time 4/4
  \partial 2
}

chordNames = \chordmode {
  \germanChords
  \override ChordName #'font-size = #-1
  \override ChordName #'font-series = #'bold
  % Akkorde folgen hier.
  s2 g1 d c g
  e:min7 b:min7 e:min7 a
  f c es bes
  d:min f g c2 d
  g1 c d2:sus4 d g:sus4 g
  e1:min7 a d2:sus4 d g1
}

melody = \relative c' {
  \global
  % Die Noten folgen hier.
  b4 \mark "Strophen" c
  d d e d8 \tieSolid d ~
  d a'4.\breathe g4 fis
  g d d c8 b8 ~
  b4 r4 d d8 e ~
  e4 d e fis8 fis
  (fis) d4.\breathe e4 fis
  g fis e  d8 e
  (e4) r a a8 a
  (a4) a g f8 g
  (g) c4. \breathe g4 g8 g
  (g4) g f es8 d ~
  \tieDotted d ~ d r4 d e
  f f g a8 a8
  (a) f4. \breathe f4 f
  a a g8 f4 \tieSolid g8 ~
  \slurDotted g2( a2)
  \break

  \repeat volta 2 {
    b \mark "Refrain" d
    d4. \tieSolid c8 ~ c4 b
    a2 d2
    c4. b8 ~ b2 \breathe
    g b
    b4. a8 ~ a4 g
    a2 b2
    a4. g8 ~ g2
  }
}

verse = \lyricmode {
  \override LyricText #'font-name = #"Aller"
  % Liedtext folgt hier.
  \set stanza = #"1. "
  Aus den Dör -- fern und aus Städ -- ten, von ganz nah und auch von fern, __
  mal ge -- spannt, __ mal e -- her skep -- tisch, man -- che zö -- gernd, vie -- le gern, __
  folg -- ten sie __ den Spu -- ren Je -- su, folg -- ten sie __ dem, der sie rief __
  und sie wur -- den selbst zu Bo -- ten, __ dass der Ruf wie Feu -- er lief: __
  \set stanza = #"1.-4. "
  Ein -- ge -- la -- den zum Fest des Glau -- bens, ein -- ge -- la -- den zum Fest des Glau -- bens.

}

\score {
  <<
    \new ChordNames \chordNames
    \new Staff { \melody }
    \addlyrics { \verse }
  >>
  \layout { }
  \midi {
    \tempo 4=120
  }
}



Sollten euch Fehler oder Unsinnigkeiten beim restlichen Code auffallen, bin ich dankbar für Hinweise. Die Dokumentation für Lilypond ist zwar sehr gut und umfangreich, aber der Einstieg ist für Selbstlerner echt schwer und Tutorials sind rar.

Vielen Dank!

harm6

Hallo Chris,

willkommen im Forum.

Ich hol' mal etwas weiter aus.

Eine RehearsalMark ist ein music-event. Es hat keine Dauer, genauso wie \break und \breathe und andere, siehe:
\void \displayMusic \mark "foo"
=>
(make-music
  'MarkEvent
  'label
  "foo")

Es wird gedruckt vor dem nachfolgenden, genauso wie \breathe und \break (wobei \break natürlich im engeren Sinne nicht "gedruckt" wird).
Also führt Deine Eingabe
b4 \mark "Strophen" c
bzw
b \mark "Refrain" d
dazu, daß die RehearsalMark nach dem "b" eingefügt wird.
RehearsalMark.self-alignment-X ist per default 0 und so erscheinen sie zentriert "irgendwo" über einem Punkt links von der Folgenote.
Dieses "irgendwo" wird bestimmt durch 'break-align-symbols, also im LilyPond-Sinne "breakable" Objekten, setzbar sind:

ambitus
breathing-sign
clef
cue-clef
cue-end-clef
custos
key-cancellation
key-signature
left-edge
staff-bar
time-signature

In Abwesenheit aller wird die BreakAlignGroup oder PaperColumn genommen, aber da bin ich mir nicht sicher.

Zusammengefasst bedeutet das, daß Du eine RehearsalMark nur an den erwähnten Objecten ausrichten kannst, auf keinen Fall jedoch an einer Note oder einer NoteColumn.


Du könntest jetzt die RehearsalMark korrekt einsetzen, d.h.:
\mark "Strophen"  b4 c
bzw
\mark "Refrain" b d
Und dann self-alignment-X auf LEFT setzen
Mir würde das reichen.
Oder mittels X-offset dahin verschieben wo Du sie haben willst, ist aber anfällig gegen layout-Veränderungen.

Ein anderer Weg wäre auf RehearsalMark zu verzichten und stattdessen TextScript zu verwenden.
TextScript ist das mittel der Wahl um einfachen Text über/unter einer Note erscheinen zu lassen.
Allerdings willst du den Text ja über den Akkorden haben, insofern muß man einige Klimmzüge unternehmen, da ChordNames per default kein TextScript zuläßt und die Zeichen "^" und "-" in ChordNames syntaktisch bereits belegt sind:
"Text_engraver" in den Context packen
TextScript, mittels "_" eingeben und die Ausrichtung tweaken. Im Code unten habe ich dazu <> verwendet, einen empty chord ohneDauer, der der nächsten NoteColumn zugeschlagen wird.


\version "2.18.2"

#(set! paper-alist (cons '("a5 angepasst" . (cons (* 123 mm) (* 160 mm))) paper-alist))
#(set-global-staff-size 16)


\paper {
  #(set-paper-size "a5 angepasst")
  indent = #0
  left-margin = #0
  right-margin = #0
  top-margin = #0
  bottom-margin = #0
  myStaffSize = #10
  #(define fonts
     (make-pango-font-tree
      "Aller"
      "Aller"
      "Aller"
      (/ myStaffSize 12)
      ))
}

\layout {
  \context {
    \Score
    \remove "Bar_number_engraver"
    \override RehearsalMark.font-size = #-1
    \override RehearsalMark.font-series = #'bold
    \override RehearsalMark.Y-offset = #2
    \override RehearsalMark.self-alignment-X = #0
  }
  \context {
    \Voice
    \consists "Melody_engraver"
    \override Stem #'neutral-direction = #'()
  }
}

global = {
  \key g \major
  \time 4/4
  \partial 2
}

chordNames = \chordmode {
  \germanChords
  \override ChordName #'font-size = #-1
  \override ChordName #'font-series = #'bold
  % Akkorde folgen hier.
  <>_\tweak direction #UP _\markup \bold "Strophen"
  s2 g1 d c g
  e:min7 b:min7 e:min7 a
  f c es bes
  d:min f g c2 d
  <>_\tweak direction #UP _\markup \bold "Refrain"
  g1 c d2:sus4 d g:sus4 g
  e1:min7 a d2:sus4 d g1
}

melody = \relative c' {
  \global
  % Die Noten folgen hier.
  b4 c
  d d e d8 \tieSolid d ~
  d a'4.\breathe g4 fis
  g d d c8 b8 ~
  b4 r4 d d8 e ~
  e4 d e fis8 fis
  (fis) d4.\breathe e4 fis
  g fis e  d8 e
  (e4) r a a8 a
  (a4) a g f8 g
  (g) c4. \breathe g4 g8 g
  (g4) g f es8 d ~
  \tieDotted d ~ d r4 d e
  f f g a8 a8
  (a) f4. \breathe f4 f
  a a g8 f4 \tieSolid g8 ~
  \slurDotted g2( a2)
  \break

  \repeat volta 2 {
    b d
    d4. \tieSolid c8 ~ c4 b
    a2 d2
    c4. b8 ~ b2 \breathe
    g b
    b4. a8 ~ a4 g
    a2 b2
    a4. g8 ~ g2
  }
}

verse = \lyricmode {
  \override LyricText #'font-name = #"Aller"
  % Liedtext folgt hier.
  \set stanza = #"1. "
  Aus den Dör -- fern und aus Städ -- ten, von ganz nah und auch von fern, __
  mal ge -- spannt, __ mal e -- her skep -- tisch, man -- che zö -- gernd, vie -- le gern, __
  folg -- ten sie __ den Spu -- ren Je -- su, folg -- ten sie __ dem, der sie rief __
  und sie wur -- den selbst zu Bo -- ten, __ dass der Ruf wie Feu -- er lief: __
  \set stanza = #"1.-4. "
  Ein -- ge -- la -- den zum Fest des Glau -- bens, ein -- ge -- la -- den zum Fest des Glau -- bens.

}

\score {
  <<
    \new ChordNames \with { \consists "Text_engraver" }
    \chordNames
    \new Staff { \melody }
    \addlyrics { \verse }
  >>
  \layout {
  }
%  \midi {
%    \tempo 4=120
%  }
}


ZitatSollten euch Fehler oder Unsinnigkeiten beim restlichen Code auffallen, bin ich dankbar für Hinweise.
Das einzige was mir auffiel war in z.B.:
\override LyricText #'font-name = #"Aller"
Das ist veraltete Syntax, immer noch gültig und wohl auch in der nächsten stable aber irgendwann wird wohl nur noch die neuere gelten:
\override LyricText.font-name = #"Aller"

Zitat
Die Dokumentation für Lilypond ist zwar sehr gut und umfangreich, aber der Einstieg ist für Selbstlerner echt schwer und Tutorials sind rar.
Aber es lohnt sich ;)
Außerdem gibts ja dieses Forum ...

Gruß,
  Harm

Malte

Hallo Chris,

willkommen im Forum! Bitte gib immer ein möglichst kleines Codebeispiel an, welches nur die Dinge enthält, die für deine Frage (möglicherweise) relevant sind. Das könnte z. B. so aussehen:\version "2.18.2"

\layout {
  \context {
    \Score
    \override RehearsalMark.Y-offset = #2
    \override RehearsalMark.self-alignment-X = #0
  }
}

global = {
  \key g \major
  \time 4/4
  \partial 2
}

chordNames = \chordmode {
  s2 g1 d
  g1 c
}

melody = \relative c' {
  \global
  b4 \mark "Strophen" c
  d d e d8 d ~
  d a'4.\breathe g4 fis
  \break

  \repeat volta 2 {
    b \mark "Refrain" d
    d4. c8 ~ c4 b
    a2
  }
}

\score {
  <<
    \new ChordNames \chordNames
    \new Staff { \melody }
  >>
}

Das ist noch nicht so klein, wie es sein könnte, aber wenn du so kurz erst dabei bist, dachte ich mir, wäre es für dich vielleicht hilfreich, die originale Struktur noch erkennen zu können. Ein Minimalbeispiel im engeren Sinne ist das noch nicht, man könnte noch weiter verkleinern, aber so ists schon mal viel übersichtlicher. Solche kleinen Beispiele helfen anderen, aber auch dir, ein Problem schnell einzukreisen ;)

Das Problem ist hier aus zwei Teilen zusammengesetzt:

  • Du hast schon mit den beiden \overrides an LilyPonds Standardverhalten für das Positionieren der RehearsalMarks gedreht. Wenn man weiß, was man da tut, kann das helfen, hier wäre es aber nicht nötig und ein Entfernen der beiden Zeilen zeigt, daß die nicht Hauptgrund für das Problem waren. Die erste (Y-offset) ist nur für vertikales Verschieben verantwortlich, nicht für horizontales. Die zweite für die Ausrichtung, sie hat aber keine Auswirkung, da sie den Standardwert 0 bzw. #CENTER setzt.
  • Der Hauptgrund für die merkwürdige Positionierung ist nämlich, daß Befehle wie \key, \time, \mark, \tempo, \bar etc. an der Stelle in der Musik stehen müssen, an der sie passieren sollen, also vor den entsprechenden Noten. Du hast die beiden \mark-Befehle stattdessen nach der ersten Note gesetzt, sie beziehen sich also zeitmäßig auf die zweite Note.

    Das fällt nicht sofort auf, weil RehearsalMarks standardmäßig zentriert und nicht linksbündig gesetzt werden.
Die Lösung heißt also:
\mark "Refrain" b d
statt
b \mark "Refrain" d
und für linksbündige Texte
\override RehearsalMark.self-alignment-X = #LEFT

RehearsalMarks sind normalerweise Probenziffern und die sind i. d. R. an Taktstrichen (im Fall der Strophe mangels Taktstrich an der rechten Kante der Tonartvorzeichen) ausgerichtet, nicht an Noten. Solltest du wirklich linksbündig mit den Noten abschließen wollen, bräuchtest du wohl statt \mark eher \tempo. Der \override ist dann hinfällig.

Malte

Zitat von: Chris am Montag, 22. Juli 2019, 12:47
Sollten euch Fehler oder Unsinnigkeiten beim restlichen Code auffallen, bin ich dankbar für Hinweise. Die Dokumentation für Lilypond ist zwar sehr gut und umfangreich, aber der Einstieg ist für Selbstlerner echt schwer und Tutorials sind rar.
Mir sind noch ein paar Dinge aufgefallen, ich dachte mir aber, ich pack das jetzt noch in einen eigenen Beitrag. Einiges ist wahrscheinlich Geschmackssache, anderes wie z. B. mein Kommentar zu Klammern/Bögen könnte dir in Zukunft einiges an Kopfzerbrechen sparen.


Zitat

#(set-global-staff-size 16)

\paper {
  #(set-paper-size "a5 angepasst")
  indent = #0
  left-margin = #0
  right-margin = #0
  top-margin = #0
  bottom-margin = #0
  myStaffSize = #10
  #(define fonts
     (make-pango-font-tree
      "Aller"
      "Aller"
      "Aller"
      (/ myStaffSize 12)
      ))
}

• Die ganzen # vor den Zahlen brauchst du in neueren Versionen nicht mehr, auch in 2.18.2 schon nicht.
• LilyPonds Standard-Systemgröße ist 20. Du hast sie hier auf 16 gesetzt, die Fonts aber um den Faktor 10/12 statt 16/20 skaliert, die Noten sind also um den Faktor 25/24 oder gut 4% zu groß. Ich würde empfehlen, für die Skalierung statt (/ myStaffSize 12) lieber (/ staff-height 20 pt) zu schreiben. staff-height wird gesetzt von set-global-staffsize, bei dir also z. B. 16pt.
• Du scheinst ja randlose PDFs haben zu wollen, vermutlich für ein einfaches Einfügen in ein anderes Programm? Falls du den Hinweis ,,Music engraving ..." dafür noch entfernen möchtest, geht das mit\header {
  tagline = ##f
}



Zitat
global = {
  \key g \major
  \time 4/4
  \partial 2
}
• So eine globale Variable für Tonarten etc. ist vor allem sinnvoll, wenn du die gleiche Information in mehreren Instrumenten haben willst. In deinem Liederbuch bräuchtest du das nicht, da könntest du diese Sachen direkt in melody mit reinschreiben.


Zitat
  e:min7 b:min7 e:min7 a
  f c es bes
• Einfacher zu tippen fände ich e:m7 sowie
• deutsche Tonnamen (b statt bes, h statt b). Die kannst du verwenden, indem du oben in deiner Datei (z. B. unterm \version-Befehl) \language "deutsch" schreibst.


Zitat
  d d e d8 \tieSolid d ~
• Wenn du nur einzelne Bögen gepunktet haben möchtest, wäre statt eines ständigen Wechsels von \tieDotted und \tieSolid stattdessen an den fraglichen Stellen \once \tieDotted möglich. Das wirkt sich nur auf den unmittelbar folgenden Bogen aus. Ähnlich für \slurDotted .


Zitat
  e4 d e fis8 fis
  (fis) d4.\breathe e4 fis
• Für einen Haltebogen (Tie) solltest du ~ verwenden, nicht ( ). Die Klammern sind für Legato-Bögen (Slur) gedacht.
• Davon abgesehen sieht es so aus, als würdest du die zweite Note des Bogens (hier das dritte fis) einklammern. Die öffnende Klammer gehört jedoch eigentlich zur Note davor, also zum zweiten fis. Das würde ich auch unbedingt so schreiben. Für einen Bogen von g nach a also g( a) und nicht g (a).


Zitat
  \override LyricText #'font-name = #"Aller"
• Nachdem du oben Aller als Text gesetzt hast, dürfte ein expliziter override hier eigentlich nicht mehr nötig sein.
• siehe auch Harms Kommentar zum Thema Syntax (LyricText.font-name)


Zitat
  \set stanza = #"1.-4. "
• Kleinigkeit: Das schließende Leerzeichen sollte nicht nötig sein, für ,,bis" lieber einen Halbgeviertstrich. Also\set stanza = "1.–4."
• Auch hier ist wieder # nicht nötig.

Chris

Wow, vielen Dank an Harm und Malte für die vielen tollen Hinweise!

Zurzeit versuche ich, mir die Logik von Lilypond über die vielen verschiedenen Schnipsel, die ich im Internet zu meinen Anliegen finde, zu erschließen. Erste Anlaufstelle ist natürlich immer die Dokumentation, aber dort sind die Beispiele manchmal zu kompliziert und manchmal zu stark reduziert für mich. Zudem erscheinen mir die Erklärungen zur Programmlogik recht unsystematisch, was es mir schwer macht, da durchzublicken.

Dass das mit dem Text über den Akkorden so schwierig ist, hätte ich nicht gedacht. Ich habe jetzt Maltes Vorschlag mit \tempo übernommen, da mir der am solidesten erscheint. Trotzdem dürfte das eher ein Workaround sein, denke ich. \tempo hat jetzt dazu geführt, dass der "Refrain" an der richtigen Stelle steht, "Strophen" sich aber merkwürdigerweise am Brevis (habe \time in 2/2 geändert) orientiert. Die beiden Texte sind nun unterschiedlich ausgerichtet. Falls ihr dazu eine schnelle Idee habt, gerne her damit. Ansonsten suche ich selbst nachher nochmal weiter.

Die anderen Hinweise werde ich mir zu Herzen nehmen.
So wenig in Kürze, weil ich los mus. Ich danke euch vielmals!

Malte

#5
Zitat von: Chris am Montag, 22. Juli 2019, 15:28
Zurzeit versuche ich, mir die Logik von Lilypond über die vielen verschiedenen Schnipsel, die ich im Internet zu meinen Anliegen finde, zu erschließen. Erste Anlaufstelle ist natürlich immer die Dokumentation, aber dort sind die Beispiele manchmal zu kompliziert und manchmal zu stark reduziert für mich. Zudem erscheinen mir die Erklärungen zur Programmlogik recht unsystematisch, was es mir schwer macht, da durchzublicken.
Ich glaube, eine Mischung aus Dokumentation, Schnipseln (auch in Foren und Mailinglisten; kennst du übrigens das LilyPond Snippet Repository?) und eigenen Fragen in Foren/Mailinglisten ist eine gute Herangehensweise. Allerdings muß man bei älterem Code immer drauf schauen, ob der für die aktuelle Version so noch funktioniert und ob es nicht inzwischen auch einfachere Lösungen gibt, was ab und zu auch vorkommt. Manche Sachen wurden so oft gefragt, daß LilyPond sie inzwischen selbst kann; zwar muß man ggf. eine sog. ,,Entwickler-Version" (englisch ,,unstable") installieren, allerdings sind die (insbesondere aktuell 2.19.83) gar nicht so instabil, wie der Name vermuten läßt.
Zitat
Dass das mit dem Text über den Akkorden so schwierig ist, hätte ich nicht gedacht. Ich habe jetzt Maltes Vorschlag mit \tempo übernommen, da mir der am solidesten erscheint. Trotzdem dürfte das eher ein Workaround sein, denke ich. \tempo hat jetzt dazu geführt, dass der "Refrain" an der richtigen Stelle steht, "Strophen" sich aber merkwürdigerweise am Brevis (habe \time in 2/2 geändert) orientiert. Die beiden Texte sind nun unterschiedlich ausgerichtet. Falls ihr dazu eine schnelle Idee habt, gerne her damit. Ansonsten suche ich selbst nachher nochmal weiter.
Hier hilft merkwürdigerweise  \override Score.MetronomeMark.break-align-symbols = #'(first-note)bzw. im entsprechenden \context-\Score-Block\override MetronomeMark.break-align-symbols = #'(first-note)Ich frage mich, warum sich da MetronomeMark und RehearsalMark so unterscheiden ... RehearsalMark wäre natürlich semantisch tendenziell ,,richtiger" und insofern ist das schon ein Workaround. Aber er ist noch nicht besonders häßlich ;) Es sei denn, du brauchst dann doch mal eine tatsächliche Tempoangabe, dann wirds haarig ...

Edit: Komisch, first-note scheint da nicht ausschlaggebend zu sein ... auch fast beliebige andere Werte führen dazu. Scheint wohl der Standardfall zu sein, wenn kein kompatibles Symbol gefunden wird ... Ich untersuche das mal und schreibe ggf. nen Bug-Report.