Autor Thema: \quoteDuring und \articulate  (Gelesen 7882 mal)

fugenkomponist

  • Member
Re: \quoteDuring und \articulate
« Antwort #15 am: Donnerstag, 20. August 2015, 15:18 »
So, ich hab noch ein bisschen damit rumprobiert und es scheint jetzt ganz gut zu klappen. Ich hab das ganze jetzt so zusammengebaut, dass man \replaceQuote (und auch \articulate) nirgendwo mehr von Hand einsetzen muss, sondern nur eine einzige Datei per \include einbinden muss. Für artikulierte Zitate dann noch zwei weitere Includes (ich dachte mir erst, dass die Dateien sich vielleicht gegenseitig einbinden sollten, habe das aber wieder verworfen, damit man nicht nachher Dateien mehrmals einbindet).

Den Code habe ich in ein .zip gepackt, weil ich an diesen Beitrag nur vier Anhänge hängen darf. Es enthält folgende Dateien:

  • replaceQuotes.ily: ändert \addQuote so, dass das Zitieren transitiv wird (was auch eine Lösung für diesen Thread darstellt)
  • articulateQuotes.ily: ändert \addQuote so, dass das Zitieren mit \articulate funktioniert (und hat als Nebeneffekt auch die schon erwähnte Transitivität)
  • demo_noten.ily: enthält die Definitionen von Notenvariablen
  • demo_standard.ly, demo_partitur.ly, demo_articulated.ly: enthalten jeweils die gleiche Partitur, die aus den Noten in demo_noten.ily wird; einmal LilyPonds Standardverhalten, einmal mit transitiven Zitaten, einmal mit \articulate

Angehängt habe ich außerdem noch als Bilder die Ergebnisse der drei Varianten.

Vielen Dank nochmal an harm!
« Letzte Änderung: Donnerstag, 20. August 2015, 15:24 von fugenkomponist »

fugenkomponist

  • Member
Re: \quoteDuring und \articulate
« Antwort #16 am: Donnerstag, 20. August 2015, 20:59 »
Mir ist soeben eine ganz wesentliche Einschränkung von harms Lösung und damit auch meiner Abwandlung davon aufgefallen: Nicht jeder kann jeden zitieren, erstaunlich, dass uns das beiden noch nicht aufgefallen ist … Wenn die \addQuote-Befehle eine bestimmte Reihenfolge haben, in der A über B steht, dann kann B A zitieren, aber A B nicht (z. B. kann foo im verlinkten Beitrag nicht bla zitieren).

Allgemein gesprochen: Wir stellen uns einen gerichteten Graphen vor, in dem eine Kante A→B bedeutet, dass A B zitiert. An diesen gabs bisher so gut wie keine Anforderungen (Zyklen sind nur verboten, wenn die Zitate alle zum gleichen Zeitpunkt passieren; lustigerweise gerät LilyPond weder in eine Endlosschleife noch hauts ne Warnung raus falsch gedacht, LilyPonds quoteDuring ist ja nicht transitiv). Jetzt muss er aber ein DAG (gerichteter azyklischer Graph) sein; die nötige Anordnung der \addQuote-Befehle ergibt sich dann aus einer topologischen Sortierung dieses Graphen. Das ist schon eine ziemlich einschneidende Anforderung.

Meine Erklärung mithilfe von LilyPonds Fehlermeldung: Angenommen, \addQuote "A" \A steht über \addQuote "B" \B und A zitiert B per \quoteDuring "B" s1.
\addQuote "A" \A wertet A nun per replaceQuote aus, stößt auf den \quoteDuring-Befehl, schaut also nach einem zitierbaren "B" und findet es nicht.

Ich habe gerade nur eine Idee, was man da machen könnte: lazy evaluation. Ich hab mal gelesen, dass Scheme das kann, bin mir aber noch nicht klar darüber, in welchem Ausmaß das geht und ob das hier weiterhelfen könnte oder LilyPond mir nen Strich durch die Rechnung macht. Ich probier das mal.

Edit: Mal abgesehen davon, dass promise?, force und delay da sind, aber GUILE lazy nicht kennt (warum auch immer delay und force sind grundsätzlich Teil der Sprache, lazy kommt mit SRFI-45 dazu, wenn ich das hier und das hier richtig verstehe), hab ich irgendwie gerade gar keinen Plan …
« Letzte Änderung: Donnerstag, 20. August 2015, 23:05 von fugenkomponist »

fugenkomponist

  • Member
Re: \quoteDuring und \articulate
« Antwort #17 am: Freitag, 21. August 2015, 17:58 »
Ich weiß immer noch nicht, ob das mit der lazy evaluation irgendwie klappen könnte, meine Intuition sagt aber „nein, eine Zitier-Iteration reicht nicht aus“. (harm, kannst du da vielleicht etwas zu sagen? Ich hab das nichtmal anständig zum Kompilieren gebracht, ganz zu schweigen von irgendwelchen Ergebnissen in die richtige Richtung ;) )

Was aber irgendwie gehen sollte wäre folgendes: Erstmal haben wir die Musikvariablen m_1 bis m_n, die alle irgendwelche Zitate per \quoteDuring q_1 bis \quoteDuring q_n enthalten können (die q_i sind Strings, die ja irgendetwas sein können, nicht unbedingt die Namen der m_i). Dann kommen die n Zeilen \addQuote q_i m_i. Und dann füttern wir eine Funktion mit m_1 bis m_n und q_1 bis q_n; diese Funktion ersetzt nun erstmal in allen m_i die Vorkommen von \quoteDuring q_1 durch die entsprechenden Teile von m_1. Dann das gleiche mit q_2, …, q_n.

Das vergrößert natürlich den Rechenaufwand. Aber ich hab das Gefühl, dass ich da nicht drumherum komme. (Alles unter der Annahme, dass ich nicht einfach sage „ok, ich zitiere immer die erste Geige in der zweiten, nie andersrum“. Vielleicht mach ich das irgendwann – es ist nicht so wichtig, dass sich da jetzt noch jemand extra stundenlang reinhängen sollte.)

Edit: Hier mal eine Datei, die im Endeffekt dann in allen Stimmen 10 as, 10 hs, 10 c's, 10 d's haben soll. Ich bin alle möglichen Kombinationen, wer wen direkt, indirekt über eine Zwischenstation oder indirekt über zwei Zwischenstationen zitiert, durchgegangen.\version "2.19.25"

A = \relative {
  \time 10/4
  a a a a a a a a a a |
  \quoteDuring "B" { s s }
  \quoteDuring "C" { s }
  \quoteDuring "D" { s }
  \quoteDuring "B" { s s }
  \quoteDuring "C" { s }
  \quoteDuring "D" { s s }
  \quoteDuring "C" { s } |
  \quoteDuring "C" { s s }
  \quoteDuring "B" { s }
  \quoteDuring "D" { s }
  \quoteDuring "C" { s s }
  \quoteDuring "B" { s }
  \quoteDuring "D" { s s }
  \quoteDuring "B" { s } |
  \quoteDuring "D" { s s }
  \quoteDuring "B" { s }
  \quoteDuring "C" { s }
  \quoteDuring "D" { s s }
  \quoteDuring "B" { s }
  \quoteDuring "C" { s s }
  \quoteDuring "B" { s } |
}

B = \relative {
  \time 10/4
  \quoteDuring "A" { s s }
  \quoteDuring "C" { s }
  \quoteDuring "D" { s }
  \quoteDuring "A" { s s }
  \quoteDuring "C" { s }
  \quoteDuring "D" { s s }
  \quoteDuring "C" { s } |
  b b b b b b b b b b |
  \quoteDuring "C" { s }
  \quoteDuring "A" { s }
  \quoteDuring "C" { s }
  \quoteDuring "D" { s }
  \quoteDuring "A" { s }
  \quoteDuring "D" { s }
  \quoteDuring "C" { s s }
  \quoteDuring "A" { s }
  \quoteDuring "D" { s } |
  \quoteDuring "D" { s }
  \quoteDuring "A" { s }
  \quoteDuring "D" { s }
  \quoteDuring "C" { s }
  \quoteDuring "A" { s }
  \quoteDuring "C" { s }
  \quoteDuring "D" { s s }
  \quoteDuring "A" { s }
  \quoteDuring "C" { s } |
}

C = \relative {
  \time 10/4
  \quoteDuring "A" { s }
  \quoteDuring "B" { s }
  \quoteDuring "A" { s }
  \quoteDuring "D" { s }
  \quoteDuring "B" { s }
  \quoteDuring "D" { s }
  \quoteDuring "A" { s s }
  \quoteDuring "B" { s }
  \quoteDuring "D" { s } |
  \quoteDuring "B" { s }
  \quoteDuring "A" { s }
  \quoteDuring "B" { s }
  \quoteDuring "D" { s }
  \quoteDuring "A" { s }
  \quoteDuring "D" { s }
  \quoteDuring "B" { s s }
  \quoteDuring "A" { s }
  \quoteDuring "D" { s } |
  c' c c c c c c c c c |
  \quoteDuring "D" { s }
  \quoteDuring "A" { s }
  \quoteDuring "B" { s }
  \quoteDuring "D" { s }
  \quoteDuring "B" { s }
  \quoteDuring "A" { s s }
  \quoteDuring "B" { s }
  \quoteDuring "D" { s s } |
}

D = \relative {
  \time 10/4
  \quoteDuring "A" { s }
  \quoteDuring "B" { s }
  \quoteDuring "C" { s }
  \quoteDuring "A" { s }
  \quoteDuring "C" { s }
  \quoteDuring "B" { s s }
  \quoteDuring "C" { s }
  \quoteDuring "A" { s s } |
  \quoteDuring "B" { s }
  \quoteDuring "A" { s }
  \quoteDuring "C" { s }
  \quoteDuring "B" { s }
  \quoteDuring "C" { s }
  \quoteDuring "A" { s s }
  \quoteDuring "C" { s }
  \quoteDuring "B" { s s } |
  \quoteDuring "C" { s }
  \quoteDuring "A" { s }
  \quoteDuring "B" { s }
  \quoteDuring "C" { s }
  \quoteDuring "B" { s }
  \quoteDuring "A" { s s }
  \quoteDuring "B" { s }
  \quoteDuring "C" { s s } |
  d' d d d d d d d d d |
}

\addQuote "A" \A
\addQuote "B" \B
\addQuote "C" \C
\addQuote "D" \D

<<
  \A
  \B
  \C
  \D
>>

2. Edit: Irgendwie läuft auch das noch nicht so, ich bleib aber dran. Mir ist aber inzwischen eine weitere Idee gekommen: Nicht nacheinander die Stimmen anschauen (und dann jede (n−1)-mal), sondern alle gleichzeitig durchlaufen. Dafür muss man natürlich erst einmal eine sortierte Liste der Zeitpunkte aller Events in allen Stimmen anlegen (die enthält dann z. B. Tripel (Zeitpunkt Stimme Event)). Einfach wird das sicher auch nicht, aber es dürfte den Rechenaufwand wieder runterbringen, zumindest bei wenigen Zitaten. (Jaja, ich hab Informatik studiert und müsste auch eine anständige Laufzeitanalyse machen können, aber so wichtig ist das im Moment nicht, es geht nur um ein ungefähres Gefühl und da bin ich mir ja relativ sicher; deshalb spar ich mir die erstmal, nachliefern kann ich sie dann noch mit ner fertigen Lösung …)
« Letzte Änderung: Samstag, 22. August 2015, 09:41 von fugenkomponist »

harm6

  • Member
Re: \quoteDuring und \articulate
« Antwort #18 am: Sonntag, 23. August 2015, 01:31 »
Ich habe noch nie mit `delay', etc gearbeitet. Kann Dir da also nicht groß helfen.

Aber hier was ich weiß:
`delay' wird ein paar mal in .scm-files verwendet, meist in Verbindung mit 'delay-stencil-evaluation'.
Außerdem gibt es:
https://github.com/openlilylib/openlilylib/blob/master/input-shorthands/late-evaluation-of-variables.ly

Mehr weiß ich dazu nicht.

Leider habe ich momentan auch sehr wenig Zeit. Wird wohl etwas dauern bis ich mich nochmal tiefer in das Problem versenken kann.


Gruß,
  Harm

fugenkomponist

  • Member
Re: \quoteDuring und \articulate
« Antwort #19 am: Sonntag, 23. August 2015, 02:03 »
Ich habe noch nie mit `delay', etc gearbeitet. Kann Dir da also nicht groß helfen.
Kein Problem. Du kannst ja auch nicht alles wissen ;) Vielen dank schonmal für die beiden folgenden Hinweise:
Zitat
Aber hier was ich weiß:
`delay' wird ein paar mal in .scm-files verwendet, meist in Verbindung mit 'delay-stencil-evaluation'.
Außerdem gibt es:
https://github.com/openlilylib/openlilylib/blob/master/input-shorthands/late-evaluation-of-variables.ly
(Genaueres zum ersten Hinweis sagt mir git grep.)
Zitat
Wird wohl etwas dauern bis ich mich nochmal tiefer in das Problem versenken kann.
Kein Problem, du hast mir in diesem Thread schon so sehr geholfen :) Außerdem hab ich ja jetzt erstmal drei verschiedene Ansätze, an denen ich selber ganz gut arbeiten kann (der letzte basiert glaub ich auf etwas ähnlichem wie deine ursprüngliche Lösung). Wenn ich dann mit denen irgendwann nicht mehr weiterkomm, kann ich mich ja immer noch mal hier oder auf der Mailingliste melden, und vielleicht hat ja auch jemand anders ne Idee ;)

fugenkomponist

  • Member
Re: \quoteDuring und \articulate
« Antwort #20 am: Samstag, 5. September 2015, 16:56 »
So, ich habe jetzt viel dran getan und im Endeffekt alles neu geschrieben. Dabei hab ich einiges über Scheme und LilyPond gelernt und ohne harms vorherige Komplettlösung als Vorlage zum Anschauen und Lernen wär das nicht möglich gewesen :)

Es kann jetzt in beliebige Richtungen zitiert werden und mit \articulate klappts auch. Es sind noch ein paar Kleinigkeiten optimierbar und ich weiß nicht, obs vielleicht doch an irgendeiner Stelle kaputtgehen kann (insbesondere hab ich noch keine Akkorde/Mehrstimmigkeit und merkwürdige Konstellationen von music-wrapper-music wie \tuplet, \grace und \relative getestet). Aber im Großen und Ganzen stimmts.

Hier (und im Anhang als transitiveReplaceDemo.ly) eine kleine Kostprobe:
\version "2.19.25"
\include "transitiveReplace.ily"
\include "articulate.ly"

violin = \relative {
  c'1~ c
  \quoteDuring "clarinet" s1 \quoteDuring "flute" s
  \quoteDuring "clarinet" s1 \quoteDuring "flute" s
}

flute = \relative {
  \quoteDuring "violin" s1 \quoteDuring "clarinet" s
  d'1~ d
  \quoteDuring "violin" s1 \quoteDuring "clarinet" s
}

klarinette = \relative {
  \quoteDuring "flute" s1 \quoteDuring "violin" s
  \quoteDuring "flute" s1 \quoteDuring "violin" s
  e'1~ e
}

\addQuote "violin"   \violin
\addQuote "flute"    \flute
% Bisher einziger bekannter Stolperstein:
% Unten muss jetzt \clarinet statt \klarinette verwendet werden.
\addQuote "clarinet" \klarinette

\replaceQuotes

\articulate
<<
  \new Staff \violin
  \new Staff \flute
  \new Staff \clarinet
>>
« Letzte Änderung: Samstag, 5. September 2015, 16:59 von fugenkomponist »