Autor Thema: Lilypond & Scheme  (Gelesen 3690 mal)

Manuela

  • Member
Lilypond & Scheme
« am: Mittwoch, 2. März 2016, 09:03 »
Hi,

ist schon eine Weile her, dass ich das letzte Mal hier war.  :-[
Ich bin jetzt wild entschlossen, Scheme zu lernen. Anscheinend stehen mir dabei meine Programmierkenntnisse im Weg  :(

Ich taste mich langsam vor, aber...

Ich scheitere schon an den einfachsten Sachen. Z.B. (aus dem LSR http://lsr.di.unimi.it/LSR/Snippet?id=654):

#(define (name-of music)
 (ly:music-property music 'name))

Lt. Internals Reference macht ly:music-property folgendes:

ly:music-property mus sym val
    Return the value for property sym of music expression mus. If no value is found, return val or '() if val is not specified.

Mir geht also in der obigen Definition der 3. Wert ab, denn was für einen Sinn ergibt eine Definition, die immer einen Leerwert ergibt?

Auch let bringt mich zur Verzweiflung

(let ((e (ly:music-property music 'element)))
Was genau passiert da?

and (ly:music? e)
bedeutet die Abfrage, ob e einem gültigen Lilypond-Musikausdruck entspricht, habe ich wenigstens das verstanden?

Danke für euere Unterstützung

harm6

  • Member
Re: Lilypond & Scheme
« Antwort #1 am: Mittwoch, 2. März 2016, 11:50 »
Hallo Manuela,

ich bin in Eile. Insoweit nur kurz: benutze die diversen display-proceduren um Dir Sachen anzeigen zu lassen.

Z.B.

mus = { c''1 }

#(define (name-of music)
 (ly:music-property music 'name))
 
#(write-me "\nname-of music:\n" (name-of mus))

#(define (foo m)
  (let ((e (ly:music-property m 'element))
         (elts (ly:music-property m 'elements)))
    (display "\nmusic:\n")(display-scheme-music m)
    (display "\nelement:\n")(display-scheme-music e)
    (display "\nelements:\n")(display-scheme-music elts)))
   
#(foo mus)

führt zu:

Zitat
name-of music:
SequentialMusic

music:
(make-music
  'SequentialMusic
  'elements
  (list (make-music
          'NoteEvent
          'duration
          (ly:make-duration 0)
          'pitch
          (ly:make-pitch 1 0))))


element:
'()


elements:
(list (make-music
        'NoteEvent
        'duration
        (ly:make-duration 0)
        'pitch
        (ly:make-pitch 1 0)))


Vielleicht hilft das ja schon weiter.
Das LSR-snippet ist aber keins von den simplen ...


Gruß,
  Harm



Manuela

  • Member
Re: Lilypond & Scheme
« Antwort #2 am: Mittwoch, 2. März 2016, 14:13 »
Danke Harm. Ich werde mir das heute abend mal zu Gemüte führen.

Was ich vorerst will, ist eine Funktion, die die Differenz zweier Tonhöhen berechnet, etwa

#(define-????-function (parser location p q) (ly:pitch? ly:pitch?)
(let mydiff (- (ly:pitch-steps p) (ly:pitch-steps q)))
...
)

aber das klappt irgendwie nicht

harm6

  • Member
Re: Lilypond & Scheme
« Antwort #3 am: Mittwoch, 2. März 2016, 21:29 »
Als kleiner Anschub:

\version "2.18.2"

#(define (pitch-diff p1 p2)
  (- (ly:pitch-steps p1) (ly:pitch-steps p2)))
 
#(display-scheme-music
  (let ((pitches (event-chord-pitches #{ c' e' #})))
    (pitch-diff (cadr pitches) (car pitches))))

Bitte gib immer die von Dir genutzte LilyPond-version an. ;)

Gruß,
  Harm

Manuela

  • Member
Re: Lilypond & Scheme
« Antwort #4 am: Mittwoch, 2. März 2016, 21:59 »
Danke Harm.

Sorry wegen der vergessenen Version. Verwendet noch jemand eine niedrigere Version als 2.18?

harm6

  • Member
Re: Lilypond & Scheme
« Antwort #5 am: Mittwoch, 2. März 2016, 22:25 »
Zitat
Verwendet noch jemand eine niedrigere Version als 2.18?

Kommt gelegentlich vor. Es ist nicht lange her da kam jemand mit 2.6. daher, iirc (auf der internationalen mailing-list).

Wichtiger sind aber zwei andere Dinge.
(1)
Momentan ist 2.18.2 zwar die aktuelle stable, aber eigentlich völlig outdated verglichen mit den neueren devel-Versionen. 2.19.x hat aber so viele Änderungen, daß 2.18.-code dort manchmal nicht funktioniert, bzw einen anderen output liefert (und umgekehrt).
(2)
Falls jemand nach Jahren diesen thread nachliest, sollte er/sie direkt sehen können auf welche lily-Version bezug genommen wurde.


Falls wir Dir beim lernen von scheme, genauer: diesem Kuddelmuddel aus guile und LilyPond-syntax, helfen können, dann machen wir das natürlich sehr gerne.
Ich empfehle allerdings konkretere Fragen als:
Zitat
Was genau passiert da?
;)

Deine Frage nach ly:music-property ist konkreter. Insoweit:
ly:music-property gibt den "Wert" des spezifizierten properties (gegeben als symbol, z.B. 'name) der gegebenen music expression zurück.
Falls nix zu finden ist eine leere Liste, doch falls das optionale val zusätzlich angegeben wurde, dann wird dieses dann retourniert.
Allerdings kann ich mich nicht erinnern jemals ein default-value für ly:music-property gebraucht zu haben, wohl aber bei grob-properties.
Wenn noch unklar, frag ;)

(ly:music? e) testet, ob e die Bedingungen erfüllt um #t bei der Abfrage durch ly:music? zu ergeben.
Aber was alles #t ist mag Überraschungen bergen:
#(write-me "(ly:music? #{ -3 #}) " (ly:music? #{ -3 #}))
-3 ist in LilyPond ein 'FingeringEvent !


Gruß,
  Harm

Manuela

  • Member
Re: Lilypond & Scheme
« Antwort #6 am: Mittwoch, 2. März 2016, 22:39 »
Danke für deine Geduld.

Ich bin inzwischen der Verzweiflung nahe.

Das funktioniert:



\version "2.18.2"
#(let ((x 2) (y 1) (z 4)) (display (+ x y)) (display (- z 4)) ( display (+ (* x y) (/ z x))))

Jetzt hätte ich gerne (nur zu Test- und Lernzwecken)

#(display (ly:pitch-alteration cis))
und habe jede Menge Varianten ausprobiert, etwa

#(display (#ly:pitch-alteration cis))
...
#(display (#ly:pitch-alteration #'cis))

mit verschiedenen Klammern, nichts davon funktioniert. Wenn ich das nicht rasch lerne, gebe ich auf :(

harm6

  • Member
Re: Lilypond & Scheme
« Antwort #7 am: Mittwoch, 2. März 2016, 23:19 »
(1)
Mit
#(display (ly:pitch-alteration cis))
bist Du ja in einem lily-file.

(2)
Das #-Zeichen wechselt nach scheme.
Aber in scheme ist cis nicht definiert.

(3)
Du mußt auf den pitch cis (LilyPond) in scheme zugreifen.
Da gibt es verschieden Möglichkeiten.
Die simpelste:
#(display (ly:pitch-alteration #{ cis #}))
Mit den Klammern #{ #} kannst Du einen LilyPond-Musik-Ausdruck in scheme "setzen".
(Komplizierter wird es natürlich wenn Du den/die pitches erst auslesen mußt:
#(display (ly:pitch-alteration #{ cis1 #}))
funktioniert schon nicht da cis1 in LilyPond kein pitch sondern eine ausgewachsene Note, ein Notevent, ist.)

HTH,
  Harm

Ganz generell ist das manipulieren von Musik komplizierter als das manipulieren von grobs ...

Manuela

  • Member
Re: Lilypond & Scheme
« Antwort #8 am: Donnerstag, 3. März 2016, 05:59 »
Danke Harm.

Ich bin dann schlafen gegangen, war total frustriert. Wahrscheinlich ginge es schneller, wenn ich im Forum erklären würde, was ich beabsichtige, und dann schreibst du den Code dazu  ;)

Ich will es aber endlich selber können, normalerweise bin ich nicht doof.  >:(

Jetzt nochmals zum Mitschreiben:

#(.... ) schaltet auf den Guile-Interpreter um. Wenn ich dazwischen etwas von Lilipond ausgewertet haben möchte, schreibe ich #{ ... #}

Wenn ich innerhalb von #{ ... #} auf eine Variable zugreiben möchte, die ich in Lilypond mit meinevariable = { } definiert habe (was ja auch einem Scheme-Ausdruck #(define ... ) entspricht), dann schreibe ich was? $meinevariable oder \meinevariable? (bin jetzt nicht daheim, sonst würde ich es gleich ausprobieren - und wahrscheinlich wieder verzweifeln, weil nichts davon funktioniert).
« Letzte Änderung: Donnerstag, 3. März 2016, 06:13 von Manuela »

fugenkomponist

  • Member
Re: Lilypond & Scheme
« Antwort #9 am: Donnerstag, 3. März 2016, 07:11 »
#(.... ) schaltet auf den Guile-Interpreter um. Wenn ich dazwischen etwas von Lilipond ausgewertet haben möchte, schreibe ich #{ ... #}
Richtig.
Zitat
Wenn ich innerhalb von #{ ... #} auf eine Variable zugreiben möchte, die ich in Lilypond mit meinevariable = { } definiert habe (was ja auch einem Scheme-Ausdruck #(define ... ) entspricht), dann schreibe ich was? $meinevariable oder \meinevariable? (bin jetzt nicht daheim, sonst würde ich es gleich ausprobieren - und wahrscheinlich wieder verzweifeln, weil nichts davon funktioniert).
In diesem Fall musst du $meinevariable oder #meinevariable schreiben. Die beiden machen noch einen Unterschied: $meinevariable verwendet jedes Mal eine frische Kopie, während #meinevariable das nicht tut, sondern einfach die vorhandene Variable ändert. Deshalb heißt es im Beispiel mit \mitRaute zweimal as: Es ist die selbe Note, die geändert und dann zweimal verwendet wurde; \mitDollar nimmt stattdessen eine frische Kopie für den zweiten Aufruf $note, weshalb es dann wieder c heißt.
\version "2.19.36"
\language "deutsch"

changePitchToAs =
#(define-music-function (n) (ly:music?)
   (ly:music-set-property! n 'pitch #{ as #})
   n)

mitDollar =
#(define-music-function (note) (ly:music?)
   #{
     \changePitchToAs $note
     $note
   #})

mitRaute =
#(define-music-function (note) (ly:music?)
   #{
     \changePitchToAs #note
     #note
   #})

\mitDollar c'1

\mitRaute c'1

Manuela

  • Member
Re: Lilypond & Scheme
« Antwort #10 am: Donnerstag, 3. März 2016, 07:43 »

In diesem Fall musst du $meinevariable oder #meinevariable schreiben. Die beiden machen noch einen Unterschied: $meinevariable verwendet jedes Mal eine frische Kopie, während #meinevariable das nicht tut, sondern einfach die vorhandene Variable ändert.

Danke komponist, ich glaube, das hilft mir wirklich weiter.  :)

Wohin ist (parser location ...) verschwunden? Hängt das mit der Lilypond-Version zusammen?

fugenkomponist

  • Member
Re: Lilypond & Scheme
« Antwort #11 am: Donnerstag, 3. März 2016, 14:29 »
Wohin ist (parser location ...) verschwunden? Hängt das mit der Lilypond-Version zusammen?
Ja, seit 2.19.?? braucht man die nicht mehr, siehe Changes

Manuela

  • Member
Re: Lilypond & Scheme
« Antwort #12 am: Donnerstag, 3. März 2016, 16:36 »

Ja, seit 2.19.?? braucht man die nicht mehr, siehe Changes

Wie stabil ist denn die neue Version, ist der Umstieg schon zu empfehlen?

fugenkomponist

  • Member
Re: Lilypond & Scheme
« Antwort #13 am: Donnerstag, 3. März 2016, 18:07 »
„Instabil“ ist sie eigentlich nur in dem Sinne, dass alle paar Wochen mal eine neue Version kommt (inzwischen sind wir bei 2.19.37, aber erst 2.18.2) und dass immer mal wieder neue Funktionen hinzukommen (aber man muss ja nicht jede einzelne Version auch gleich installieren, nur, wenn sich mal wieder was getan hat, was man gut gebrauchen kann ;) ). Große bugs oder crashes (die in der 2.18.2 noch nicht da waren) gibts eigentlich nicht.

Für mich gabs genug Gründe, 2.19 zu verwenden, weshalb ich 2.18 eigentlich nur noch anschmeiße, wenn ich Fragen von anderen Nutzern beantworte ;) Dazu gehören z. B. Dauern ohne Tonhöhe (für RhythmicStaffs oder zum Wiederholen von Tönen/Akkorden mit weniger Schreibaufwand) und die einfache Verwendung von weiteren Notenschriftarten, aber auch einige weitere.
« Letzte Änderung: Donnerstag, 3. März 2016, 18:08 von fugenkomponist »