Deutsches Lilypond Forum (Archiv)

Allgemein => Fragen zu Funktionen => Thema gestartet von: Manuela am Sonntag, 1. Februar 2015, 08:53

Titel: Akkorde als Variable definieren führt zu unerwünschter Notendauer
Beitrag von: Manuela am Sonntag, 1. Februar 2015, 08:53
Hi,
vor kurzem habe ich Lilypond entdeckt und bin begeistert, genau das, was ich mir vorgestellt hatte für Notensatz.
Ab und zu hakt es, so wie hier. Wenn ich einen Akkord als Variable zuweise, so macht Lilypond immer Viertelnoten daraus, egal welche Länge die vorhergehende Note hatte. Was mache ich falsch? Danke für eure Hilfe

Hier ein Beispiel:

\version "2.18.2"

FDur  = < f' a c >
\score
{

  \new Staff \relative c {
    \clef bass
    \key f \major
    f,8 \FDur f, \FDur
  }
}
Titel: Re: Akkorde als Variable definieren führt zu unerwünschter Notendauer
Beitrag von: trulli am Sonntag, 1. Februar 2015, 09:24
Hallo Manuela,

herzlich willkommen hier im Forum.

Deine Definition enthält keinen Notenwert, darum setzt Lily seinen 4-tel Standard.

\version "2.18.2"

FDur  = < f' a c > 8
\score
{

  \new Staff \relative c {
    \clef bass
    \key f \major
    f,8 \FDur f, \FDur
  }
}

Grüße von Trulli
Titel: Re: Akkorde als Variable definieren führt zu unerwünschter Notendauer
Beitrag von: fugenkomponist am Sonntag, 1. Februar 2015, 10:27
Das wundert mich jetzt aber auch. Ich dachte schon, eine mögliche Erklärung zu haben: Nämlich, dass FDur nicht einfach durch „<f' a c>“, sondern durch sowas wie „\new Voice { <f' a c> }“ ersetzt wird. Aber das tuts nicht, höchstens „{ <f' a c> }“. Ich sehe jetzt auch nicht so ganz, warum das einen Unterschied macht, ob ich \FDur schreibe oder den Inhalt von FDur … Kann das jemand noch ausführlicher erklären?

Ansonsten, wenn du neu bei LilyPond bist, Manuela, kennst du vielleicht noch nicht die beiden folgenden Lösungen, wär das was für dich? Oder hast du häufiger wechselnde Akkorde?
\score
{
  \new Staff \relative c {
    \clef bass
    \key f \major
    f,8 <f' a c> f, q f q f q
    \repeat unfold 4 { f <f' a c> }
  }
}
Titel: Re: Akkorde als Variable definieren führt zu unerwünschter Notendauer
Beitrag von: Manuela am Sonntag, 1. Februar 2015, 11:35
Danke für eure Antworten.

@trulli: Den Notenwert für die Akkorddauer habe ich absichtlich weggelassen, damit ich die Variable an verschiedenen Stellen einfügen kann und es sollte automatisch der vorangegangene Notenwert verwendet werden. Funktioniert aber nicht wie gedacht.

@fugenkomponist: ich möchte Akkordeonbässe setzen, q und repeat unfold kenne ich und verwende ich auch, wenn es geht

Gibt es vielleicht irgendwo Codesnippets für Akkordeon? Ich habe bereits gesucht, aber nicht viel gefunden.
Titel: Re: Akkorde als Variable definieren führt zu unerwünschter Notendauer
Beitrag von: iugin am Sonntag, 1. Februar 2015, 13:21
Hallo Manuela

meinst du so etwas?
\version "2.18.2"

FDur = #(define-music-function (parser location)()
          #{
            <f a c>
          #}
          )

\relative c'{
 c2 \FDur
}

Ich hoffe, es hilft dir :)

Einen lieben Gruss

Eugenio
Titel: Re: Akkorde als Variable definieren führt zu unerwünschter Notendauer
Beitrag von: Manuela am Sonntag, 1. Februar 2015, 13:40
Danke für den Tipp, es funktioniert  :D.
Der Inhalt übersteigt zwar momentan noch mein Lily-KnowHow, aber irgendwann werde ich schon durchsteigen

viele Grüße
Manuela
Titel: Re: Akkorde als Variable definieren führt zu unerwünschter Notendauer
Beitrag von: fugenkomponist am Sonntag, 1. Februar 2015, 14:22
Gibt es vielleicht irgendwo Codesnippets für Akkordeon? Ich habe bereits gesucht, aber nicht viel gefunden.
Hast du schon im Akkordeon-Unterforum geschaut? Da gibts zwar „nur“ drei Threads, aber dieser Beitrag (https://liarchiv.joonet.de/index.php?topic=1158.msg6343#msg6343) sieht beim Überfliegen des Anhangs stradella-bass.pdf so aus, als könnte er dir was nützen ;) Da scheint unglaublich viel Funktionalität drin zu stecken, aber vielleicht ist so auf Seite 6–8 oder so was für dich dabei …
Titel: Re: Akkorde als Variable definieren führt zu unerwünschter Notendauer
Beitrag von: Manuela am Sonntag, 1. Februar 2015, 14:32

Hast du schon im Akkordeon-Unterforum geschaut? Da gibts zwar „nur“ drei Threads, aber dieser Beitrag (https://liarchiv.joonet.de/index.php?topic=1158.msg6343#msg6343) sieht beim Überfliegen des Anhangs stradella-bass.pdf so aus, als könnte er dir was nützen ;) Da scheint unglaublich viel Funktionalität drin zu stecken, aber vielleicht ist so auf Seite 6–8 oder so was für dich dabei …

Danke für den Hinweis. Ich war bei diesem Thread, habe jedoch beim Wort "Griffschrift für steirische ..." aufgehört zu lesen  :-[
Titel: Re: Akkorde als Variable definieren führt zu unerwünschter Notendauer
Beitrag von: harm6 am Sonntag, 1. Februar 2015, 17:14
Hallo Manuela,

auch von mir ein herzliches willkommen hier im Forum.

Wenn ich einen Akkord als Variable zuweise, so macht Lilypond immer Viertelnoten daraus, egal welche Länge die vorhergehende Note hatte. Was mache ich falsch?

Hier ein Beispiel:

\version "2.18.2"

FDur  = < f' a c >
\score
{

  \new Staff \relative c {
    \clef bass
    \key f \major
    f,8 \FDur f, \FDur
  }
}

Die Zuweisung:
FDur  = < f' a c >
führt zu einer statischen Variablen, da nicht nur die Tonhöhen, sondern auch die Dauern festgekloppt werden und nicht mehr einfach verändert werden können. LilyPond fällt auf den default zurück falls nirgendwo Dauern angegeben sind. Und das sind Viertel.

Siehe auch den output von
#(display-scheme-music FDur)

Zitat
(make-music
  'EventChord
  'elements
  (list (make-music
          'NoteEvent
          'duration
          (ly:make-duration 2)
          'pitch
          (ly:make-pitch 0 3))
        (make-music
          'NoteEvent
          'duration
          (ly:make-duration 2)
          'pitch
          (ly:make-pitch -1 5))
        (make-music
          'NoteEvent
          'duration
          (ly:make-duration 2)
          'pitch
          (ly:make-pitch -1 0))))

Eugenios coding umgeht das scheinbar
\version "2.18.2"

FDur = #(define-music-function (parser location)()
          #{
            <f a c>
          #}
          )

\relative c'{
 c2 \FDur
}

denn

FDur = #(define-music-function (parser location)()
          #{
            <f a c>
          #}
          )

\relative c'{
 c2 \FDur
}

#(display-scheme-music FDur)

returniert:

Zitat
#<Music function #<procedure #f (parser location)>>
D.h. die Funktion FDur wird erst evaluiert, wenn sie aufgerufen wird und übernimmt damit die aktuelle Tondauer von vorher oder den default.
Es gibt allerdings keine Möglichkeit eigene Tondauern zu setzen.

Ich schrieb oben schon, daß es keine einfache Möglichkeit gibt eine einmal festgesetzte Dauer zu verändern, aber mit ein bißchen Aufwand geht es schon.
Führt allerdings dazu, daß Du die Dauer immer angeben mußt und zwar als string, d.h. mit quotation-marks, z.B.: "8.", für eine punktierte Achtel.

Hier das coding:
\version "2.18.0"

#(use-modules (ice-9 regex))

%% c/p from define-markup-commands.scm
%% because it's not public
#(define (parse-simple-duration duration-string)
  "Parse the `duration-string', e.g. ''4..'' or ''breve.'',
and return a (log dots) list."
  (let ((match (regexp-exec (make-regexp "(breve|longa|maxima|[0-9]+)(\\.*)")
                            duration-string)))
    (if (and match (string=? duration-string (match:substring match 0)))
        (let ((len (match:substring match 1))
              (dots (match:substring match 2)))
          (list (cond ((string=? len "breve") -1)
                      ((string=? len "longa") -2)
                      ((string=? len "maxima") -3)
                      (else (log2 (string->number len))))
                (if dots (string-length dots) 0)))
        (ly:error (_ "not a valid duration string: ~a") duration-string))))


#(define (chord transpose-to chrd duration-string)
  (let* ((parsed-dur-string (parse-simple-duration duration-string))
         (duration
           (ly:make-duration (car parsed-dur-string) (cadr parsed-dur-string))))
    (music-map
      (lambda (m)
        (if (music-is-of-type? m 'note-event)
            (begin
              (ly:music-set-property! m 'duration duration)
              (ly:music-property #{ \transpose c $transpose-to $m #} 'element))
            m))
      chrd)))

chrd-func =
#(define-scheme-function (parser location transpose-to chrd)
  (ly:pitch? ly:music?)
    (define-music-function (parser location duration-string)
     (string?)
     (chord transpose-to chrd duration-string)))

Dur = < c e g >
%% Using \chordmode is possible as well, may result in the need to transpose
%% differently
moll = \chordmode { c:m }

c-dur = \chrd-func c \Dur
d-dur = \chrd-func d \Dur
e-dur = \chrd-func e \Dur
f-dur = \chrd-func f \Dur
g-dur = \chrd-func g \Dur

c-moll = \chrd-func c, \moll

\score {
  \new Staff \relative c {
    \clef bass
    \key f \major
    \c-dur "4."
    \d-dur "8"
    \e-dur "16.."
   
    \c-moll "32"
  }
}


Letztendlich scheint es nur die Möglichkeiten zu geben die Dauern immer zu übernehmen oder immer selbst anzugeben. Zumindest habe ich keine anderen Weg gefunden.


Gruß,
  Harm
Titel: Re: Akkorde als Variable definieren führt zu unerwünschter Notendauer
Beitrag von: Manuela am Sonntag, 1. Februar 2015, 18:52
Wow, da kann ich nur staunen, wie gut ihr euch auskennt  :) Harm, Hut ab

Eugenio, nochmals herzlichen Dank für deine Hilfe, funktioniert perfekt, zumindest für meine Zwecke.

Alles was ich will, ist ein paar Liedchen aus meinem alten Schulliederbuch für Pianoakkordeon mit Bässen zu setzen. Es hat mich einigen Schweiß gekostet, bis ich eine Vorlage gebastelt hatte, die meinen Vorstellungen entspricht. Leider fand ich nirgends etwas Passendes, dieses Instrument scheint unter den Lilypondisten nicht sehr verbreitet zu sein.

Falls es irgendjemand interssiert, könnte ich meine Vorlage ins Forum stellen, es gibt sicher jede Menge Verbesserungsmöglichkeiten
Titel: Re: Akkorde als Variable definieren führt zu unerwünschter Notendauer
Beitrag von: harm6 am Sonntag, 1. Februar 2015, 20:55
[...]
Alles was ich will, ist ein paar Liedchen aus meinem alten Schulliederbuch für Pianoakkordeon mit Bässen zu setzen. Es hat mich einigen Schweiß gekostet, bis ich eine Vorlage gebastelt hatte, die meinen Vorstellungen entspricht. Leider fand ich nirgends etwas Passendes, dieses Instrument scheint unter den Lilypondisten nicht sehr verbreitet zu sein.
David Kastrup (https://liarchiv.joonet.de/index.php?topic=1222.0), LilyPond-core-developer, spielt selbst Akkordeon.
Im Laufe der Zeit hat er auch einiges dazu gepostet bzw Funktionalität geschaffen.
Schau mal in die Archive.

Zitat
Falls es irgendjemand interssiert, könnte ich meine Vorlage ins Forum stellen, es gibt sicher jede Menge Verbesserungsmöglichkeiten
Immer.

Gruß,
  Harm
Titel: Eselsbrücke
Beitrag von: ingmar am Sonntag, 1. Februar 2015, 21:03
Es gibt oft noch eine andere Lösung, nicht so elegant, aber auch möglich, die in manchen derartigen Fällen helfen kann.

Und zwar dann, wenn es um die einmalige Eingabe eines Notentexts geht, bei der einfach Zeit gespart werden soll.

Du schreibst einfach statt <f a c> "FDUR" oder "@F" oder auch "XX" oder "APFELKUCHEN" - was immer dir sinnvoll erscheint. Der String darf nur sonst nicht vorkommen, also z.B. kein lilypod-Code sein.

Abschließend, wenn alle Noten eingegeben sind, nutzt du ganz harmlos Suchen und Ersetzen, um deinen Platzhalterstring durch <f a c> zu ersetzen und kompilierst erst anschließend.

Der Vorteil ist, dass du dazu nicht in die Untiefen von scheme hinabsteigen musst, du musst keine besondere Syntax beachten. Und oft ist es besser, im resultierenden Code dann echtes übersichtliches lilypond stehen zu haben als etwas Kryptisches, was man nach einem Jahr selbst nicht mehr versteht...

Gruß,
- ingmar