Transpose mit MusicTree

Begonnen von Köbi, Dienstag, 8. August 2017, 14:25

« vorheriges - nächstes »

Köbi

Unter http://lilypondblog.org/2014/07/trees-music-and-lilypond/ habe ich etwas praktisches gefunden (Spielt für das nachvollziehen des Problems nicht direkt eine Rolle.)

Leider funktioniert das in Kombination mit \transpose zu einem unerwarteten Problem: Wieso steht im 1. Ssystem auch ein d' und nicht ein c', wie ich es erwarten würde?


\version "2.19.64"

musicTree = #'()

% function to store music in `musicTree`
putMusic =
#(define-void-function (parser location path content)(string? ly:music?)
   (let ((pl (string->path path)))
     (set! musicTree (tree-set! musicTree pl content))
     ))

% function to get music from `musicTree`
getMusic =
#(define-music-function (parser location path)(string?)
   (let* ((pl (string->path path))
          (content (tree-get musicTree pl)))
     (if (ly:music? content) content (make-music 'SequentialMusic 'void #t))
     ))

% set a value in a tree -- based on nested association lists
#(define-public (tree-set! tree path val)
   (if (> (length path) 1)
       (let ((tab (assoc (car path) tree)))
         (if (not (pair? tab))(set! tab '((car path))))
         (assoc-set! tree (car path) (tree-set! (cdr tab) (cdr path) val))
         )
       (assoc-set! tree (car path) val))
   )

% get a value from a tree -- based on nested association lists
#(define-public (tree-get tree path)
   (let ((ret (assoc (car path) tree)))
     (if (pair? ret)
         (if (> (length path) 1)
             (tree-get (cdr ret) (cdr path))
             (cdr ret))
         #f))
   )

% split a string by '/'
#(define-public (string->path str)(string-split str #\/))

\putMusic "A" \relative { c' }


\new Staff {
  \getMusic "A"
}
\new Staff {
  \transpose c d \getMusic "A"
}


Ich komme einfach nicht drauf, sorry.

Malte

Zitat von: Köbi am Dienstag,  8. August 2017, 14:25
Leider funktioniert das in Kombination mit \transpose zu einem unerwarteten Problem: Wieso steht im 1. Ssystem auch ein d' und nicht ein c', wie ich es erwarten würde?
musicTree ist eine einzige Datenstruktur, die durch das \transpose anscheinend verändert wird. Aber merkwürdig, denn PDF-Ausgabe und Output von \displayLilyMusic widersprechen sich:\new Staff {
  \displayLilyMusic \getMusic "A"
}
\new Staff {
  \displayLilyMusic \transpose c d \getMusic "A"
}

Du kannst aber zwischen die beiden Partituren noch die ZeilemusicTree = #(ly:music-deep-copy musicTree)schalten. Dann wird musicTree kopiert und diese Kopie wieder dem Namen musicTree zugewiesen. Die erste Partitur arbeitet dann mit der alten, die zweite mit der neuen Kopie.

harm6

Unter gewissen Umständen kann transpose ihr Argument nicht nur destruktiv verändern, sondern sogar "zurückschlagen" bis in die originale Definition des Arguments und es auch dort verändern.
Gewisse Umstände sind idR nicht ganz astreine Codings. Hier ist es getMusic. Verwende:

getMusic =
#(define-music-function (parser location path)(string?)
   (let* ((pl (string->path path))
          (content (tree-get musicTree pl)))
     (if (ly:music? content)
         (ly:music-deep-copy content) ;; <-----------
         (make-music 'SequentialMusic 'void #t))))


Das von Malte vorgeschlagene:
musicTree = #(ly:music-deep-copy musicTree)
würde ich nicht verwenden.
Es funktioniert ja. Aber musicTree ist keine Musik, insoweit bin ich etwas erstaunt, daß es klappt. Das mag auch nur solange gelten wie ein paranoider Code-Hygeniker diesen Fall nicht ausschließt... ;)

Gruß,
  Harm

Köbi

#3
Ihr seid einfach super! Vielen Dank Harm, so funktioniert es :-)