define-music-function s2. * $zahl - welcher Variablentyp?

Begonnen von Manuela, Sonntag, 13. August 2017, 09:04

« vorheriges - nächstes »

Manuela

Hi,

wenn ich folgende Funktion definiere
\version "2.19.62"

xPausen =
#(define-music-function (zahl)(number?)
   (
     #{
       s2. * $zahl
       s4 d s s d
     #}
     )
   )

\relative c' { \xPausen #3 }


bekomme ich diese Fehlermeldung

Starte lilypond-windows.exe 2.19.62 [Ohne Titel]...
Processing `document.ly'
Parsing...
document.ly:7:14: error: syntax error, unexpected NUMBER_IDENTIFIER, expecting UNSIGNED or FRACTION
       s2. *  $zahl
document.ly:13:16: error: error in #{ ... #}
\relative c' { \xPausen #3 }
document.ly:5:4: In expression ((#<procedure embedded-lilypond #> "\x0d
       s2. * $zahl\x0d
       s4 d s s d\x0d
     " "document.ly" ...)):
document.ly:5:4: Wrong type to apply: #<unspecified>
Wurde mit dem Return-Code 1 beendet.


Mit welchem Typ muss ich die Funktion definieren? Ich habe schon verschiedene Varianten probiert (integer, positive...), nichts klappt.
Danke für eure Hilfe
viele Grüße
-- Manuela

Malte

#1
Das Ding ist: Bei Ausdrücken wie s2.*3 ist das für LilyPond nicht ,,Dauer * Zahl", sondern der ganze Ausdruck 2.*3 ist eine ly:duration?. Die drei Teile 2., * und 3 sind also erstmal nicht separat voneinander einzugeben. Du hast jetzt folgende Möglichkeiten:
• Die ganze Dauer der Funktion übergeben. Ich habe hier mit \skip gearbeitet, aus irgendeinem Grund braucht das aber, wenns ganz am Anfang steht, anscheinend ein Musikereignis davor, deshalb der leere EventChord <> in der Funktion.
\scaleDurations verwenden und nur den Faktor übergeben.
    ∘ Falls der Faktor immer eine ganze Zahl ist, reicht number?.
    ∘ Ansonsten kann man einen Bruch übergeben. Dabei muß man allerdings beachten, daß ein Bruch wie 3/4 in LilyPond-Syntax eigentlich ein Paar in Scheme ist, also pair? übergeben wird.*\version "2.19.64"

xPausenDur =
#(define-music-function (dur) (ly:duration?)
   #{
     <> \skip #dur
     s4 d s s d
   #})

\relative c' { \xPausenDur 2.*3 r4 r r r }
\relative c' { \xPausenDur 2.*4 r4 r r r }

xPausenNum =
#(define-music-function (num) (number?)
   #{
     \scaleDurations #(cons num 1) s2.
     s4 d s s d
   #})

\relative c' { \xPausenNum 3 r4 r r r }
\relative c' { \xPausenNum 4 r4 r r r }

xPausenRat =
#(define-music-function (rat) (pair?)
   #{
     \scaleDurations #rat s2.
     s4 d s s d
   #})

\relative c' { \xPausenRat 3/1 r4 r r r }
\relative c' { \xPausenRat 4/1 r4 r r r }
\relative c' { \xPausenRat 7/3 r4 r r r }

Die Viertelpausen hab ich nur eingefügt, um nachzuprüfen, ob die Längen der unsichtbaren Pausen auch wirklich stimmen.

* Edit: Deswegen auch #(cons num 1) in der zweiten Lösung: die Zahl 3 wird nicht zum Bruch 3/1, sondern zum Paar 3/1 gemacht ;)

Manuela

Danke Malte, Version 2 ist genau das, was ich gesucht habe.

Die anderen Lösungsmöglichkeiten sind natürlich auch interessant  :)

3/1 wird also von Lilypond in ein pair umgewandelt, das wusste ich nicht. Wieder was gelernt.
Danke für eure Hilfe
viele Grüße
-- Manuela

Malte

#3
Zitat von: Manuela am Sonntag, 13. August 2017, 12:36
3/1 wird also von Lilypond in ein pair umgewandelt [...]
Genauer gesagt ist 3/1 ein pair?, auch wenn die Schreibweise einen Bruch suggeriert. Statt #'(5 . 3) kann man also 5/3 schreiben:\version "2.19.64"

\relative {
  \override Staff.Clef.extra-offset = 5/3
  s1
}
Allerdings können damit nur Paare von natürlichen Zahlen dargestellt werden, 0.1/5.8 für #'(0.1 . 5.8) geht also nicht.

Übrigens muß man gut aufpassen: 3/1 ist ein Paar, #3/1 ein Bruch.\version "2.19.64"

istPaar =
#(define-void-function (something) (scheme?)
   (display (pair? something))
   (newline))

istBruch =
#(define-void-function (something) (scheme?)
   (display (rational? something))
   (newline))

\istPaar 3/1 \istPaar #3/1  \istPaar #'(3 . 1) \istPaar #(cons 3 1)
#(newline)
\istBruch 3/1 \istBruch #3/1  \istBruch #'(3 . 1) \istBruch #(cons 3 1)