Deutschsprachiges LilyPond-Forum

Allgemeine Fragen und Probleme => Fragen und Probleme aller Art => Thema gestartet von: thomas am Montag, 27. März 2023, 13:23

Titel: Jeden Takt einzeln markieren
Beitrag von: thomas am Montag, 27. März 2023, 13:23
Hallo,

kann man in einem score immer nur einen Takt markieren? Und dann ein oder mehrere PDFs erzeugen, in denen jeweils nur der eine Takt markiert ist.


Beispiel:
\version "2.20.0"

\repeat unfold 10 { c'1 }
Soll ein PDF mit 10 Seiten erzeugen, bei denen jeweils ein Takt markiert ist. Oder 10 PDFs mit einer Seite.

Gruß Thomas


test1.png
test1.png
test1.png
test1.png
Titel: Antw:Jeden Takt einzeln markieren
Beitrag von: Manuela am Montag, 27. März 2023, 17:51
Ich kann eine Art Halbautomatik anbieten

\version "2.23.5"

colorSpan =
#(define-music-function (y-lower y-upper color)
   (number? number? color?)
   #{
     \once\override HorizontalBracket.stencil =
     $(lambda (grob)
        (let* (
                (area (ly:horizontal-bracket::print grob))
                (X-ext (ly:stencil-extent area X))
                (Y-ext (ly:stencil-extent area Y)))
          (set! Y-ext (cons y-lower y-upper))
          (ly:grob-set-property! grob 'layer -10)
          (ly:make-stencil (list 'color color
                                 (ly:stencil-expr (ly:round-filled-box X-ext Y-ext 0))
                                 X-ext Y-ext))))
     \once\override HorizontalBracket.Y-offset = #0
     \once\override HorizontalBracket.shorten-pair = #'(-.95 . -1.65)
   #})

markierterTakt =
#(define-music-function (y-lower y-upper color wo)
   (number? number? color? number?)
   #{
     {
       s1 * $wo
       \omit Rest
       \colorSpan $y-lower $y-upper $color
       r4\startGroup s s r\stopGroup
     }
   #})

\layout {
  \context {
    \Voice
    \consists "Horizontal_bracket_engraver"
  }
}

musi = \relative { c' c c c }

\new Staff <<
  \new Voice \relative {
    \repeat unfold 5 \musi
  }
  \new Voice {
    s1
    \omit Rest
    \colorSpan #-3 #2 #red
    r4\startGroup s s r\stopGroup
    s1
  }
  \new Voice
  {
    \markierterTakt #-3 #3 #green #3
  }
>>

Mit der Funktion markierterTakt kannst du den Takt angeben, der farbig markiert werden soll. Falls es sich um einen 3/4 Takt handelt, muss die Funktion entsprechend angepasst werden

Das ganze beruht auf dem Snippet #960 (https://lsr.di.unimi.it/LSR/Item?id=960)
Titel: Antw:Jeden Takt einzeln markieren
Beitrag von: Arnold am Montag, 27. März 2023, 21:17
Hallo Thomas,

und noch ein Hinweis, was mit Scheme auch geht, ohne gleich ein lauffähiges Beispiel zu liefern:

SCHEME kann auch Dateien schreiben (nur in der Web-Version verboten).
Man kann sogar im LY-Quellcode dann per SCHEME erst eine Datei erstellen, die an späterer Stelle in der Datei dann per \include gelesen wird.
Allerdings gebe ich zu, daß es nicht bequem ist, jeden »\« zu verdoppeln, damit er dem String-Format entspricht, den man dann mittels »(display ...« ausgibt.
So könnte man aber bequem eine frei definierbare Anzahl an \bookparts erstellen, die sich dann nur ein einer Kleinigkeit unterscheiden.

Arnold
Titel: Antw:Jeden Takt einzeln markieren
Beitrag von: thomas am Dienstag, 28. März 2023, 10:07
Hallo,

die Lösung von Manuela funktioniert, wenn man nur Viertel hat.

Wenn man kürzere Noten hat, werden die letzten Noten nicht markiert.
taktegelb-kurz.png

Wenn man längere Noten hat, wird der Takt breiter, wenn er markiert wird.
taktegelb-lang.png

Wenn nicht alle Noten markiert sind ist in meinem Fall zwar ärgerlich, aber verschmerzbar. Wenn sich aber die Takte verbreitern nur weil sie markiert wurden, damit kann ich leider nichts anfangen.

Mit
       \colorSpan $y-lower $y-upper $color
       r2\startGroup r2\stopGroup

würde es dann noch mit halben Noten funktionieren, aber immer noch nicht mit ganzen. Und bei kurzen Noten fehlt dann noch mehr.

Gruß Thomas
Titel: Antw:Jeden Takt einzeln markieren
Beitrag von: Rudi Guggt am Dienstag, 28. März 2023, 13:16
Hallo,

in der Mailingliste (https://www.mail-archive.com/lilypond-user@gnu.org/msg99699.html) gab es eine ähnliche Problemstellung.

An 2 Stellen aktualisiert, sieht die vorgestellte Lösung dazu so aus:

bgColor =
#(define-music-function (parser location y-lower y-upper color) (number?
number? color?)
   #{\stopStaff
     \override Staff.StaffSymbol.stencil =
     $(lambda (grob)
        (let* ((staff (ly:staff-symbol::print grob))
               (X-ext (ly:stencil-extent staff X))
               (Y-ext (ly:stencil-extent staff Y)))
          (set! Y-ext (cons
                       (+ (car Y-ext) (+ y-lower 2))
                       (+ (cdr Y-ext) (- y-upper 2))))
          (ly:grob-set-property! grob 'layer -10)
          (ly:stencil-add
           (ly:make-stencil (list 'color color
                              (ly:stencil-expr (ly:round-filled-box X-ext
Y-ext 0))
                              X-ext Y-ext))
           staff)))
     \startStaff
   #})

\relative c' {
  c1
  \bgColor #-2 #2 #yellow
  c1
  \stopStaff \revert Staff.StaffSymbol.stencil \startStaff
  c1
  \bgColor #-3 #2 #green
  c1
}

Wenn das jemand mit der Taktzählautomatik verdübeln könnte, wär natürlich klasse...

Gruß
Rudi
Titel: Antw:Jeden Takt einzeln markieren
Beitrag von: Manuela am Dienstag, 28. März 2023, 13:45
Rudi, deine Lösung ist natürlich viel besser da unabhängig von den Notenwerten.

Zitat von: Rudi Guggt am Dienstag, 28. März 2023, 13:16Wenn das jemand mit der Taktzählautomatik verdübeln könnte, wär natürlich klasse...

Damit kann ich aushelfen (in Anlehnung an den bereits publizierten Code)
\version "2.23.5"

musi = \relative { c''4 c c c c1 c2 c4 c8 c16 c c2 c2 }

bgColor =
#(define-music-function (y-lower y-upper color)
   (number? number? color?)
   #{\stopStaff
     \override Staff.StaffSymbol.stencil =
     $(lambda (grob)
        (let* ((staff (ly:staff-symbol::print grob))
               (X-ext (ly:stencil-extent staff X))
               (Y-ext (ly:stencil-extent staff Y)))
          (set! Y-ext (cons
                       (+ (car Y-ext) (+ y-lower 2))
                       (+ (cdr Y-ext) (- y-upper 2))))
          (ly:grob-set-property! grob 'layer -10)
          (ly:stencil-add
           (ly:make-stencil
            (list 'color color
                  (ly:stencil-expr (ly:round-filled-box X-ext Y-ext 0))
                  X-ext Y-ext))
           staff)))
     \startStaff
   #})

colorTakt =
#(define-music-function (y-lower y-upper color wo)
   (number? number? color? number?)
   #{
     {
       s1 * $wo
       \bgColor #-2 #2 #color
       s1
       \stopStaff \revert Staff.StaffSymbol.stencil \startStaff
     }
   #})

\new Staff
<<
  \new Voice \musi
  \new Voice \colorTakt #2 #2 #yellow #0
>>

\new Staff
<<
  \new Voice \musi
  \new Voice \colorTakt #2 #2 #yellow #1
>>

\new Staff
<<
  \new Voice \musi
  \new Voice \colorTakt #2 #2 #yellow #2
>>

\new Staff
<<
  \new Voice \musi
  \new Voice \colorTakt #2 #2 #yellow #3
>>

Wenn die Taktzählung mit 1 beginnen soll, kann man folgenden Code verwenden
colorTakt =
#(define-music-function (y-lower y-upper color wo)
   (number? number? color? number?)
   #{
     {
       s1 * #(- wo 1)
       \bgColor #-2 #2 #color
       s1
       \stopStaff \revert Staff.StaffSymbol.stencil \startStaff
     }
   #})

Wahrscheinlich geht es eleganter als mit einer 2. Stimme, Harm, wo bist du? Ich vermisse dich...
Titel: Antw:Jeden Takt einzeln markieren
Beitrag von: thomas am Dienstag, 28. März 2023, 17:24
So geht es.
Zweite Stimme ist für mich in Ordnung.
Wenn es der erste Takt in der Zeile ist, wird Notenschlüssel usw. mit markiert. Aber damit kann ich erst mal leben. Wenn das noch weg wäre, würde ich den Betreff ändern auf gelöst.
Titel: Antw:Jeden Takt einzeln markieren
Beitrag von: Malte am Dienstag, 28. März 2023, 17:33
Hallo allerseits, ich habe gerade den Thread nur überflogen, dabei aber gesehen, dass ihr selbst eine Funktion zum farbigen Hinterlegen gebaut habt. In LilyPond 2.24 scheint eine entsprechende Funktion schon eingebaut zu sein, siehe Changes (http://lilypond.org/doc/v2.24/Documentation/changes/index#editorial-annotation-improvements). Hilft das für einen einfacheren Code?
Titel: Antw:Jeden Takt einzeln markieren
Beitrag von: Manuela am Dienstag, 28. März 2023, 17:55
Danke Malte, da haben wir uns vergebens geplagt  ;)
Aber nicht jede/r hat 2.24 oder höher installiert, mein Ubuntu steht bei 2.23
Titel: Antw:Jeden Takt einzeln markieren
Beitrag von: Manuela am Dienstag, 28. März 2023, 18:00
Malte, weil du schon da bist  :) .

Ich habe schon in einem anderen Thread (https://lilypondforum.de/index.php/topic,1123.0.html) gepostet, aber keine Antwort erhalten. Das Archiv (https://archiv.lilypondforum.de/) ist nicht erreichbar
Titel: Antw:Jeden Takt einzeln markieren
Beitrag von: harm6 am Dienstag, 28. März 2023, 21:58
Zitat von: Manuela am Dienstag, 28. März 2023, 13:45Harm, wo bist du? Ich vermisse dich...

Ich bin immer noch da ;)
Allerdings beruflich so eingespannt, daß mir die Zeit und Energie fehlt, um mehr zu tun als die Beiträge zu lesen :(

Gruß,
  Harm
Titel: Antw:Jeden Takt einzeln markieren
Beitrag von: juergen74 am Dienstag, 28. März 2023, 23:15
Hallo,

hier mal die bisherigen Erkenntnisse zusammen mit einem Loop und den gewünschten Seitenumbrüchen:

\version "2.24.0"

\paper {
  ragged-bottom = ##t
}

musi = \relative { c''4 c c c c1 c2 c4 c8 c16 c c2 c2 }

createScores =
#(define-scheme-function (repeats) (number?)
   (for-each add-score (map (lambda (num)
                              #{
                                \score {
                                  \new Staff
                                  <<
                                    {
                                      \musi
                                      \pageBreak
                                    }
                                    {
                                      s1 * #num
                                      \staffHighlight "yellow"
                                      s1
                                      \stopStaffHighlight
                                    }
                                  >>
                                }
                              #})
                         (iota repeats))))

\createScores #4

Mit der neuen Funktion \StaffHighlight werden auch Notenschlüssel usw. nicht markiert. Für ältere Versionen:\version "2.24.0"


\paper {
  ragged-bottom = ##t
}

musi = \relative { c''4 c c c c1 c2 c4 c8 c16 c c2 c2 }

bgColor =
#(define-music-function (y-lower y-upper color)
   (number? number? color?)
   #{\stopStaff
     \override Staff.StaffSymbol.stencil =
     $(lambda (grob)
        (let* ((staff (ly:staff-symbol::print grob))
               (X-ext (ly:stencil-extent staff X))
               (Y-ext (ly:stencil-extent staff Y)))
          (set! Y-ext (cons
                       (+ (car Y-ext) (+ y-lower 2))
                       (+ (cdr Y-ext) (- y-upper 2))))
          (ly:grob-set-property! grob 'layer -10)
          (ly:stencil-add
           (ly:make-stencil
            (list 'color color
              (ly:stencil-expr (ly:round-filled-box X-ext Y-ext 0))
              X-ext Y-ext))
           staff)))
     \startStaff
   #})

createScores =
#(define-scheme-function (repeats) (number?)
   (for-each add-score (map (lambda (num)
                              #{
                                \score {
                                  \new Staff
                                  <<
                                    {
                                      \musi
                                      \pageBreak
                                    }
                                    {
                                      s1 * $num
                                      \bgColor #-2 #2 #yellow
                                      s1
                                      \stopStaff \revert Staff.StaffSymbol.stencil \startStaff
                                    }
                                  >>
                                }
                              #})
                         (iota repeats))))

\createScores #4

Wo müsste man denn ansetzen, um das vollautomatisch zu erzeugen (also ohne erst die Takte zu zählen und als Parameter mitzugeben)? ApplyContext, Translator, Engraver?


Grüße, Jürgen.
Titel: Antw:Jeden Takt einzeln markieren
Beitrag von: Manuela am Mittwoch, 29. März 2023, 15:32
Ich habe chatGPT befragt. Abgesehen davon, dass es lustigen Scheme-Code geliefert und Funktionen frei erfunden hat z.B. ly:math-round, hat es mir einen Hinweis auf ly:music-length geliefert, damit habe ich folgende Funktion gebastelt

\version "2.23.5"

\paper {
  ragged-bottom = ##t
  ragged-last = ##t
  ragged-right = ##t
  tagline = ##f
}

% Definieren Sie eine Melodie mit 4 Takten
melody = \relative {
  \time 4/4
  c'4 d e f c1 c c d2 e f g
}

bgColor =
#(define-music-function (y-lower y-upper color)
   (number? number? color?)
   #{\stopStaff
     \override Staff.StaffSymbol.stencil =
     $(lambda (grob)
        (let* ((staff (ly:staff-symbol::print grob))
               (X-ext (ly:stencil-extent staff X))
               (Y-ext (ly:stencil-extent staff Y)))
          (set! Y-ext (cons
                       (+ (car Y-ext) (+ y-lower 2))
                       (+ (cdr Y-ext) (- y-upper 2))))
          (ly:grob-set-property! grob 'layer -10)
          (ly:stencil-add
           (ly:make-stencil
            (list 'color color
                  (ly:stencil-expr (ly:round-filled-box X-ext Y-ext 0))
                  X-ext Y-ext))
           staff)))
     \startStaff
   #})

createPages =
#(define-scheme-function (mus col) (ly:music? color?)
   (let* ((muslength (ly:music-length mus))
          (musdauer  (ly:moment-main muslength))
          (takte     (inexact->exact (floor musdauer)))
          )
     (for-each
      add-score
      (map (lambda (num)
             #{
               \score {
                 \new Staff
                 <<
                   {
                     $mus
                     \pageBreak
                   }
                   {
                     s1 * $num
                     \bgColor #-2 #2 $col
                     s1
                     \stopStaff \revert Staff.StaffSymbol.stencil \startStaff
                   }
                 >>
               }
             #})
           (iota takte)))))

\bookpart {
  \melody
}

\createPages \melody #green

Für ein anderes Taktmaß als 4/4 müsste man die Funktion natürlich umdefinieren, könnte das Taktmaß auch als Parameter übergeben
Titel: Antw:Jeden Takt einzeln markieren
Beitrag von: Manuela am Mittwoch, 29. März 2023, 15:52
Und jetzt nochmal mit beliebigem Taktmaß

\version "2.23.5"

\paper {
  ragged-bottom = ##t
  ragged-last = ##t
  ragged-right = ##t
  tagline = ##f
}

melody = \relative {
  \time 3/8
  c'8 d e f g a c4. c c d8. e f g
}

bgColor =
#(define-music-function (y-lower y-upper color)
   (number? number? color?)
   #{\stopStaff
     \override Staff.StaffSymbol.stencil =
     $(lambda (grob)
        (let* ((staff (ly:staff-symbol::print grob))
               (X-ext (ly:stencil-extent staff X))
               (Y-ext (ly:stencil-extent staff Y)))
          (set! Y-ext (cons
                       (+ (car Y-ext) (+ y-lower 2))
                       (+ (cdr Y-ext) (- y-upper 2))))
          (ly:grob-set-property! grob 'layer -10)
          (ly:stencil-add
           (ly:make-stencil
            (list 'color color
                  (ly:stencil-expr (ly:round-filled-box X-ext Y-ext 0))
                  X-ext Y-ext))
           staff)))
     \startStaff
   #})

%% mus: Musikausdruck, sollte eine einfache Stimme sein
%% col: gewünschte Farbe
%% mom: Taktmaß, z.B. 3/8
createPages =
#(define-scheme-function (mus col mom) (ly:music? color? ly:moment?)
   (let* ((muslength (ly:music-length mus))
          (musdiv    (ly:moment-div muslength mom))
          (musdauer  (ly:moment-main musdiv))
          (takte     (inexact->exact (floor musdauer)))
          )
     (write-me "musiv" musdiv)
     (write-me "ismom" (ly:moment? musdiv))
     (for-each
      add-score
      (map (lambda (num)
             #{
               \score {
                 \new Staff
                 <<
                   {
                     $mus
                     \pageBreak
                   }
                   {
                     s1 * $mom  * $num
                     \bgColor #-2 #2 $col
                     s1 * $mom
                     \stopStaff \revert Staff.StaffSymbol.stencil \startStaff
                   }
                 >>
               }
             #})
           (iota takte)))))

\bookpart {
  \melody
}

\createPages \melody #green #(ly:make-moment 3/8)

Achtung bei Auftakt