Autor Thema: alternative Tonart  (Gelesen 2103 mal)

DieTuba

  • Member
alternative Tonart
« am: Freitag, 12. September 2014, 17:35 »
Hallo,
ich komme wieder einmal nicht weiter: In den Begleitheften zu Kirchenliedern sind die einige Stücke oft mit einer alternative Tonart versehen. Leider kann ich keinen Bildausschnitt machen, daher hänge ich komplette Seite des Heftes als PDF zur Veranschaulichung an. Ich finde keinen Hinweis, wie das mit Lilypond bewerkstelligen kann.

Ich danke schon mal im Voraus für die Hilfe!

DieTuba

harm6

  • Member
Re: alternative Tonart
« Antwort #1 am: Freitag, 12. September 2014, 23:14 »
Hallo,

versuch mal:

\version "2.18.0"

alternativeKey =
#(define-music-function (parser location p-1 p-2 scale-def)
     (ly:pitch? ly:pitch? list?)
#{
  \override Staff.KeySignature #'stencil =
   #(lambda (grob)
      (let* ((staff-space (ly:staff-symbol-staff-space grob))
             (line-thickness (ly:staff-symbol-line-thickness grob))
             (th line-thickness)
             (default-stil (ly:key-signature-interface::print grob))
             ;; To avoid programming error @code{(markup #:null)} is returned if
             ;; the scale would not result in a printed KeySignature.
             ;; TODO: add the other scales: ionian, locrian etc
             (stil-to-add
               (grob-interpret-markup grob
                 (if (or (and (= (ly:pitch-notename p-2) 5)
                              (eq? scale-def minor))
                         (and (= (ly:pitch-notename p-2) 0)
                              (eq? scale-def major)))
                 (markup #:null)
                 #{
                   \markup
                     \score {
                       { \key $p-2 $scale-def }
                       \layout {
                         \override Staff.TimeSignature #'stencil = ##f
                         \override Staff.Clef #'stencil = ##f
                         \override Staff.StaffSymbol #'line-count = #0
                         indent = 0
                       }
                   }
                 #})
                 ))
             (stil-to-add-x-ext (ly:stencil-extent stil-to-add X))
             (stil-to-add-y-ext (ly:stencil-extent stil-to-add Y)))
    (if (< 0 (interval-length stil-to-add-x-ext))
        (if (or (and (= (ly:pitch-notename p-1) 5)
                     (eq? scale-def minor))
                (and (= (ly:pitch-notename p-1) 0)
                     (eq? scale-def major)))
            (bracketify-stencil
                      (ly:make-stencil
                        (ly:stencil-expr stil-to-add)
                        ;; left bracket is to far away
                        ;; trimmed a little
                        (cons
                           (+ (car stil-to-add-x-ext) (* 0.7 staff-space) )
                           (cdr stil-to-add-x-ext))
                        ;; adjusting the top and bottom ending of the bracket
                        (cons
                           (+ (car stil-to-add-y-ext) (* 0.2 staff-space))
                           (- (cdr stil-to-add-y-ext) (* 0.5 staff-space))))
                      Y th (* 2.5 th) th)
            (ly:stencil-combine-at-edge
              default-stil
              X
              RIGHT
              (bracketify-stencil
                (ly:make-stencil
                  (ly:stencil-expr stil-to-add)
                  ;; left bracket is to far away
                  ;; trimmed a little
                  (cons
                     (+ (car stil-to-add-x-ext) (* 0.7 staff-space) )
                     (cdr stil-to-add-x-ext))
                  ;; adjusting the top and bottom ending of the bracket
                  (cons
                     (+ (car stil-to-add-y-ext) (* 0.2 staff-space))
                     (- (cdr stil-to-add-y-ext) (* 0.5 staff-space))))
                Y th (* 2.5 th) th)
                1))
      default-stil)))
         
  \key $p-1 $scale-def
#})

%%%%%%%%%%%%%%
% EXAMPLES
%%%%%%%%%%%%%%

\relative c' {
\alternativeKey c f \major
c1
\alternativeKey b c \major
c
\alternativeKey e ees \major
c
\alternativeKey a aes \major
c
\alternativeKey d des \major
c
\alternativeKey g ges \major
c
\alternativeKey c ces \major
c
\alternativeKey ges g \major
c1
\alternativeKey des d \major
c
        \alternativeKey aes a \major
        c
\alternativeKey ees e \major
c
\alternativeKey bes b \major
c
\alternativeKey f fis \major
c
\alternativeKey ces cis \major
c
}

HTH,
  Harm

DieTuba

  • Member
Re: alternative Tonart
« Antwort #2 am: Samstag, 13. September 2014, 10:45 »
Hallo, Harm,
herzlichen Dank für die Hilfe! Das ging schneller als erwartet.
Eine Frage hätte ich allerdings noch: Kann man anstelle der eckilgen Klammern auch runde Klammern setzen? Oder ist dazu der aufwand zu groß?

DieTuba
« Letzte Änderung: Samstag, 13. September 2014, 10:47 von DieTuba »

harm6

  • Member
Re: alternative Tonart
« Antwort #3 am: Samstag, 13. September 2014, 11:12 »
Ich hab' im Moment das Problem, daß mein Computer kaputt ist. Da ich momentan als Gast auf einem anderen System arbeite, weiß ich nicht wann ich Gelegenheit habe den Code noch mal zu bearbeiten.
Den geposteten Code mit der eckigen Klammer hatte ich schon vor einiger Zeit geschrieben und brauchte ihn nur von einer externen Festplatte zu kopieren. ;)

Allerdings finde ich die eckige Klammer auch viel geeigneter für diesen Zweck, imho.
Ich schau aber mal rein sobald ich es ermöglichen kann ...

Gruß,
  Harm

DieTuba

  • Member
Re: alternative Tonart
« Antwort #4 am: Samstag, 13. September 2014, 15:40 »
Alles klar, die eckilgen Klammern funktionieren natürlich. Ich möchte nur möglichst nahe am Original bleiben mit dem Notensatz. Das Ganze ist aber sowieso nicht eilig, sondern eher eine längerfristiges Projekt.
Also, nochmals vielen Dank unf hoffentlich arbeitet Dein Rechner bald wieder!

DieTuba

harm6

  • Member
Re: alternative Tonart
« Antwort #5 am: Freitag, 19. September 2014, 01:49 »
Hallo,

ich hab den Code noch mal überarbeitet.
Das ganze soll ja auch für verschiedene Schlüssel machbar sein. Funktioniert allerdings nicht automatisch :(
Ein Problem bleibt:
Falls Du z.B. a-moll und as-moll angeben willst gibts Probleme.

Für weitere Erklärungen bin ich momentan zu müde. Schau mal, ob Du mit dem Code klar kommst.

\version "2.19.13"

#(define (condition-not-to-print scale-def)
  (lambda (p)
    (and (= (ly:pitch-alteration p) 0) 
         (or (and (= (ly:pitch-notename p) 0)
                     (or (eq? scale-def major)
                         (eq? scale-def ionian)))
             (and (= (ly:pitch-notename p) 1)
                     (eq? scale-def dorian))
             (and (= (ly:pitch-notename p) 2)
                     (eq? scale-def phrygian))
             (and (= (ly:pitch-notename p) 3)
                     (eq? scale-def lydian))
             (and (= (ly:pitch-notename p) 4)
                     (eq? scale-def mixolydian))
             (and (= (ly:pitch-notename p) 5)
                  (or (eq? scale-def minor)
                      (eq? scale-def aeolian)))
             (and (= (ly:pitch-notename p) 6)
                     (eq? scale-def locrian))))))
                     
#(define ((print-key-sig-markup which-clef pitch scale-def) grob)
    (let* ((staff-space (ly:staff-symbol-staff-space grob))
           (th (ly:staff-symbol-line-thickness grob))
           (default-stil (ly:key-signature-interface::print grob))
           (stil-to-add
             (grob-interpret-markup grob
               #{
                 \markup
                   \score {
                     {
                       \key $pitch $scale-def
                       \clef $(symbol->string (car which-clef))
                     }
                     \layout {
                       \omit Staff.TimeSignature
                       \omit Staff.Clef
                       \override Staff.StaffSymbol #'line-count = #0
                       indent = 0
                     }
                 }
               #}))
           (stil-to-add-x-ext (ly:stencil-extent stil-to-add X))
           (stil-to-add-y-ext (ly:stencil-extent stil-to-add Y))
           (final-stil
             (ly:make-stencil
               (ly:stencil-expr stil-to-add)
               ;; left bracket will be too far away,
               ;; trimmed a little.
               ;; values are my choice
               (cons
                  (+ (car stil-to-add-x-ext) (* 0.7 staff-space) )
                  (cdr stil-to-add-x-ext))
               ;; adjusting the top and bottom ending for the bracket.
               ;; values are my choice
               (cons
                  (+ (car stil-to-add-y-ext) (* 0.2 staff-space))
                  (- (cdr stil-to-add-y-ext) (* 0.5 staff-space))))))
       final-stil))
                 
#(define
  (print-second-key-sig which-clef bracket-or-parenthesis pitch scale-def)
  (lambda (grob)
    (let* ((th (ly:staff-symbol-line-thickness grob))
           (default-stil (ly:key-signature-interface::print grob))
           (final-stil ((print-key-sig-markup which-clef pitch scale-def) grob))
           (stil-to-add-x-ext (ly:stencil-extent final-stil X)))
           
     (if (< 0 (interval-length stil-to-add-x-ext)) 
         (let* ((bracketified-stencil
                  (bracketify-stencil
                     final-stil
                     ;; values are my choice:
                     Y th (* 2.5 th) th))
                (parenthesized-stencil
                  (parenthesize-stencil
                     final-stil
                     ;; values are my choice:
                     (/ th 2) (* 4 th) 0 (* 2 th)))
                (which-stil
                  (cond ((equal? bracket-or-parenthesis "bracket")
                              bracketified-stencil)
                        ((equal? bracket-or-parenthesis "parenthesis")
                         parenthesized-stencil)
                        (else
                          (begin
                            (ly:warning
             "\tNeither \"bracket\" nor \"parenthesis\", typo? Ignoring second")
                            point-stencil)))))
                 (ly:stencil-combine-at-edge
                   default-stil
                   X
                   RIGHT
                   which-stil
                   1)) 
         default-stil))))
         
alternativeKey =
#(define-music-function (parser location clef b-or-p p-1 p-2 scale)
    ((symbol-list-or-symbol? '(treble))
     (string? "bracket")
     ly:pitch?
     ly:pitch?
     list?)
"
 Adds a second KeySignature, bracketified or parenthesized.
"
#{
  \key $p-1 $scale
  \override Staff.KeySignature #'stencil =
   #(print-second-key-sig clef b-or-p p-2 scale)
#})

%% `double-key' offers the possibility to predefine clef and bracket/parenthesis
%% in a separat definition, delaying the setting of the pitches and the scale
double-key =
#(define-scheme-function (parser location clef b-or-p)
    (symbol-list-or-symbol? string?)
  (define-music-function (parser location p-1 p-2 scale)
       (ly:pitch? ly:pitch? list?)
  #{
    \key $p-1 $scale
    \override Staff.KeySignature #'stencil =
     #(print-second-key-sig clef b-or-p p-2 scale)
           
  #}))

%% Example
my-double-key = \double-key soprano parenthesis

%%%%%%%%%%%%%%
% EXAMPLES
%%%%%%%%%%%%%%
%%{
\relative c' {
\omit Staff.KeyCancellation
%% using default-arguments: treble-clef and bracket
\alternativeKey c f \major
c1
\alternativeKey treble  parenthesis b c \major
c
\clef soprano
%% my-double-key is predefined to use soprano-clef and parenthesis
\my-double-key e ees \major
c
\clef treble
\alternativeKey treble  parenthesis a aes \major
c
\alternativeKey treble  parenthesis d des \major
c
\alternativeKey treble  parenthesis g ges \major
c
\alternativeKey treble  bracket c ces \major
c
\alternativeKey treble  parenthesis ges g \major
c1
\alternativeKey treble  parenthesis des d \major
c
        \alternativeKey treble  parenthesis aes a \major
        c
\alternativeKey treble  parenthesis ees e \major
c
\alternativeKey treble  parenthesis bes b \major
c
\alternativeKey treble  parenthesis f fis \major
c
\clef bass
\alternativeKey bass  bracket ces cis \major
c
\break
\clef treble
%% works with all scale-definitions, example: \phrygian
\alternativeKey a b \phrygian
a
}
%}

%{
Limitations:

If the initial KeySignature causes no printed accidentals
(c-major, a-minor, etc), LilyPond does not create this grob for the next
line(s).

Therefore the alternativeKey-function and their derivates can't find a stencil
to do some additions.

Example:
%}

\relative c' {
\alternativeKey c ces \major
c1
\break
%% no Terminal-output!!
\once \override Staff.KeySignature.after-line-breaking =
  #(lambda (grob)
    (display "\n\t")
    (display grob))
c1
}

HTH,
  Harm

DieTuba

  • Member
Re: alternative Tonart
« Antwort #6 am: Samstag, 20. September 2014, 15:58 »
Danke für die Hilfe, das sieht jetzt aus wie im Original. Und bisher hatte ich auch noch keine Tonarten, bei denen ein Problem auftritt.

Ich danke recht herzlich für die Hilfe!

DieTuba