Arpeggio mit Arrow als gerade Linie? [gelöst]

Begonnen von kilgore, Donnerstag, 4. Februar 2021, 10:02

« vorheriges - nächstes »

kilgore

Hallo!

Ich möchte gerne das Arpeggio Symbol als gerade Linie haben, nicht die gewohnte Triller-Linie.

@harm6 hat mir für ein anderes Problem etwas mit Arpeggio gebaut, wo die Arpeggio tatsächlich eine gerade Linie ist (Bracket ohne Protrusion). Aber da sehe ich nicht wie man einen Pfeil noch dazu bekommt: https://lilypondforum.de/index.php/topic,732.msg4160.html#msg4160


Basteln kann ich das natürlich, aber es kommt oft genug vor, dass eine automatische Funktion viel besser wäre!


\version "2.20.0"

\relative c' {

\arpeggioArrowUp <c e g c>\arpeggio
r4
<c e g c>
_\tweak #'extra-offset #'( -1 . 5.5 )
_\markup {
   \combine
  \draw-line #'(0 . 5)
  \arrow-head #Y #DOWN ##f
  }

}


Danke!
kilgore

harm6

Hallo kilgore,

schau mal, ob das was für Dich ist.
Allerdings erhebt issue 556 das Haupt, sobald Fingersätze zur rechten oder linken dazu kommen. Workaround ist 'X-extent zu tweaken.
Das kann man natürlich auch dann machen, wenn das horizontale spacing zu dicht wird.


\version "2.22.0"

%% The stencil-procedure
#(define (strike grob)
  "Returns a stencil for the @code{Arpeggio} grob with a simple vertical line
and an arrow-head."
  (let* ((pos (ly:grob-property grob 'positions))
         (thick (ly:grob-property grob 'thickness 1))
         (direction (ly:grob-property grob 'arpeggio-direction)))
    (grob-interpret-markup grob
      #{
        \markup
          \combine
          \translate #`(0 . ,(cdr pos))
          \override #`(thickness . ,thick)
          \draw-line #`(0 . ,(- (interval-length pos)))
          \translate
            #(cons 0 ((if (= direction 1) cdr car) (interval-widen pos 0.5)))
          \fontsize #thick
          \arrow-head #Y #direction ##f
      #})))
     
%% music-function to facilitate predefining strike-commands
arpeggioStrike =
#(define-music-function (context-string dir)((string? "Bottom") ly:dir?)
"Sets the @code{arpeggio-direction} property of @code{Arpeggio} to @var{dir}.
Read by the procedure @code{strike}, which returns a stencil.
The optional @var{context-string} sets the context for these commands."
#{
  \override #context-string . Arpeggio.arpeggio-direction = #UP
  \override #context-string . Arpeggio.stencil = #strike
#})
     
%% predefined strike up/down commands for various contexts
arpeggioStrikeUp = \arpeggioStrike #UP
staffArpeggioStrikeUp = \arpeggioStrike Staff #UP
scoreArpeggioStrikeUp = \arpeggioStrike Score #UP

arpeggioStrikeDown = \arpeggioStrike #DOWN
staffArpeggioStrikeDown = \arpeggioStrike Staff #DOWN
scoreArpeggioStrikeDown = \arpeggioStrike Score #DOWN

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Examples
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\paper { indent = 30 }

%% arpeggio-strikes in Voice
\new Staff
  \with { instrumentName = "Strikes in Voice" }
  <<
    \new Voice {
      \voiceOne
      \arpeggioStrikeUp
      <e'' c'' a' e'>16\arpeggio
      \arpeggioStrikeDown
      q16\arpeggio
    }
    \new Voice {
      \voiceTwo a16 a
    }
  >>

%% arpeggio-strikes in Staff
\new Staff
  \with {
  \consists "Span_arpeggio_engraver"
  instrumentName = "Strikes in Staff"
  }
  <<
    \new Voice {
      \voiceOne
      \set Staff.connectArpeggios = ##t
      \staffArpeggioStrikeUp
      <e'' c'' a' e'>16\arpeggio
      \staffArpeggioStrikeDown
      q16\arpeggio
    }
    \new Voice {
      \voiceTwo a16\arpeggio a\arpeggio
    }
  >>

%% arpeggio-strikes in ChoirStaff, here the commands need to be applied in Score
\score {
  \new ChoirStaff
    \with {
      instrumentName = "Strikes in Score"
    }
    {
      \set Score.connectArpeggios = ##t
      <<
        \new Voice \relative c' {
          \scoreArpeggioStrikeUp
          <c e>2\arpeggio
          <d f>2\arpeggio
          <c e>1\arpeggio
        }
        \new Voice \relative c {
          \clef bass
          <c g'>2\arpeggio
          <b g'>2\arpeggio
          <c g'>1\arpeggio
        }
      >>
    }
  \layout {
    \context {
      \Score
      \consists "Span_arpeggio_engraver"
    }
  }
}

%% issue 556 "fingeringOrientations affects cross-voices arpeggio"
%% https://gitlab.com/lilypond/lilypond/-/issues/556
%% workaround: adjust X-extent

\new Staff
  \with {
  \consists "Span_arpeggio_engraver"
  instrumentName = "bug 556"
  }
  <<
    \new Voice {
      \voiceOne
      \set Staff.connectArpeggios = ##t
      \set fingeringOrientations = #'(left) 
      <>^"buggy"
      \staffArpeggioStrikeUp
      <e''-0 c''-1 a'-3 e'-2>4\arpeggio
      \staffArpeggioStrikeDown
      <e''-0 c''-1 a'-3 e'-2>\arpeggio
      \bar "||"
      <>^"tweaked"
      \override Staff.Arpeggio.X-extent = #'(-0.5 . -0.2)
      \staffArpeggioStrikeUp
      <e''-0 c''-1 a'-3 e'-2>\arpeggio
      \staffArpeggioStrikeDown
      <e''-0 c''-1 a'-3 e'-2>\arpeggio
    }
    \new Voice {
      \set fingeringOrientations = #'(left)
      \voiceTwo
      <a-0>\arpeggio <a-0>\arpeggio
     
      <a-0>\arpeggio <a-0>\arpeggio
    }
  >>


Gruß,
  Harm

kilgore

Hallo Harm6,

Danke erneut und vielmals für diese Lösung! Genau so habe ich es mir vorgestellt. Immer wieder beeindruckend, wie du das machst.

Herzlich,
kilgore

kilgore

In der Praxis habe ich einen kleinen Fehler (?) in harm6's Lösung gefunden. Da werden nämlich nur Pfeilen nach oben gesetzt, egal ob man #UP oder #DOWN angibt.

Auch wenn ich nur wenig davon verstehe, habe ich es selber gelöst. Harm6 hat vielleicht eine elegantere Korrektur, aber für mich funktioniert es erstmal! Hier die bearbeitete Lösung:


%% The stencil-procedure
#(define (strike grob)
  "Returns a stencil for the @code{Arpeggio} grob with a simple vertical line
and an arrow-head."
  (let* ((pos (ly:grob-property grob 'positions))
         (thick (ly:grob-property grob 'thickness 1))
         (direction (ly:grob-property grob 'arpeggio-direction)))
    (grob-interpret-markup grob
      #{
        \markup
          \combine
          \translate #`(0 . ,(cdr pos))
          \override #`(thickness . ,thick)
          \draw-line #`(0 . ,(- (interval-length pos)))
          \translate
            #(cons 0 ((if (= direction 1) cdr car) (interval-widen pos 0.5)))
          \fontsize #thick
          \arrow-head #Y #direction ##f
      #})))
     
%% music-function to facilitate predefining strike-commands
arpeggioStrikeOne =
#(define-music-function (context-string dir)((string? "Bottom") ly:dir?)
"Sets the @code{arpeggio-direction} property of @code{Arpeggio} to @var{dir}.
Read by the procedure @code{strike}, which returns a stencil.
The optional @var{context-string} sets the context for these commands."
#{
  \override #context-string . Arpeggio.arpeggio-direction = #UP
  \override #context-string . Arpeggio.stencil = #strike
#})

arpeggioStrikeTwo =
#(define-music-function (context-string dir)((string? "Bottom") ly:dir?)
"Sets the @code{arpeggio-direction} property of @code{Arpeggio} to @var{dir}.
Read by the procedure @code{strike}, which returns a stencil.
The optional @var{context-string} sets the context for these commands."
#{
  \override #context-string . Arpeggio.arpeggio-direction = #DOWN
  \override #context-string . Arpeggio.stencil = #strike
#})
     
%% predefined strike up/down commands for various contexts
arpeggioStrikeUp = \arpeggioStrikeOne #UP
staffArpeggioStrikeUp = \arpeggioStrikeOne Staff #UP
scoreArpeggioStrikeUp = \arpeggioStrikeOne Score #UP

arpeggioStrikeDown = \arpeggioStrikeTwo #DOWN
staffArpeggioStrikeDown = \arpeggioStrikeTwo Staff #DOWN
scoreArpeggioStrikeDown = \arpeggioStrikeTwo Score #DOWN

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Examples
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\paper { indent = 30 }

%% arpeggio-strikes in Voice
\new Staff
  \with { instrumentName = "Strikes in Voice" }
  <<
    \new Voice {
      \voiceOne
      \arpeggioStrikeUp
      <e'' c'' a' e'>16\arpeggio
      \arpeggioStrikeDown
      q16\arpeggio
    }
    \new Voice {
      \voiceTwo a16 a
    }
  >>

%% arpeggio-strikes in Staff
\new Staff
  \with {
  \consists "Span_arpeggio_engraver"
  instrumentName = "Strikes in Staff"
  }
  <<
    \new Voice {
      \voiceOne
      \set Staff.connectArpeggios = ##t
      \staffArpeggioStrikeUp
      <e'' c'' a' e'>16\arpeggio
      \staffArpeggioStrikeDown
      q16\arpeggio
    }
    \new Voice {
      \voiceTwo a16\arpeggio a\arpeggio
    }
  >>

%% arpeggio-strikes in ChoirStaff, here the commands need to be applied in Score
\score {
  \new ChoirStaff
    \with {
      instrumentName = "Strikes in Score"
    }
    {
      \set Score.connectArpeggios = ##t
      <<
        \new Voice \relative c' {
          \scoreArpeggioStrikeUp
          <c e>2\arpeggio
          <d f>2\arpeggio
          <c e>1\arpeggio
        }
        \new Voice \relative c {
          \clef bass
          <c g'>2\arpeggio
          <b g'>2\arpeggio
          <c g'>1\arpeggio
        }
      >>
    }
  \layout {
    \context {
      \Score
      \consists "Span_arpeggio_engraver"
    }
  }
}

%% issue 556 "fingeringOrientations affects cross-voices arpeggio"
%% https://gitlab.com/lilypond/lilypond/-/issues/556
%% workaround: adjust X-extent

\new Staff
  \with {
  \consists "Span_arpeggio_engraver"
  instrumentName = "bug 556"
  }
  <<
    \new Voice {
      \voiceOne
      \set Staff.connectArpeggios = ##t
      \set fingeringOrientations = #'(left)
      <>^"buggy"
      \staffArpeggioStrikeUp
      <e''-0 c''-1 a'-3 e'-2>4\arpeggio
      \staffArpeggioStrikeDown
      <e''-0 c''-1 a'-3 e'-2>\arpeggio
      \bar "||"
      <>^"tweaked"
      \override Staff.Arpeggio.X-extent = #'(-0.5 . -0.2)
      \staffArpeggioStrikeUp
      <e''-0 c''-1 a'-3 e'-2>\arpeggio
      \staffArpeggioStrikeDown
      <e''-0 c''-1 a'-3 e'-2>\arpeggio
    }
    \new Voice {
      \set fingeringOrientations = #'(left)
      \voiceTwo
      <a-0>\arpeggio <a-0>\arpeggio
     
      <a-0>\arpeggio <a-0>\arpeggio
    }
  >>

harm6

Zitat von: kilgoreIn der Praxis habe ich einen kleinen Fehler (?) in harm6's Lösung gefunden. Da werden nämlich nur Pfeilen nach oben gesetzt, egal ob man #UP oder #DOWN angibt.

In der Tat, in `arpeggioStrike` habe ich doch glatt vergessen die Variable `context-string` zu übergeben und stattdessen auf einem konstanten Wert belassen.

Hier der korrigierte Code (komplett):


\version "2.22.0"

%% The stencil-procedure
#(define (strike grob)
  "Returns a stencil for the @code{Arpeggio} grob with a simple vertical line
and an arrow-head."
  (let* ((pos (ly:grob-property grob 'positions))
         (thick (ly:grob-property grob 'thickness 1))
         (direction (ly:grob-property grob 'arpeggio-direction)))
    (grob-interpret-markup grob
      #{
        \markup
          \combine
          \translate #`(0 . ,(cdr pos))
          \override #`(thickness . ,thick)
          \draw-line #`(0 . ,(- (interval-length pos)))
          \translate
            #(cons 0 ((if (= direction 1) cdr car) (interval-widen pos 0.5)))
          \fontsize #thick
          \arrow-head #Y #direction ##f
      #})))
     
%% music-function to facilitate predefining strike-commands
arpeggioStrike =
#(define-music-function (context-string dir)((string? "Bottom") ly:dir?)
"Sets the @code{arpeggio-direction} property of @code{Arpeggio} to @var{dir}.
Read by the procedure @code{strike}, which returns a stencil.
The optional @var{context-string} sets the context for these commands."
#{
  \override #context-string . Arpeggio.arpeggio-direction = #dir
  \override #context-string . Arpeggio.stencil = #strike
#})
     
%% predefined strike up/down commands for various contexts
arpeggioStrikeUp = \arpeggioStrike #UP
staffArpeggioStrikeUp = \arpeggioStrike Staff #UP
scoreArpeggioStrikeUp = \arpeggioStrike Score #UP

arpeggioStrikeDown = \arpeggioStrike #DOWN
staffArpeggioStrikeDown = \arpeggioStrike Staff #DOWN
scoreArpeggioStrikeDown = \arpeggioStrike Score #DOWN

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Examples
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\paper { indent = 30 }

%% arpeggio-strikes in Voice
\new Staff
  \with { instrumentName = "Strikes in Voice" }
  <<
    \new Voice {
      \voiceOne
      \arpeggioStrikeUp
      <e'' c'' a' e'>16\arpeggio
      \arpeggioStrikeDown
      q16\arpeggio
    }
    \new Voice {
      \voiceTwo a16 a
    }
  >>

%% arpeggio-strikes in Staff
\new Staff
  \with {
  \consists "Span_arpeggio_engraver"
  instrumentName = "Strikes in Staff"
  }
  <<
    \new Voice {
      \voiceOne
      \set Staff.connectArpeggios = ##t
      \staffArpeggioStrikeUp
      <e'' c'' a' e'>16\arpeggio
      \staffArpeggioStrikeDown
      q16\arpeggio
    }
    \new Voice {
      \voiceTwo a16\arpeggio a\arpeggio
    }
  >>

%% arpeggio-strikes in ChoirStaff, here the commands need to be applied in Score
\score {
  \new ChoirStaff
    \with {
      instrumentName = "Strikes in Score"
    }
    {
      \set Score.connectArpeggios = ##t
      <<
        \new Voice \relative c' {
          \scoreArpeggioStrikeUp
          <c e>2\arpeggio
          <d f>2\arpeggio
          <c e>1\arpeggio
        }
        \new Voice \relative c {
          \clef bass
          <c g'>2\arpeggio
          <b g'>2\arpeggio
          <c g'>1\arpeggio
        }
      >>
    }
  \layout {
    \context {
      \Score
      \consists "Span_arpeggio_engraver"
    }
  }
}

%% issue 556 "fingeringOrientations affects cross-voices arpeggio"
%% https://gitlab.com/lilypond/lilypond/-/issues/556
%% workaround: adjust X-extent

\new Staff
  \with {
  \consists "Span_arpeggio_engraver"
  instrumentName = "bug 556"
  }
  <<
    \new Voice {
      \voiceOne
      \set Staff.connectArpeggios = ##t
      \set fingeringOrientations = #'(left) 
      <>^"buggy"
      \staffArpeggioStrikeUp
      <e''-0 c''-1 a'-3 e'-2>4\arpeggio
      \staffArpeggioStrikeDown
      <e''-0 c''-1 a'-3 e'-2>\arpeggio
      \bar "||"
      <>^"tweaked"
      \override Staff.Arpeggio.X-extent = #'(-0.5 . -0.2)
      \staffArpeggioStrikeUp
      <e''-0 c''-1 a'-3 e'-2>\arpeggio
      \staffArpeggioStrikeDown
      <e''-0 c''-1 a'-3 e'-2>\arpeggio
    }
    \new Voice {
      \set fingeringOrientations = #'(left)
      \voiceTwo
      <a-0>\arpeggio <a-0>\arpeggio
     
      <a-0>\arpeggio <a-0>\arpeggio
    }
  >>


Gruß,
  Harm

kilgore

Danke Harm, für das Update!

Die Lösung funktioniert im Kontext hervorragend!