Allgemein > Fragen zu Funktionen

Wiederholungsklammer manuell setzen

<< < (4/5) > >>

xr:
Meine Lösung, die nun wirklich funktioniert, wird jetzt nicht mehr berechnet, sondern ist fest vorgegeben. Geht wohl schneller, als mir noch weiter über Lösungsmöglichkeiten den Kopf zu zerbrechen.


--- Code: ---\version "2.18.2"


Klammer =
#(define-music-function
    (parser location num)
    (number?)
   
    (define listeA '((volta "1")) )
    (define listeB '( (volta #f) (volta "2")) )
    (define listeC '( (volta #f) (volta "3")) )
    (define listeD '( (volta #f) (volta "4")) )
    (define listeE '( (volta #f) (volta "5")) )
    (define listeF '( (volta #f) (volta "6")) )
    (define listeG '( (volta #f) (volta "7")) )
    (define listeH '( (volta #f) (volta "8")) )
    (define listeI '( (volta #f) (volta "9")) )
   
    ( cond
      (( = num 1)
            #{ \set Score.repeatCommands = #listeA #})
      (( = num 2)
            #{ \set Score.repeatCommands = #listeB #})
      (( = num 3)
            #{ \set Score.repeatCommands = #listeC #})
      (( = num 4)
            #{ \set Score.repeatCommands = #listeD #})
      (( = num 5)
            #{ \set Score.repeatCommands = #listeE #})
      (( = num 6)
            #{ \set Score.repeatCommands = #listeF #})
      (( = num 7)
            #{ \set Score.repeatCommands = #listeG #})
      (( = num 8)
            #{ \set Score.repeatCommands = #listeH #})
      (( = num 9)
            #{ \set Score.repeatCommands = #listeI #})   
    )
)

Klammer-aus =
#(define-music-function
    (parser location)
    ()   
    #{
     \set Score.repeatCommands = #'((volta #f))
    #})


\score { 
    <<
      \relative {   
       
        \time 4/4 
       
        f'4 g f f 
       
        \Klammer 1
        e4 f e e
        g4 e e e
        f4 g f  f 
        \Klammer-aus
        \bar ":|."
       
        \Klammer 2
        e4 f e e
        g4 e e e
        \Klammer-aus
        \bar ":|."
        \Klammer 7
        e4 f e e
        g4 e e e
        \Klammer-aus
        c4 d c c     
      }
 
    >>
}

--- Ende Code ---

harm6:

--- Zitat ---Dummerweise überschreibt immer die letzte Zahl alle Zahlen der vorangegangenen Klammern. Das fällt natürlich erst bei mehreren Klammern auf.
Weiß irgendwer warum das so ist?

--- Ende Zitat ---

\set Score.repeatCommands setzt das context-property 'repeatCommands'.
Mehrere davon zur selben Zeit überschreiben sich gegenseitig, ist völlig normal und auch bei jedem override so.
Für overrides gibts mittlerweile eine Funktion, die den default (falls vorhanden) ausliest und dann mit dem gewünschten Wert erweitert. Für context-properties gibts das meines Wissens nach nicht.

In Deinem Fall mußt Du die bisherigen Setzungen von repeatCommands zum gegebenen Zeitpunkt auslesen, Deine Werte hinzufügen und neu zuweisen.

Such mal hier im Forum nach setRepeatCommand

Ob mein damaliger 2.16.-code heute noch funktioniert habe ich allerdings nicht getestet.


Gruß,
  Harm


xr:
Danke für deinen Hinweis.
Darum kümmere ich mich allerdings erst wieder, wenn nochmal ein ähnliches Problem auftaucht.

Xaver

Arnold:
Hallo,

und jetzt gebe ich nochmal meinen Senf dazu - Schwerpunkt meine forgestellten Funktionen:

* Mit meinem Beispiel kann man so Unsinniges erzeugen wie ein \repeat volta mit mehr Alternativen als Wiederholungen! Meine Routine sollte dann automatisch die Wiederholungszahl erhöhen.
* Daß leider noch kein Markup statt eines Textes als Voltenzahl übergeben werden kann, habe ich in einem vorherigen Post schon erwähnt. Wird ergänzt.
* Beim Setzen der Voltenzahl (per applyContext-Funktion) habe ich bisher nur den neuen Eintrag vorangestellt, also wurde der alte (automatische) Eintrag eigentlich gar nicht gelöscht. Und bei einer zwanzigstimmigen Partitur stände der Eintrag dann auch zwanzigmal in der Liste. - applyContext-Funktion wird erweitert.
* Diese applyContext-Funktion finde ich, wäre dann allgemein sehr nützlich anzuwenden: zwar \repeat volta mit \alternative notieren, aber zu Anfang der Alternativen einfach einen abweichenden Volta-Text angeben ohne auf Beginn und Ende der Voltaklammern achten zu müssen, also etwa so:
\repeat volta 3 {
 ...
} \alternative { {
 ...
} { \setVoltaText #(make-text-markup (make-bold-markup (make-fontsize-markup 2 "Fine")))
 ...
 \bar "|."
} { \setVoltaText #"2."
 ...
} }
* Dann ließen sich auf ähnliche Weise auch noch "unabhängig arbeitende" Funktionen \setVoltaStart und \setVoltaEnd definieren, welche ebenfall die anderen Einträge in der repeatCommands-Liste stehen lassen.Wenn ich das alles habe, werde ich es hier veröffentlichen. Voraussichtlich Anfang nächster Woche.

Arnold

Arnold:
So, jetzt meine aktualiserite Version:

--- Code: ---\version "2.18.2"
#(define (string-or-markup? x) (or (string? x) (markup? x)))

pmpStartRepeat = #(define-music-function (parser location) () (make-music 'MarkEvent
 'label "<parallel-music-results-postprocess:start repeat volta 2>"))
pmpStartRepeatEx = #(define-music-function (parser location count) (integer?) (make-music 'MarkEvent
 'label (string-append "<parallel-music-results-postprocess:start repeat volta " (number->string count) ">")
 'extra-int count))
pmpEndRepeat = #(define-music-function (parser location) () (make-music 'MarkEvent
 'label "<parallel-music-results-postprocess:end repeat>"))
pmpStartAlternative = #(define-music-function (parser location) () (make-music 'MarkEvent
 'label "<parallel-music-results-postprocess:start alternative>"))
pmpStartAlternativeEx = #(define-music-function (parser location s) (string-or-markup?) (make-music 'MarkEvent
 'label (string-append "<parallel-music-results-postprocess:start named alternative:" (if (markup? s) "(markup)" s) ">")
 'extra-text s))

#(define (pmpMark mus)
  (if (ly:music? mus)
   (let
    ((eventtype (ly:music-property mus 'name))
     (labeltext (ly:music-property mus 'label))
    )
    (if (and (eq? eventtype 'MarkEvent) (string? labeltext))
     (let*
      ((head "<parallel-music-results-postprocess:")
       (headlen (string-length head))
       (labellen (string-length labeltext)))
      (if (<= labellen headlen) 0
       (let*
        ((labelhead (string-copy labeltext 0 headlen))
         (labelpost (string-copy labeltext headlen))
         (postlen (string-length labelpost))
         (labelshortpost (string-copy labelpost 0 (min postlen 19)))
        )
        (if (string=? labelhead head)
         (if (string=? labelshortpost "start repeat volta ") 1
          (if (string=? labelpost "end repeat>") 2
           (if (string=? labelpost "start alternative>") 3
            (if (string=? labelshortpost "start named alterna") 4
             0))))
         0))))
     0))
   0))

#(define (pmpMarkRepeatCount mus)
  (if (ly:music? mus)
   (let
    ((eventtype (ly:music-property mus 'name))
     (labeltext (ly:music-property mus 'label)))
    (if (and (eq? eventtype 'MarkEvent) (string? labeltext))
     (let*
      ((head "<parallel-music-results-postprocess:")
       (headlen (+ (string-length head) 19))
       (labellen (string-length labeltext)))
      (if (<= labellen headlen) 2
       (let*
        ((labelhead (string-copy labeltext 0 headlen))
         (labelpost (string-copy labeltext headlen (- labellen 1)))
         (labelterm (string-copy labeltext (- labellen 1))))
        (if (string=? labelterm ">") (string->number labelpost)
         2))))
     2))
   2))

#(define (parallel-music-results-postprocess mus)
  (let ((eventtype (ly:music-property mus 'name)))
   (if (eq? eventtype 'SequentialMusic)
    (let
     ((es (ly:music-property mus 'elements))
      (new-es '())
      (active-dest 0)
      (rep-collect '())
      (alt-collect '())
      (alt-list-collect '())
      (rep-count 2)
     )
     (for-each (lambda (ese)
       (let ((etype (pmpMark ese)))
        (if (eq? etype 2) ;; end repeat ;;
         (begin
          (if (eq? active-dest 3)
           (set! alt-list-collect (append alt-list-collect (cons (make-music 'SequentialMusic 'elements alt-collect) '()))))
          (set! new-es (append new-es (cons
           (make-music 'VoltaRepeatedMusic 'repeat-count (max rep-count (length alt-list-collect))
            'element (make-music 'SequentialMusic 'elements rep-collect) 'elements alt-list-collect) '())))
          (set! active-dest 0)
          (set! rep-collect '())
          (set! alt-collect '())
          (set! alt-list-collect '())))
        (if (eq? etype 1) ;; start repeat ;;
         (begin
          (if (eq? active-dest 3)
           (set! alt-list-collect (append alt-list-collect (cons (make-music 'SequentialMusic 'elements alt-collect) '()))))
          (if (>= active-dest 1) ;; terminate existing repeat and start new repeat block
           (set! new-es (append new-es (cons
            (make-music 'VoltaRepeatedMusic 'repeat-count (max rep-count (length alt-list-collect))
             'element (make-music 'SequentialMusic 'elements rep-collect) 'elements alt-list-collect) '()))))
          (set! active-dest 1)
          (set! rep-collect '())
          (set! alt-collect '())
          (set! rep-count (ly:music-property ese 'extra-int 2))
          (set! alt-list-collect '())))
        (if (and (eq? etype 3) (>= active-dest 1)) ;; start alternative (only when repeat allready started) ;;
         (if (eq? active-dest 3) ;; next alternative ;;
          (begin
           (set! alt-list-collect (append alt-list-collect (cons (make-music 'SequentialMusic 'elements alt-collect) '())))
           (set! alt-collect '()))
          (set! active-dest 3)))
        (if (and (eq? etype 4) (>= active-dest 1)) ;; start named alternative (only when repeat allready started) ;;
         (begin
          (if (eq? active-dest 3) ;; next alternative ;;
           (set! alt-list-collect (append alt-list-collect (cons (make-music 'SequentialMusic 'elements alt-collect) '())))
          (set! active-dest 3))
         (set! alt-collect (cons
           (make-music 'ApplyContext
            'procedure (lambda (ctx)
                        (let ((score-ctx (ly:context-find ctx 'Score)))
                         (if (ly:context? score-ctx)
                          (let* ((old-rc (ly:context-property score-ctx 'repeatCommands '())) ; (boolean? (cadr v))
                                 (filtered-rc (filter (lambda (v)
                                    (or (not (pair? v)) (not (eq? (car v) 'volta)) (boolean? (cadr v)) )) old-rc)))
                           (ly:context-set-property! score-ctx 'repeatCommands
                            (cons (list 'volta (ly:music-property ese 'extra-text "?")) filtered-rc)))))))
           '()))))
        (if (eq? etype 0)
         (begin
          (if (eq? active-dest 0)
           (set! new-es (append new-es (cons ese '()))))
          (if (eq? active-dest 1)
           (set! rep-collect (append rep-collect (cons ese '()))))
          (if (eq? active-dest 3)
           (set! alt-collect (append alt-collect (cons ese '()))))))))
      es)
     (if (eq? active-dest 1) ;; start repeat is open ;;
      (set! new-es (append new-es (cons
       (make-music 'VoltaRepeatedMusic 'repeat-count (max rep-count (length alt-list-collect))
        'element (make-music 'SequentialMusic 'elements rep-collect) 'elements alt-list-collect) '()))))
     (if (eq? active-dest 3) ;; start alternative is open ;;
      (begin
       (set! alt-list-collect (append alt-list-collect (cons (make-music 'SequentialMusic 'elements alt-collect) '())))
       (set! new-es (append new-es (cons
        (make-music 'VoltaRepeatedMusic 'repeat-count (max rep-count (length alt-list-collect))
         'element (make-music 'SequentialMusic 'elements rep-collect) 'elements alt-list-collect) '())))))
     (ly:music-set-property! mus 'elements new-es)
     mus)
    mus)))

LinearToVoltaRepeats =
#(define-music-function (parser location m) (ly:music?)
  (parallel-music-results-postprocess m))

setVoltaText =
#(define-music-function (parser location on-ctx str) ((symbol? 'Score) string-or-markup?)
  (make-music 'ApplyContext
   'procedure (lambda (ctx)
     (let ((this-ctx (ly:context-find ctx on-ctx)))
      (if (ly:context? this-ctx)
       (let* ((old-rc (ly:context-property this-ctx 'repeatCommands '())) ; (boolean? (cadr v))
              (filtered-rc (filter (lambda (v)
                 (or (not (pair? v)) (not (eq? (car v) 'volta)) (boolean? (cadr v)) )) old-rc)))
        (ly:context-set-property! this-ctx 'repeatCommands
         (cons (list 'volta str) filtered-rc))))))))

setVoltaEndInContext =
#(define-music-function (parser location on-ctx) (symbol?)
  (for-each display (list "\n on-ctx = " on-ctx " "))
  (make-music 'ApplyContext
   'procedure (lambda (ctx)
     (let ((this-ctx (ly:context-find ctx on-ctx)))
      (if (ly:context? this-ctx)
       (let* ((old-rc (ly:context-property this-ctx 'repeatCommands '())) ; (boolean? (cadr v))
              (already-in-rc (filter (lambda (v)
                 (and (pair? v) (eq? (car v) 'volta) (boolean? (cadr v)) (not (cadr v)) )) old-rc)))
        (if (null? already-in-rc)
         (ly:context-set-property! this-ctx 'repeatCommands
          (cons (list 'volta #f) old-rc)))))))))

setVoltaEnd =
#(define-music-function (parser location) ()
  (make-music 'ApplyContext
   'procedure (lambda (ctx)
     (let ((this-ctx (ly:context-find ctx 'Score)))
      (if (ly:context? this-ctx)
       (let* ((old-rc (ly:context-property this-ctx 'repeatCommands '())) ; (boolean? (cadr v))
              (already-in-rc (filter (lambda (v)
                 (and (pair? v) (eq? (car v) 'volta) (boolean? (cadr v)) (not (cadr v)) )) old-rc)))
        (if (null? already-in-rc)
         (ly:context-set-property! this-ctx 'repeatCommands
          (cons (list 'volta #f) old-rc)))))))))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\LinearToVoltaRepeats {
  c'1
  \pmpStartRepeat
  d'
  \pmpStartAlternative
  e'
  \pmpStartAlternative
  f'
  \pmpStartRepeatEx #3  % impizit wird die zuletzt gestartete Wiederholung
  g'
  \pmpStartAlternative
  a'
  \pmpStartAlternativeEx #(make-text-markup (make-bold-markup (make-fontsize-markup 2 "Fine")))
  b'
  \bar "|."
  \pmpStartAlternativeEx #"2."
  c''
  \pmpStartRepeatEx #5
  d''
  \pmpStartAlternativeEx #"1., 3."
  e''
  \pmpStartAlternativeEx #"2., 4."
  f''
  \pmpStartAlternative
  g''
  \pmpEndRepeat
  a''
  \bar "|."
  \once \override Score.RehearsalMark.direction = #DOWN
  \once \override Score.RehearsalMark.self-alignment-X = #RIGHT
  \once \override Score.RehearsalMark.break-visibility = #begin-of-line-invisible
  \mark \markup \fontsize #-2 "D.C. al Fine"
}

\LinearToVoltaRepeats {
  g1
  \pmpStartRepeat
  a
  \pmpStartRepeat
  b
  \pmpEndRepeat
  c'
  \pmpStartRepeatEx #3
  d'
  \pmpStartAlternative
  e'
  \pmpStartAlternative
  f'
  \pmpStartRepeat
  g'
  \pmpStartAlternative
  a'
  \pmpStartAlternative
  b'
  \pmpStartRepeat
  c''
  \pmpStartAlternative
  d''
  \pmpStartAlternative
  e''
  \pmpStartAlternative
  f''
  \pmpEndRepeat
  \bar "|."
}

RM = {
  \repeat volta 2 {
    c'1 cis'
  } \alternative { {
    \setVoltaText #"7."
    d' dis'1
  } {
    \setVoltaText #"3."
    e'2 e' es'1
  } }
}

RMx = {
  \repeat volta 2 {
    c'1 cis'
  } \alternative { {
    \setVoltaText #'Staff #"777."
    d' dis'
  } {
    \setVoltaText #'Staff #"333."
    e' es'
  } }
}

RMxu = {
  \repeat volta 2 {
    c'1 cis'
  } \alternative { {
    \setVoltaText #'Staff #"777."
    d' \unset Staff.repeatCommands dis'
  } {
    \setVoltaText #'Staff #"333."
    << { e' } { s2 \unset Staff.repeatCommands } >> es'1
  } }
}

\score {
  <<
    \new Staff { \RM \bar "|." }
    \new Staff \with {
      \consists Volta_engraver
    } { \RM \bar "|." }
  >>
  \header {
    piece = \markup \justify {
      Mit \bold "\\setVoltaText" kann man den Starttext
      der Volte überschreiben, ohne die anderen \bold repeatCommands
      zu überschreiben. Implizit bedeutet das immer auch einen Start
      der Volta.
    }
  }
}

\defineBarLine "|-V" #'("|" "" "|")
\allowVoltaHook "|-V"
LM = {
  c'1 \bar ".|:"
  d'
  \setVoltaText "7."
  e'
  \bar ":|."
  \setVoltaEnd
  \setVoltaText "3."
  f'
  \setVoltaEnd
  g'
  \setVoltaText #(make-text-markup (make-bold-markup (make-fontsize-markup 2 "bis")))
  a' b'
  \setVoltaEnd \bar "|-V"
  c''
  \bar "|."
}

\score {
  <<
    \new Staff { \LM \bar "|." }
    \new Staff \with {
      \consists Volta_engraver
    } { \LM \bar "|." }
  >>
  \header {
    piece = \markup \column { \justify {
      Mit \bold "\\setVoltaEnd" kann man das Ende der Voltenklammer
      festlegen. Legt man außderdem die Wiederholungszeichen über \bold "\\bar"
      fest, so kann man damit alle (zu druckenden) Wiederholungen ohne Nutzung von
      \bold "\\repeat volta" beschreiben. Folglich werden diese auch nicht
      durch \bold "\\unfoldRepeats" aufgelöst.
    }
    \vspace #0.3
    \justify {
      Übrigens, \bold »bis« ist eine alte Bezeichnung, diesen (kurzen) Abschnitt
      zwei Mal zu spielen. Damit die benutzte »Voltenklammer« am Schluß an dem
      einfachen Taktstrich auch heruntergezogen wird, in den anderen Fällen aber
      nicht, wurde eine »neuer Taktstrich-Satz« mittels \bold "\\defineBarLine"
      definiert und an diesem per \bold "\\allowVoltaHook" der Schlußstrich der
      Voltenklammer aktiviert.
    }
  }}
}

\score {
  <<
    \new Staff { \RM \RM \RM \bar "|." }
    \new Staff \with {
      \consists Volta_engraver
    } { \RM \RMx \RM \bar "|." }
  >>
  \header {
    piece = \markup \justify {
      Im Prizip kann man auch in jeder Notenzeile
      (d. h. in jedem Staff-Kontext)
      einen anderen Text setzen, wäre da nicht noch
      das eine oder andere kleine, störende Problemchen.
    }
  }
}

\score {
  <<
    \new Staff { \RM \RM \RM \bar "|." }
    \new Staff \with {
      \consists Volta_engraver
    } { \RM \RMxu \RM \bar "|." }
  >>
  \header {
    piece = \markup \justify {
      Ein \bold "\\unset Staff.repeatCommands" kurz nach
      \bold "\\setVoltaText" hilft erst einmal. Aber dieses
      \italic { kurz danach } muß auch die Zeitschritte der anderen
      Stimmen mit einschließen, und die Score-weit gesetzte
      Bezeichnung geht auch noch verloren!
    }
  }
}

--- Ende Code ---
Dabei mußte ich feststellen, daß ich mit \setVoltaText zwar unterschiedliche Bezeichner in die Voltaklammern auf jeder Notenzeile (Staff) setzen kann, aber mit \consists Volta_engraver allein im Staff-Kontext dann doch noch eingies durcheinander kommt.

Arnold

Navigation

[0] Themen-Index

[#] Nächste Seite

[*] Vorherige Sete

Zur normalen Ansicht wechseln