Autor Thema: Segno, Übungszeichen, Lautstärke nach einander  (Gelesen 2694 mal)

martinusbaum

  • Member
Segno, Übungszeichen, Lautstärke nach einander
« am: Freitag, 9. November 2012, 17:14 »
hallo zusammen,

Am Zeilenanfang soll nacheinander stehen:
Segno, Übungszeichen "A", erste Note mit Lautstärkebezeichnung
\mark \markup { \musicglyph #"scripts.segno" }     b4-. \mf \mark \default
dabei steht das "A" nach der ersten Note. Wie muss die Reihenfolge der Kommandos sein? ich bin nicht draufgekommen. Bei falscher Reihenfolge wird entweder Übungszeichen oder Segno unterdrückt.
Hilfe würde mich freuen! danke
martinusbaum

Be-3

  • Member
Re: Segno, Übungszeichen, Lautstärke nach einander
« Antwort #1 am: Samstag, 10. November 2012, 11:16 »
Hallo martinusbaum,

es ist weniger ein Problem der Reihenfolge als ein Problem der Gleichzeitigkeit.
Lilypond erlaubt nur ein \mark-Ereignis zu einem Zeitpunkt. Mit der Note "zwischen" Segno und Buchstaben funktioniert es, weil die beiden Marks nicht gleichzeitig auftreten.


Lösung 1 (alter Bauerntrick)

Wenn Du einen künstlichen Abstand wie z. B. ein \grace s8 einfügst (\grace deshab, damit die Zählzeit nicht beeinflußt wird), kannst Du mehere \mark-Befehle hintereinander absetzen.

\relative c'' {
  \mark \markup { \musicglyph #"scripts.segno" } \grace s8 \mark \default b4-. \mf
}


Lösung 2

Frei nach Snippet http://lsr.dsi.unimi.it/LSR/Item?id=202 einen eigenen \markSegnoDefault-Befehl definieren, der sowohl Segno-Zeichen als auch Buchstaben gemeinsam ausgibt:

\version "2.16.0"

#(define (format-mark-segno-letters mark context)
  (markup #:line
      (#:raise 2 #:musicglyph "scripts.segno"
        #:bold (#:markletter (- (ly:context-property context 'rehearsalMark) 2))
        )))

markSegnoDefault = {
  \once \set Score.markFormatter = #format-mark-segno-letters
  \mark \default
}

\relative c'' {
  \markSegnoDefault
  b-.\mf
}

Der Befehl \mark positioniert normalerweise zentriert über dem Taktstrich bzw. zu Beginn über dem Notenschlüssel, die Positionierung als solche wäre in Deinem Fall also grundsätzlich je nach Vorlieben noch einmal näher zu betrachten. Ich habe mich hier zunächst nur auf reine Funktionalität beschränkt, um das Wesentliche herauszustellen.

Viele Grüße
Torsten
« Letzte Änderung: Samstag, 10. November 2012, 11:18 von Be-3 »

harm6

  • Member
Re: Segno, Übungszeichen, Lautstärke nach einander
« Antwort #2 am: Samstag, 10. November 2012, 23:27 »
Hallo,

ich habe mal versucht eine allgemeine Definition zu entwerfen, die ein beliebiges markup mit der jeweiligen default-RehearsalMark verbindet.
Der Code unten will es ermöglichen, daß beide links oder rechts von einander, übereinander oder in vertauschter Reihenfolge übereinander ausgegeben werden.
Nicht angegangen wir das Problem, wie RehearsalMarks am Zeilenende und am Beginn der neuen Zeile ausgegeben werden sollen.
Dazu gibt es aber https://liarchiv.joonet.de/index.php?topic=942.msg5239;topicseen#msg5239 (hiermit kann man zwar auch mehrere RehearsalMarks kombinieren, aber nur übereinander), sowie einige Snippets im LSR bzw /Documentation/snippets.

Zu diesem Zweck greife ich etwas später in den Verarbeitungsprozeß ein als Torsten's zweiter Lösungsansatz: Ich lasse die stencil erst berechnen und kombiniere sie dann, via 'before-line-breaking.
Das hat den Vorteil, daß die üblichen Formatierungsbefehle für default-RehearsalMarks weiterhin frei verfügbar sind.

Anwendung:
Der Befehl nennt sich `addMarkupToDefaultRehearsalMark´
Er benötigt zwei Argumente:
  • eine Liste
  • das custom-markup

Die vollständige Liste kann so aussehen:

  #`((axis . ,X)
     (order . 1)
     (align-direction . ,CENTER)
     (center-on-first-stencil . #t))


    Wobei

    • `axis´ die Achse ist, in der die 'stencil kombiniert werden sollen.
      Mögliche Eingaben: X oder Y
    • `order´ ist die Reihenfolge: 1 meint von links nach rechts, bzw von oben nach unten
                                              -1 umgekehrt.
      Wobei das custom-markup immer zuerst in der abzuarbeitenden Liste steht. 1 bzw -1 dreht die Liste dann um.
      Mögliche Eingaben: 1 oder -1
    • `align-direction´ gibt an wie die 'stencil zu einander justiert werden.
      Falls die 'stencil übereinander stehen (axis . Y):linksbündig, rechtsbündig, zentriert.
      Falls sie nebeneinander stehen (axis . X): Ob die Fluchtlinie oben oder unten sein soll, oder ob sie zentriert ausgerichtet werden sollen.
      (Hier fehlt mir ein wenig Fach-Vokabular. Ich hoffe, ich habe mich verständlich ausgedrückt.)
      Mögliche Eingaben: LEFT, CENTER oder RIGHT (entspricht -1, 0 oder 1)
      Andere numerische Werte sind möglich.
    • `center-on-first-stencil´ gibt an ob die neue RehearsalMark anhand ihres ersten zu schreibenden 'stencil zentriert werden soll.
      Das ist insbesondere dann sinnvoll, falls sie nebeneinander stehend am Zeilenanfang ausgegeben werden soll.
      Falls `center-on-first-stencil´ auf #f gesetzt werden soll kann man dieses Element der Liste auch komplett weglassen.
      Falls `center-on-first-stencil´ auf #t gesetzt wird kann sie mittels
      \override Score.RehearsalMark #'self-alignment-X = #<whatever>
      nicht mehr überschrieben werden. Ist dann aber auch nicht sinnvoll.
      Mögliche Eingaben: #f oder #t

    Generell: die Zeichen ` und , sind notwendig.


Das custom-markup
kann ganz normal in LilyPond-Syntax angegeben werden.
Bsp:  \markup { \musicglyph #"scripts.segno" }
Sinnvoll ist es eine Variable hierfür zu benutzen.

Die Angabe der default-RehearsalMark
habe ich nicht in die Funktion aufgenommen (obwohl das möglich gewesen wäre), um es zu ermöglichen einen Code erst mit normalen \mark \default Befehlen einzugeben und dann erst hinterher die Zusätze einzufügen.
Sie muß also wie gewohnt geschrieben werden:
\mark \default



Alles zusammen kann dann so aussehen:
     \addMarkupToDefaultRehearsalMark
       #`((axis . ,X)
          (order . 1)
          (align-direction . ,CENTER)
          (center-on-first-stencil . #t))
       \markup { \musicglyph #"scripts.segno" }


Wie oben schon erwähnt sollte man aber eher Variablen benutzen, z.B.:


    segnoMarkup = \markup { \musicglyph #"scripts.segno" }
   
    segnoDefault = {
        \addMarkupToDefaultRehearsalMark
          #`((axis . ,X)
             (order . 1)
             (align-direction . ,CENTER)
             (center-on-first-stencil . #t))
          \segnoMarkup
          \mark \default
    }


Und als \segnoDefault dann im Code anwenden.
(Hier habe ich \mark \default dann doch mit hineingeschrieben.)


Code

\version "2.16.0"

% #(ly:set-option 'debug-skylines #t)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% definition of the new combined stencil
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#(define (combine-markup-default-rehearsal-mark alist text)
   (lambda (grob)
     (let* ((default-stencil (ly:grob-property grob 'stencil))
            (sky-l (ly:grob-property grob 'skyline-horizontal-padding ))
            (other-axis (lambda (a) (remainder (+ a 1) 2)))
            (markup-stencil
              (grob-interpret-markup grob text))
            (axis (assoc-ref alist 'axis))
            (order (assoc-ref alist 'order))
            (align-direction (assoc-ref alist 'align-direction))
            (center-on-first-stencil (assoc-ref alist 'center-on-first-stencil))
            (stil-lst (list markup-stencil default-stencil))
            (stencil-list (if (= order 1) stil-lst (reverse stil-lst)))
            (new-stencil (ly:stencil-combine-at-edge
                           (ly:stencil-aligned-to (car stencil-list) (other-axis axis) align-direction)
                             axis
                             RIGHT
                             (ly:stencil-aligned-to (cadr stencil-list) (other-axis axis) align-direction)
                             1))
            (first-stencil-length (interval-length (ly:stencil-extent (car stencil-list) X)))
            (new-stencil-length (interval-length (ly:stencil-extent new-stencil X))))
           
     (if (and (eq? axis X) center-on-first-stencil)
       (ly:grob-set-property! grob 'self-alignment-X
            (/ (- new-stencil-length first-stencil-length) (* -1 new-stencil-length)))
       #f)
         
     (ly:grob-set-property! grob 'stencil new-stencil))))
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%       
% definition of a music-function to use the new stencil
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
         
addMarkupToDefaultRehearsalMark =
#(define-music-function (parser location alist mrkp)(list? markup?)
#{
        \once \override Score.RehearsalMark #'before-line-breaking =
          #(combine-markup-default-rehearsal-mark alist mrkp)
#})

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% definition of the test-markup to use with the function
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

segnoMarkup =
\markup { \musicglyph #"scripts.segno" }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% definitions of shortcuts of various combinitions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

segnoDefault = {
\addMarkupToDefaultRehearsalMark
  #`((axis . ,X)
     (order . 1)
     (align-direction . ,CENTER)
     (center-on-first-stencil . #t))
  \segnoMarkup
  \mark \default
}

defaultSegno = {
\addMarkupToDefaultRehearsalMark
  #`((axis . ,X)
     (order . -1)
     (align-direction . ,CENTER)
     (center-on-first-stencil . #t))
  \segnoMarkup
  \mark \default
}

defaultOnTopOfSegno = {
\addMarkupToDefaultRehearsalMark
  #`((axis . ,Y)
     (order . -1)
     (align-direction . ,CENTER)
     ;; if `center-on-first-stencil´ is set to #f
     ;; it can be omitted!
     ;; see `segnoOnTopOfDefault´
     (center-on-first-stencil . #f))
  \segnoMarkup
  \mark \default
}

segnoOnTopOfDefault = {
\addMarkupToDefaultRehearsalMark
  #`((axis . ,Y)
     (order . 1)
     (align-direction . ,CENTER))
  \segnoMarkup
  \mark \default
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ----- TEST ----
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\paper {
        indent = 0
        line-width = 50
}

\relative c' {
        \set Score.markFormatter = #format-mark-box-alphabet
% A
        \mark \default
        c'1
        \break   
% B
        \segnoDefault
        b4-. \mf a2.
        \break
% C
        \mark \default
        a1
        \break
% D
        \defaultSegno
        g
        \break
% E
        \mark \default
        f1
        \break
% F
        \defaultOnTopOfSegno
        e
        \break
% G
        \mark \default
        d1
        \break
% H
        \segnoOnTopOfDefault
        e
        \break 
% I
        \mark \default
        d1
}


Code und PNG auch im Anhang.

Getestet mit 2.16.0 und 2.17.6
Für 2.12.3 und 2.14.2 muß man als Funktion
addMarkupToDefaultRehearsalMark =
#(define-music-function (parser location alist mrkp)(list? markup?)
#{
        \once \override Score.RehearsalMark #'before-line-breaking =
          #(combine-markup-default-rehearsal-mark $alist $mrkp)
#})
benutzen, dann klappts auch mit diesen Versionen.

HTH,
  Harm

P.S.:
Die Erweiterung auf eine beliebige Anzahl von markups mit/ohne default-RehearsalMark halte ich für möglich.
Aber ist das sinnvoll?
Ich denke nicht. Insoweit habe ich mir das gespart.

EDIT: Aus irgendeinem Grund hat die forums-software .ly und .png vertauscht. Strange!
« Letzte Änderung: Samstag, 10. November 2012, 23:33 von harm6 »

martinusbaum

  • Member
Re: Segno, Übungszeichen, Lautstärke nach einander
« Antwort #3 am: Sonntag, 11. November 2012, 17:27 »
Danke für die Hilfe.
Als Laie denke ich da
Riesenaufwand für ein Zeichen ...
Aber es funktioniert..
Dam
Danke

harm6

  • Member
Re: Segno, Übungszeichen, Lautstärke nach einander
« Antwort #4 am: Montag, 12. November 2012, 00:51 »
Zitat von: martinusbaum
Als Laie denke ich da
Riesenaufwand für ein Zeichen ...

Nun ja, der Aufwand entstand, weil ich einen Code entwickeln wollte, der allgemein, für jedes denkbare markup, in jeder denkbaren Achse, in jeder denkbaren horizentalen sowie vertikalen Ausrichtung, mit der Möglichkeit die RehearsalMark auf ihrem ersten Teil zu zentrieren entwickeln wollte, ohne die format-mark-Befehle festzuschreiben.
Und nicht weil ich ein einzelnes Zeichen definieren wollte.

Wenn man ein einziges Beispiel hard-coded angeben will, geht das natürlich sehr viel kürzer, wie Torsten es ja vorgemacht hat.

Tatsächlich denke ich darüber nach, ob mein Code auch so erweiterbar ist, daß er verschiedene RehearsalMarks vor und nach dem Zeilenumbruch ausgeben kann.
Falls mir das irgendwann gelingt, so wird es natürlich noch aufwendiger.

Der Hauptaufwand ist allerdings das Programmieren nicht das anwenden.
Die Definition(en) kann man ja in einem to-include-file speichern und dann nur noch aufrufen.


-Harm