Autor Thema: Takte pro Zeile zählen  (Gelesen 1689 mal)

infranator

  • Member
Takte pro Zeile zählen
« am: Donnerstag, 19. Februar 2015, 13:07 »
Hallo Leute,

ich würde gerne über den letzten Takt einer Zeile schreiben, wieviele Takte in der Zeile sind.
So wie im folgendem Beispiel:

\version "2.19.9"

{
  s1*8
  \startMeasureCount
  \override Staff.MeasureCounter.count-from = #9
  s1
  \break
  \stopMeasureCount
  s1*6
  \startMeasureCount
  \override Staff.MeasureCounter.count-from = #7
  s1
 
  \break
  \stopMeasureCount
  s1*4
  \startMeasureCount
  \override Staff.MeasureCounter.count-from = #5
  s1
  \stopMeasureCount
}

\layout {
  \context {
  \Staff
  \consists #Measure_counter_engraver
  }
}

Die Methode ist allerdings sehr umständlich und funktioniert nur mit expliziten Umbrüchen.
Leider kenne ich mich gar nicht mit Engravern aus, aber wäre es möglich einen zu schreiben, der das Zählen der Takte pro Zeile übernimmt, egal ob die Umbrüche explizit definiert sind, oder nicht?

Oder gibt es ein Tutorial wie man in Lilypond eigene engraver schreibt? Bisher kenne ich nur den Vortrag http://chemnitzer.linux-tage.de/2012/vortraege/900 von David Kastrup, bei dem man leider kein Wort mehr versteht, wenn es interessant wird.

Infranator

harm6

  • Member
Re: Takte pro Zeile zählen
« Antwort #1 am: Samstag, 21. Februar 2015, 15:52 »
Hallo,

engraver zu benutzen wird nicht funktionieren, da sie ins Geschehen eingreifen bevor die Zeilenumbrüche berechnet werden.

Stattdessen habe ich einen override für 'LeftEdge geschrieben welcher einen Text rechts zum 'StaffSymbol anfügt.
Zwei Nachteile:
- man muß aufpassen, daß das ganze nicht über den rechten Rand hinausragt.
- es ist kollisionsanfällig

\version "2.19.15"

% #(use-modules (ice-9 pretty-print))

#(define grob-name
;Return the name of @var{grob}
  (lambda (x)
    (if (ly:grob? x)
        (assq-ref (ly:grob-property x 'meta) 'name)
        (ly:error "~a is not a grob" x))))

#(define (look-up-for-parent name-symbol axis grob)
"
 Return the parent of @var{grob}, specified by it's @var{name-symbol} in
 axis @var{axis}.
 If not found, look up for the next parent.
"
 (let* ((parent (ly:grob-parent grob axis)))
 (cond
   ((not (ly:grob? parent))
    (ly:error
       (_"Perhaps typing error for \"~a\" or \"~a\" is not in the parent-tree.")
       name-symbol name-symbol))
   ((not (equal? name-symbol (grob-name parent)))
    (look-up-for-parent name-symbol axis parent))
   (else parent))))
   
#(define (format-mrkp-to-add arg)
  #{
    \markup {
      \box
      #(number->string arg)
      #(format #f "bar~a in this line" (if (< 1 arg) "s" ""))
    }
  #})

print-measures-per-line =
\override Score.LeftEdge.after-line-breaking =
#(lambda (grob)
  (let* (;; get the 'System from grob
         (sys (ly:grob-system grob))
         ;; filter for 'LeftEdge
         (left-edges-from-system
           (filter
             (lambda (g) (eq? 'LeftEdge (grob-name g)))
             (ly:grob-array->list (ly:grob-object sys 'all-elements))))
         ;; get the 'NonMusicalPaperColumn associated with
         ;; 'left-edges-from-system',
         ;; read out 'when from it and extract main timing,
         ;; sort the resulting list, using "<"
         (when-left-edges
           (sort
             (map
               (lambda (g)
                 (ly:moment-main
                   (ly:grob-property 
                     (look-up-for-parent 'NonMusicalPaperColumn X g)
                     'when)))
               left-edges-from-system)
             <))
          ;; the difference of first and last entry of 'when-left-edges' will
          ;; return the amount of bars per line
          (bars-per-line
            (- (last when-left-edges)
               (car when-left-edges)))
          ;; get the top-most 'StaffSymbol from 'System
          ;; TODO: is it safe?
          (top-staff-symbol
              (car
                (filter
                  (lambda (g) (eq? 'StaffSymbol (grob-name g)))
                (ly:grob-array->list (ly:grob-object sys 'all-elements)))))
          ;; get the 'stencil from 'top-staff-symbol'
          (top-staff-symbol-stil
            (ly:grob-property top-staff-symbol 'stencil))
          ;; make a 'stencil using the predefined 'format-mrkp-to-add'
          ;; this will be added to the 'top-staff-symbol-stil' below
          (new-stil-to-add
            (grob-interpret-markup grob
               (format-mrkp-to-add bars-per-line)))
               )
  ;; add 'new-stil-to-add' to 'top-staff-symbol-stil' only if 'LeftEdge is a
  ;; broken item
  (if (= (ly:item-break-dir grob) -1)
      (ly:grob-set-property! top-staff-symbol 'stencil
       (ly:stencil-combine-at-edge
         top-staff-symbol-stil
         X
         RIGHT
         ;; TODO: better use 'stencil-translate'?
         (ly:stencil-aligned-to
           new-stil-to-add
            Y -4) ;; the value '-4' is quite arbitrary
        1))) ;; insert a little space after 'StaffSymbol
       ))

             
%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%


\paper {
%% Because the markup for counting the bars per line is added to the
%% right of the 'StaffSymbol, an appropiate setting for 'line-width' or
%% 'right-margin' is needed
%% alternatively the 'format-mrkp-to-add' should be changed
line-width = 80
% right-margin = 4\cm
}

mus =
\relative c' {
  c1 c c  c
  c c
  \clef "alto"
  \time 8/8
  \key des \major
  c c
  c c c c
  c c c c
  c2 c c c 
  c c c c
  c4 c c c
  c8 c c c
  c c c c
  c4 c c c
  c2 c c c
  \break
  \time 4/4
  \key cis \major
  c1
  \repeat unfold 32 c16
  %% testing 'alternativeNumberingStyle'
  \set Score.alternativeNumberingStyle = #'numbers-with-letters
  \repeat volta 3 { c,,4 d e f | }
    \alternative {
      { c4 d e f | c2 d }
      { f4 g a b | f4 g a b | f2 a |}
      { c4 d e f | c2 d }
    }
  c1
}


\score {
  \new StaffGroup
  <<
    \new Staff
      %% testing other staf-sizes
      %\with {
      %   fontSize = #-6
      %  \override StaffSymbol.staff-space = #(magstep -6)
      %  \override StaffSymbol.thickness = #(magstep -6)
      %}
      { \transpose c c'' \mus }
    \new Staff
      \mus
  >>
  \layout {
    \context {
      \Score
      %% needed to get acces to 'LeftEdge at line-end
      \override LeftEdge.break-visibility = ##(#t #f #t)
      %% call it :)
      \print-measures-per-line
    }
  }
}

Zahlreiche Kommentare im code.


Ist nicht das gelbe vom Ei, aber das Beste was mir einfiel.


Gruß,
  Harm

infranator

  • Member
Re: Takte pro Zeile zählen
« Antwort #2 am: Montag, 23. Februar 2015, 10:43 »
Hallo harm,

super! Damit kann ich auf jeden Fall was anfangen. Ich werde mal versuchen den Code zu verstehen und ein bisschen damit rumprobieren.
Viele Dank!

Infranator