Hallo,
ich hab beschlossen, mir mal ein bisschen scheme anzueignen. Das erste kleine Projekt ist eine coll’ottava-Funktion. Das klappt für den Anfang auch erstaunlich gut, ich bin aber auf mehrere Probleme gestoßen:
• Ich laufe rekursiv in die ganzen SequentialMusic, TimeScaledMusic etc. rein, bis ich auf EventChords oder NoteEvents stoße. Die meisten Eigenschaften (z. B. bei TimeScaledMusic nominator und denominator und bei NoteEvents duration, pitch, tweaks) will ich übernehmen und nur element/elements und articulations ändern. Nun weiß ich aber
* erstens nicht, welche das alle sind (und wo ich das rauskriegen könnte) und
* zweitens frage ich mich, ob das nicht auch einfacher geht, nach dem Motto „gib das ursprüngliche Objekt zurück, nur mit der articulations-Eigenschaft geändert“ statt „baue ein neues Objekt, das diese und jene Eigenschaften vom alten übernimmt und die und die articulations besitzt“. Scheme ist ja nicht rein funktional, deshalb könnte ich mir vorstellen, dass das irgendwie geht, oder?
• \relative bereitet mir Probleme: wenn ich \relative c' { \collottavaMusic { <c e> g' } } sage, baue ich mir im Moment daraus im Prinzip \relative c' { <c c' e e'> <g' g''> } statt dem eigentlich gewollten \relative c' { <c c' e, e'> <g' g'> }. Irgendwie hab ich keine Ahnung, wo ich da ansetzen könnte.
Hat jemand Ahnung von Scheme/LilyPond-Interna und könnte mir ein, zwei Hinweise dazu geben?
Viele Grüße,
Malte
Ach ja, zum Notenbeispiel noch: das ist nur für mich gewesen, um zu sehen, dass ich weder Artikulationen dupliziere noch verliere (aber Ties, die wohl den Artikulationen zugerechnet werden, sollen ja doch verdoppelt werden) etc. Aber man sieht am zweiten Beispiel (ganz unten im Code) ganz gut, dass es mit \relative noch nicht so tut wie mit absoluten Tonhöhen (erstes Beispiel, eigentlich sollten die beiden identisch sein).
\version "2.16.0"
#(define (octave-up note)
(make-music
'NoteEvent
'articulations (ly:music-property note 'articulations)
'tweaks (ly:music-property note 'tweaks)
'duration (ly:music-property note 'duration)
'pitch (ly:pitch-transpose
(ly:music-property note 'pitch)
(ly:make-pitch 1 0 0))))
#(define (without-articulations note)
(make-music
'NoteEvent
'articulations (filter
(lambda (e)
(eq?
(ly:music-property e 'name)
'TieEvent))
(ly:music-property note 'articulations))
'tweaks (ly:music-property note 'tweaks)
'duration (ly:music-property note 'duration)
'pitch (ly:music-property note 'pitch)))
#(define (eventchord-from-noteevent note)
(make-music
'EventChord
'articulations (ly:music-property note 'articulations)
'elements (list
(without-articulations note)
(octave-up (without-articulations note)))))
#(define (eventchord-from-eventchord chord)
(make-music
'EventChord
'elements
(fold-right
append
'()
(map
(lambda (note)
(if
(eq? (ly:music-property note 'name) 'NoteEvent)
(list
(without-articulations note)
(octave-up (without-articulations note)))
(list note)))
(ly:music-property chord 'elements)))))
#(define (collottava music)
(cond
((eq? (ly:music-property music 'name) 'NoteEvent)
(eventchord-from-noteevent music))
((eq? (ly:music-property music 'name) 'EventChord)
(eventchord-from-eventchord music))
((not (eq? (ly:music-property music 'elements) '()))
(make-music
(ly:music-property music 'name)
'elements (map collottava (ly:music-property music 'elements))))
((not (eq? (ly:music-property music 'element) '()))
(make-music
(ly:music-property music 'name)
'numerator (ly:music-property music 'numerator)
'denominator (ly:music-property music 'denominator)
'element (collottava (ly:music-property music 'element))))
(else music)))
collottavaMusic =
#(define-music-function
(parser location music)
(ly:music?)
(collottava music))
\displayMusic { c'
\collottavaMusic {
<d' f'>4\f <d'~ f'>-.
<\tweak #'font-size #-3 d' f'> d'2\glissando es'8-.( fis'\f
\times 2/3 { a8 b c' }
} g'4)
}
\displayMusic {
\relative c' {
c
\collottavaMusic {
<d f>4\f <d~ f>-.
<\tweak #'font-size #-3 d f> d2\glissando es8-.( fis\f
\times 2/3 { a,8 b c }
}
g'4)
}
}