Leitereigene Mehrklänge/score

Zur Navigation springen Zur Suche springen
\version "2.19.83"
\language "deutsch"
#(use-modules (ice-9 regex))
\include "Exceptions.ily"

#(define (pitches->chord plist)
   (make-music 'EventChord 'elements
     (if (list? plist)
         (map (lambda (p)
                (make-music
                 'NoteEvent 'duration (ly:make-duration 0)
                 'pitch p))
           plist)
         (make-music
          'NoteEvent 'duration (ly:make-duration 0)
          'pitch plist)
         )))

%% create all n-th chords from scale
%% actually we staple every other pitch from the-scale
%% until we reach n

%% create chords with arbitraty intervals from the scale
%% input: scale
%% list: the distances of the notes, 3=terz, 4=quart ...

#(define (stacked-intervals the-scale list-or-number-or-pair)
   ;; the-scale: music from which the pitchlist is constructed
   ;; usually a scale, but could be any music
   ;; duplicate pitches are removed and sorting according to pitch height is done
   ;; list-or-number-or-pair: tells the programm which intervals to produce
   ;; list: a list of chords, 3=third, 4=forth etc. '(2 4) creates a quart-sext chord
   ;; pair: '(a . b)  a: how many notes the chord contains, b: the interval, 3=third, 4=forth
   ;; number: terzes are stapled, 3=triad, 4=tetrads, 5=pentachord etc
   ;; actually the program does not much counting
   ;; a list of intervals is created by picking notes in the order they appear
   ;; in the scale leaving gaps defined by the list
   (let* ((scpi (music-pitches the-scale))
          (pili (sort
                 (delete-duplicates scpi) ly:pitch<?))
          (m (length pili))
          (elist (cond
                  ((list? list-or-number-or-pair)
                   ;; we need to add an element to the list
                   ;; otherwise the last element of the list would not appear
                   ;; in the result
                   (append list-or-number-or-pair '(1)))
                  ((pair? list-or-number-or-pair)
                   ;; car: number of notes
                   ;; cdr: distance, 3=third, 4=forth etc.
                   (make-list  (car list-or-number-or-pair) (cdr list-or-number-or-pair)))
                  ((number? list-or-number-or-pair)
                   ;; standard definition: chord consists of thirds
                   (make-list list-or-number-or-pair 3))))
          (n (length elist)))
     (map
      (lambda (w)
        (let ((u 0))
          (map
           (lambda (x)
             (let* ((y (modulo (+ u w) m))
                    (q (quotient (+ u w) m))
                    (z (list-ref pili y))
                    (a (ly:pitch-alteration z))
                    (o (ly:pitch-octave z))
                    (n (ly:pitch-notename z))
                    (p (ly:make-pitch (+ o q) n a)))
               (set! u (+ u (list-ref elist x) -1))
               p))
           (iota n))))
      (iota m))))

CreateIntervals=
#(define-music-function (the-scale pair-list-number)(ly:music? scheme?)
   ;; creates the pure music without chordnames and other staff
   (make-sequential-music
    (map (lambda(x) (pitches->chord x))
      (stacked-intervals the-scale pair-list-number))))

dynamictext =
#(define-event-function (text) (markup?)
   (if (string? text)
       (let* ((underscores-replaced
               (string-map
                (lambda (x) (if (eq? x #\_) #\space x))
                text))
              (split-text (string-split underscores-replaced #\space))
              (formatted (map
                          (lambda (word)
                            (if (string-match "^[mrzfps]*$" word)
                                (markup #:dynamic word)
                                (markup #:normal-text #:italic word)))
                          split-text)))
         #{
           #(make-dynamic-script (make-line-markup formatted))
         #})
       ;; user provided a full-blown markup, so we don't mess with it:
       #{
         #(make-dynamic-script (markup #:normal-text text))
       #}))

#(define (pitch-alteration-semitones pitch)
   (inexact->exact (round (* (ly:pitch-alteration pitch) 2))))

#(define (conditional-string-downcase str condition)
   (if condition
       (string-downcase str)
       str))

%% Notenname als Markup mit deutschen Notennamen
#(define (note-name->my-markup pitch lowercase?)
   (let* ((name (ly:pitch-notename pitch))
          (alt-semitones (pitch-alteration-semitones pitch))
          (n-a (if (member (cons name alt-semitones) `((6 . -1) (6 . -2)))
                   (cons 7 (+ 1 alt-semitones))
                   (cons name alt-semitones))))
     (make-line-markup
      ;(make-simple-markup
      (list
       (string-append
        (conditional-string-downcase
         (list-ref '("C" "D" "E" "F" "G" "A" "H" "B") (car n-a))
         lowercase?)
        (if (or (equal? (car n-a) 2) (equal? (car n-a) 5))
            (list-ref '( "ses" "s" "" "is" "isis") (+ 2 (cdr n-a)))
            (list-ref '("eses" "es" "" "is" "isis") (+ 2 (cdr n-a)))))))))

DurStufen = {
  s1\dynamictext "I"  s\dynamictext "ii"
  s\dynamictext "iii"  s\dynamictext "IV"
  s\dynamictext "V"  s\dynamictext "vi"
  s\dynamictext "vii"
}

Stufen = {
  s1-"I" s1-"ii" s1-"iii" s-"IV" s-"V" s-"vi" s-"vii"
}

drei =
#(define-music-function (p leiter leiter1 leiter2)
   (ly:pitch? ly:music? ly:music? ly:music?)
   (let* ((was (ly:pitch-notename p))
          (o1 (cond
               ((equal? was 2) 0) ; e
               ((equal? was 3) 0) ; f
               ((equal? was 4) 0) ; g
               (else -1)))
          (o2 (if (equal? was 4) -1 -1))
          (u1 (if (equal? was 4) 1 1))
          (u2 (cond
               ((equal? was 2) 0) ; e
               ((equal? was 3) 1) ; f
               ((equal? was 4) 1) ; g
               (else 0)))
          )
     (display was)
     #{
       <<
         \new PianoStaff
         \with {
           instrumentName = \markup \fontsize #2 \override #'(font-features . ("smcp")) "Tonleiter "
         }
         \new Voice \transpose c $p { \key c \major $leiter }
         \new Dynamics \DurStufen
         \new PianoStaff
         \with {
           instrumentName = \markup \fontsize #2 \override #'(font-features . ("smcp")) "Grundstellung "
         }
         <<
           \new Staff \transpose #(ly:make-pitch -1 0) $p { \key c \major \CreateIntervals $leiter #3 }
           \new ChordNames \transpose c $p \CreateIntervals $leiter #3
           \new Staff { \clef bass \transpose #(ly:make-pitch 1 0) $p { \key c \major \CreateIntervals $leiter #3 } }
           \new Dynamics \DurStufen
         >>
         \new PianoStaff
         \with {
           instrumentName = \markup \fontsize #2 \override #'(font-features . ("smcp")) "1. Umkehrung "
         }
         <<
           \new Staff \transpose #(ly:make-pitch o1 0) $p { \key c \major \CreateIntervals $leiter1 #'(3 4) }
           \new ChordNames \transpose c $p \CreateIntervals $leiter #3
           \new Staff { \clef bass \transpose #(ly:make-pitch u1 0) $p { \key c \major \CreateIntervals $leiter1 #'(3 4) } }
           \new Dynamics \DurStufen
         >>
         \new PianoStaff
         \with {
           instrumentName = \markup \fontsize #2 \override #'(font-features . ("smcp")) "2. Umkehrung "
         }
         <<
           \new Staff \transpose #(ly:make-pitch o2 0) $p { \key c \major \CreateIntervals $leiter2 #'(4 3) }
           \new ChordNames \transpose c $p \CreateIntervals $leiter #3
           \new Staff { \clef bass \transpose #(ly:make-pitch u2 0) $p { \key c \major \CreateIntervals $leiter2 #'(4 3) } }
           \new Dynamics \DurStufen
         >>
       >>
     #}
     ))

dreik =
#(define-scheme-function (p leiter leiter1 leiter2)
   (ly:pitch? ly:music? ly:music? ly:music?)
   (scorify-music (drei p leiter leiter1 leiter2)))

vier =
#(define-music-function (p leiter l1 l2 l3)
   (ly:pitch? ly:music? ly:music? ly:music? ly:music?)
   (let* ((was (ly:pitch-notename p))
          (o1 (cond
               ((equal? was 2) 0) ; e
               ((equal? was 3) 0) ; f
               ((equal? was 4) 0) ; g
               (else -1)))
          (o2 (if (equal? was 4) -1 -1))
          (o3 -1)
          (u1 (if (equal? was 4) 1 1))
          (u2 (if (equal? was 4) 1 0))
          (u3 (cond
               ((equal? was 2) 1) ; e
               ((equal? was 3) 1) ; f
               ((equal? was 4) 1) ; g
               (else 0)))
          )
     #{
       {
         <<
           \new PianoStaff
           \with {
             instrumentName = \markup \fontsize #2 \override #'(font-features . ("smcp")) "Tonleiter "
           }
           {
             <<
               \new Voice \transpose c $p { \key c \major $leiter }
               \context Voice \Stufen
             >>
           }
           \new ChordNames \transpose c $p \CreateIntervals $leiter #4
           \new PianoStaff
           \with {
             instrumentName = \markup \fontsize #2 \override #'(font-features . ("smcp")) "Grundstellung "
           }
           {
             <<
               \new Staff \transpose c $p { \key c \major \CreateIntervals $leiter #4 }
               \context Voice \Stufen
               \new ChordNames \transpose c $p \CreateIntervals $leiter #4
               \new Staff { \clef bass \key $p \major \transpose c'' $p \CreateIntervals $leiter #4 }
             >>
           }
           \new PianoStaff
           \with {
             instrumentName = \markup \fontsize #2 \override #'(font-features . ("smcp")) "1. Umkehrung "
           }
           {
             <<
               \new Staff \transpose #(ly:make-pitch o1 0) $p { \key c \major \CreateIntervals $l1 #'( 3 3 2) }
               \context Voice \Stufen
               \new ChordNames \transpose c $p \CreateIntervals $leiter #4
               \new Staff { \clef bass \transpose #(ly:make-pitch u1 0) $p { \key c \major\CreateIntervals $l1 #'( 3 3 2) } }
             >>
           }
           \new PianoStaff
           \with {
             instrumentName = \markup \fontsize #2 \override #'(font-features . ("smcp")) "2. Umkehrung "
           }
           {
             <<
               \new Staff \transpose #(ly:make-pitch o2 0) $p { \key c \major \CreateIntervals $l2 #'( 3 2 3) }
               \context Voice \Stufen
               \new ChordNames \transpose c $p \CreateIntervals $leiter #4
               \new Staff { \clef bass \transpose #(ly:make-pitch u2 0) $p { \key c \major\CreateIntervals $l2 #'( 3 2 3) } }
             >>
           }
           \new PianoStaff
           \with {
             instrumentName = \markup \fontsize #2 \override #'(font-features . ("smcp")) "3. Umkehrung "
           }
           <<
             \new Staff \transpose #(ly:make-pitch o3 0) $p { \key c \major \CreateIntervals $l3 #'( 2 3 3) }
             \context Voice \Stufen
             \new ChordNames \transpose c $p \CreateIntervals $leiter #4
             \new Staff { \clef bass \transpose #(ly:make-pitch u3 0) $p { \key c \major \CreateIntervals $l3 #'( 2 3 3) } }
           >>
         >>
       }
     #}
     ))

vierk =
#(define-scheme-function (p leiter leiter1 leiter2 leiter3)
   (ly:pitch? ly:music? ly:music? ly:music? ly:music?)
   (scorify-music (vier p leiter leiter1 leiter2 leiter3)))

funf =
#(define-music-function (p leiter l1 l2 l3 l4)
   (ly:pitch? ly:music? ly:music? ly:music? ly:music? ly:music?)
   (let* ((was (ly:pitch-notename p))
          (o1 (cond
               ((equal? was 2) 0) ; e
               ((equal? was 3) 0) ; f
               ((equal? was 4) 0) ; g
               (else -1)))
          (o2 (if (equal? was 4) -1 -1))
          (o3 -1)
          (o4 -1)
          (u1 (if (equal? was 4) 1 1))
          (u2 (if (equal? was 4) 1 (if (equal? was 2) 1 0)))
          (u3 (cond
               ((equal? was 2) 1)  ; e
               ((equal? was 3) 1)  ; f
               ((equal? was 4) 1) ; g
               (else 0)))
          (u4 (cond
               ((equal? was 2) 1)  ; e
               ((equal? was 3) 1)  ; f
               ((equal? was 4) 1) ; g
               (else 1)))
          )
     #{
       {
         <<
           \new PianoStaff
           \with {
             instrumentName = \markup \fontsize #2 \override #'(font-features . ("smcp")) "Tonleiter "
           }
           {
             <<
               \new Voice \transpose c $p { \key c \major $leiter }
               \context Voice \Stufen
             >>
           }
           \new ChordNames \transpose c $p \CreateIntervals $leiter #5
           \new PianoStaff
           \with {
             instrumentName = \markup \fontsize #2 \override #'(font-features . ("smcp")) "Grundstellung "
           }
           {
             <<
               \new Staff \new Voice \transpose c $p { \key c \major \CreateIntervals $leiter #5 }
               \context Voice \Stufen
               \new ChordNames \transpose c $p \CreateIntervals $leiter #5
               \new Staff \new Voice { \clef bass \key $p \major \transpose c'' $p \CreateIntervals $leiter #5 }
             >>
           }
           \new PianoStaff
           \with {
             instrumentName = \markup \fontsize #2 \override #'(font-features . ("smcp")) "1. Umkehrung "
           }
           {
             <<
               \new Staff \new Voice \transpose #(ly:make-pitch o1 0) $p { \key c \major \CreateIntervals $l1 #'( 3 3 3 2) }
               \context Voice \Stufen
               \new ChordNames \transpose c $p \CreateIntervals $leiter #5
               \new Staff { \clef bass \transpose #(ly:make-pitch u1 0) $p { \key c \major\CreateIntervals $l1 #'( 3 3 3 2) } }
             >>
           }
           \new PianoStaff
           \with {
             instrumentName = \markup \fontsize #2 \override #'(font-features . ("smcp")) "2. Umkehrung "
           }
           {
             <<
               \new Staff \transpose #(ly:make-pitch o2 0) $p { \key c \major \CreateIntervals $l2 #'( 3 3 2 3) }
               \context Voice \Stufen
               \new ChordNames \transpose c $p \CreateIntervals $leiter #5
               \new Staff { \clef bass \transpose #(ly:make-pitch u2 0) $p { \key c \major\CreateIntervals $l2 #'( 3 3 2 3) } }
             >>
           }
           \new PianoStaff
           \with {
             instrumentName = \markup \fontsize #2 \override #'(font-features . ("smcp")) "3. Umkehrung "
           }
           <<
             \new Staff \transpose #(ly:make-pitch o3 0) $p { \key c \major \CreateIntervals $l3 #'( 3 2 3 3) }
             \context Voice \Stufen
             \new ChordNames \transpose c $p \CreateIntervals $leiter #5
             \new Staff { \clef bass \transpose #(ly:make-pitch u3 0) $p { \key c \major \CreateIntervals $l3 #'( 3 2 3 3) } }
           >>
           \new PianoStaff
           \with {
             instrumentName = \markup \fontsize #2 \override #'(font-features . ("smcp")) "4. Umkehrung "
           }
           <<
             \new Staff \transpose #(ly:make-pitch o4 0) $p { \key c \major \CreateIntervals $l4 #'( 2 3 3 4) }
             \context Voice \Stufen
             \new ChordNames \transpose c $p \CreateIntervals $leiter #5
             \new Staff { \clef bass \transpose #(ly:make-pitch u4 0) $p { \key c \major \CreateIntervals $l4 #'( 2 3 3 3) } }
           >>
         >>
       }
     #}
     ))

funfk =
#(define-scheme-function (p leiter leiter1 leiter2 leiter3 leiter4)
   (ly:pitch? ly:music? ly:music? ly:music? ly:music? ly:music?)
   (scorify-music (funf p leiter leiter1 leiter2 leiter3 leiter4)))

%% hier kommen die Routinen für die Erzeugung der Ausgabe

foo = \paper { ragged-right = ##f }

#(define (make-book-parts-with-top-markup markup scores)
   (let* ((output-def (ly:make-output-def))
          (raw-paper
           (begin
            (ly:output-def-set-variable! output-def 'is-paper #t)
            output-def))
          (bp  #{ \bookpart { $raw-paper } #}))

     (for-each
      (lambda (score) (ly:book-add-score! bp score))
      (cons (list markup) scores))

     bp))

#(define (fill-book-part-paper! bookpart key-value-alist)
   (for-each
    (lambda (key-value)
      (ly:output-def-set-variable!
       (ly:book-paper bookpart) (car key-value) (cdr key-value)))
    key-value-alist))


#(define-markup-command (my-header layout props p text1 text2) (ly:pitch? string? string?)
   (interpret-markup layout props
     #{ \markup \fill-line \override #'(font-features . ("smcp"))
        \override #'(box-padding . 1)
        \override #'(thickness . 2) \override #'(font-size . 4)
        { \null \rounded-box \concat { $text1 #(note-name->my-markup p #f) $text2 } \null }
     #}))

#(define (add-bookparts-to-toplevel-bookparts p leiter leiter1 leiter2 leiter3 leiter4)
   (let* ((bk (ly:make-book $defaultpaper $defaultheader '()))
          (my-funfklang #{ \markup \my-header ##{ $p #} "Leitereigene Fünfklänge " "-Dur" #} )
          (my-dreiklang #{ \markup \my-header ##{ $p #} "Leitereigene Dreiklänge " "-Dur" #} )
          (my-vierklang #{ \markup \my-header ##{ $p #} "Leitereigene Vierklänge " "-Dur" #} )
          (paper-kadenzen #{ \paper { line-width = 160 ragged-right = ##f } #})
          (bk-parts
           (list
            (make-book-parts-with-top-markup ; leere Seite einfügen
             ""
             '())
            (make-book-parts-with-top-markup
             my-dreiklang
             (list (dreik p leiter leiter1 leiter2)))
            (make-book-parts-with-top-markup
             my-vierklang
             (list (vierk p leiter leiter1 leiter2 leiter3)))
            (make-book-parts-with-top-markup
             my-funfklang
             (list (funfk p leiter leiter1 leiter2 leiter3 leiter4)))
            )))
     (for-each
      (lambda (book-part key-values)
        (fill-book-part-paper! book-part key-values))
      bk-parts
      (map
       (lambda (paper)
         (ly:module->alist (ly:output-def-scope paper)))
       (list paper-kadenzen paper-kadenzen paper-kadenzen)))
     (for-each
      (lambda (book-part)
        (ly:parser-define! 'toplevel-bookparts
          (cons book-part (ly:parser-lookup 'toplevel-bookparts))))
      bk-parts)
     ))

myBookparts =
#(define-void-function (mus leiter leiter1 leiter2 leiter3 leiter4)
   (ly:music? ly:music? ly:music? ly:music? ly:music? ly:music?)
   (let ((pitches (music-pitches mus)))
     (for-each
      (lambda (pitch) (add-bookparts-to-toplevel-bookparts pitch leiter leiter1 leiter2 leiter3 leiter4))
      pitches)))

leiter  = \relative c' { c1 d e f g a h }
leiters = \relative c' { e1 f g a h c d }
leitert = \relative c' { g1 a h c d e f }
leiterq = \relative c' { h1 c d e f g a }
leiterd = \relative c' { d1 e f g a h c }

\paper {
  markup-system-spacing.minimum-distance = #5
  markup-markup-spacing.minimum-distance = #5
  score-system-spacing.minimum-distance = #10
  top-markup-spacing.minimum-distance = #10
  markup-system-spacing.basic-distance = 12
  oddHeaderMarkup = ##f
  evenHeaderMarkup = #oddHeaderMarkup
  oddFooterMarkup = #oddHeaderMarkup
  evenFooterMarkup = #oddHeaderMarkup
  ragged-right = ##f
  ragged-last = ##f
  ragged-bottom = ##t
  ragged-last-bottom = ##t
  line-width = 150\mm
}

\layout {

  \context {
    \Staff
    \remove "Time_signature_engraver"
  }

  \context {
    \PianoStaff
    \override SystemStartBrace.collapse-height = #1
  }

  \context {
    \Score
    \override BarNumber.stencil = ##f
    \override KeyCancellation.break-visibility = #all-invisible
    \override StaffGrouper.staffgroup-staff-spacing.basic-distance = #15
    \override StaffGrouper.staffgroup-staff-spacing.padding = #4
    \override VerticalAxisGroup.nonstaff-unrelatedstaff-spacing.padding = #1
    \override VerticalAxisGroup.nonstaff-unrelatedstaff-spacing.minimum-distance = #3
    %\remove "Default_bar_line_engraver"
    automaticBars =##f
    \override SpacingSpanner.strict-note-spacing = ##t
  }

  \context {
    \ChordNames
    \alias ChordNames
    \override ChordName.self-alignment-X = #LEFT
    chordNameLowercaseMinor = ##f
    \override Rest.stencil = ##f
    chordNoteNamer = #(chord-name->german-markup #f)
    chordChanges = ##f
    chordNameLowercaseMinor = ##f
    chordNameExceptions = #chExceptions
    chordRootNamer = #germanChords
    majorSevenSymbol = \markup { maj7 }
    \override ChordName.font-name = #"Arial Narrow"
    \override ChordName.layer = #2
    \override ChordName.extra-spacing-width = #'(+inf.0 . -inf.0)
    \override ChordName.font-size = #1
    noChordSymbol = ##f
    \override VerticalAxisGroup.staff-affinity = #UP
    \override VerticalAxisGroup.nonstaff-relatedstaff-spacing.padding = #1
  }

  \context {
    \Dynamics
    \override VerticalAxisGroup.staff-affinity = #UP
    \override VerticalAxisGroup.nonstaff-relatedstaff-spacing.padding = #1
  }
}