lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Repeating a section with different transpose


From: Thomas Morley
Subject: Re: Repeating a section with different transpose
Date: Sun, 12 Apr 2015 21:22:48 +0200

2015-04-12 20:40 GMT+02:00 Eljakim Schrijvers <address@hidden>:
> Super, that is great to see! Thank you so much.
>
> I prefer this over Python (which I normally program in) since this can
> easily be posted in lilybin.com.
>
> Thanks again,
>
> Eljakim



Hi,

sorry for dropping in that late.
Here my own highly automate approach.



\version "2.19.17"

%% LIMITATION:
%% can't distuingish between minor- and aeolian-scale, major- and ionian-scale

%% TODO
%% define and use an alist for the following lists
scales =
#(list major minor ionian locrian aeolian mixolydian lydian phrygian dorian)

scales-names =
#'(major minor ionian locrian aeolian mixolydian lydian phrygian dorian)

german-scale-names =
#'(Dur Moll Ionisch Lokrisch Äolisch Mixolydisch Lydisch Phrygisch Dorisch)

french-scale-names =
#'(majeur mineur ionien locrien éolien mixolydien lydien phrygien dorien)

%% procedures returning strings/markups for accidental and note-name
#(define (alteration->text-accidental-markup alteration)
  (make-smaller-markup
   (make-raise-markup
    (if (= alteration FLAT)
        0.3
        0.6)
    (make-musicglyph-markup
     (assoc-get alteration standard-alteration-glyph-name-alist "")))))

#(define (accidental->markup alteration)
  "Return accidental markup for @var{alteration}."
  (if (= alteration 0)
      (make-line-markup (list empty-markup))
      (make-line-markup
        (list
          (alteration->text-accidental-markup alteration)
          (make-hspace-markup 0.1)))))

#(define (note-name->markup pitch)
  "Return pitch-markup for @var{pitch}."
  (make-concat-markup
   (list
    (make-simple-markup
      (vector-ref #("C" "D" "E" "F" "G" "A" "B") (ly:pitch-notename pitch)))
    (accidental->markup (ly:pitch-alteration pitch)))))

#(define (note-name->german-string pitch)
  "Return string for @var{pitch}, using german note names."
  (define (pitch-alteration-semitones pitch)
   (inexact->exact (round (* (ly:pitch-alteration pitch) 2))))

  (let* ((name (ly:pitch-notename pitch))
         (alt-semitones  (pitch-alteration-semitones pitch))
         (n-a (if (equal? (cons name alt-semitones) '(6 . -1))
                  (cons 7 alt-semitones)
                  (cons name alt-semitones))))
   (string-append
       (vector-ref #("C" "D" "E" "F" "G" "A" "H" "B") (car n-a))
     (let ((alteration (/ (cdr n-a) 2)))
       (cond
          ((and (= alteration FLAT) (= (car n-a) 7))
            "")
          ((and (= alteration FLAT) (or (= (car n-a) 5) (= (car n-a) 2) ))
            "s")
          ((= alteration FLAT) "es")
          ((and (= alteration DOUBLE-FLAT) (or (= (car n-a) 5)(= (car n-a) 2)))
            "ses")
          ((= alteration DOUBLE-FLAT)
            "eses")
          ((= alteration SHARP)
            "is")
          ((= alteration DOUBLE-SHARP)
            "isis")
          (else ""))))))

#(define (note-name->french-string pitch)
  "Return string for @var{pitch}, using french note names."

  (let* ((name (ly:pitch-notename pitch))
         (alteration (ly:pitch-alteration pitch)))
    (string-append
        (vector-ref #("Do" "Ré" "Mi" "Fa" "Sol" "La" "Si") name)
        (cond
           ((= alteration FLAT) "-bémol")
           ((= alteration DOUBLE-FLAT) "-double bémol")
           ((= alteration SHARP) "-diése")
           ((= alteration DOUBLE-SHARP) "-double diése")
           (else "")))))

%% engraver setting instrumentName to a markup for the used KeySignature
annotate-key-engraver =
#(lambda (context)
 (let ((tonic '())
       (scale-name '())
       (german-scale-name '())
       (french-scale-name '())
       (annotate-key-tweak? #f))

  `((listeners
      (key-change-event
        .
        ,(lambda (engraver event)
          (let* ((context (ly:translator-context engraver))
                 (pitch-alist (ly:event-property event 'pitch-alist))
                 (tonic-pitch (ly:context-property context 'tonic))
                 (c0-pitch-list
                   (ly:transpose-key-alist pitch-alist
                        (ly:pitch-diff (ly:make-pitch 0 0 0) tonic-pitch)))
                 (pos-scales-from-right (length (member c0-pitch-list scales)))
                 (scale
                   (car (take-right scales-names pos-scales-from-right)))
                 (german-scale
                   (car (take-right german-scale-names pos-scales-from-right)))
                 (french-scale
                   (car (take-right french-scale-names pos-scales-from-right))))
            ;; clear the following variables before proceeding
            (set! tonic '())
            (set! scale-name '())
            (set! german-scale-name '())
            (set! french-scale-name '())

            ;; newly assign them
            (set! tonic (cons tonic-pitch tonic))
            (set! scale-name scale)
            (set! german-scale-name german-scale)
            (set! french-scale-name french-scale)))))
    (acknowledgers
       (system-start-text-interface
        . ,(lambda (engraver grob source-engraver)
             (let* ((german-root-name
                      (note-name->german-string (car tonic)))
                    (french-root-name
                      (note-name->french-string (car tonic)))
                    (english-root-name
                      (note-name->markup (car tonic))))
             (set! (ly:grob-property grob 'long-text)
               (format-key-info-markup
                 german-root-name german-scale-name
                 french-root-name french-scale-name
                 english-root-name scale-name)))))))))

%% the file-name
my-name =
#(ly:parser-output-name parser)

%% procedure to set score-headers
%% taken from
%% http://lists.gnu.org/archive/html/lilypond-user/2012-03/msg00097.html
#(define-public (set-score-headers! score header)
  (let ((scorehead (ly:score-header score)))
       ; if score has no header, create one
       (if (list? scorehead)
           (let ((mod (make-module)))
             (set! scorehead mod)
             (ly:score-set-header! score scorehead)))
       (for-each
         (lambda (p)
           (if (pair? p)
               (let ((key (car p))
                     (val (cdr p)))
                    (module-define! scorehead key val)))) header)))

%% the printing function
%% outputting scores derived from `music' transpose by the pitches from `m'
%% score-header can be specified by setting appropriate `header-props' or an
%% empty list
write-scores =
#(define-void-function (parser location m header-props music)
 (ly:music? list? ly:music?)
  (let ((score-list
          (reverse
            (map
              (lambda (pitch) #{ \transpose c $pitch $music #})
              (event-chord-pitches m)))))

 (ly:book-process
   (ly:make-book-part
     (map
       (lambda (score)
         (let ((new-score (ly:make-score score)))
           (set-score-headers! new-score header-props)
           new-score))
       score-list))
     $defaultpaper
     $defaultlayout
   my-name)))

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

%% a procedure to format the markup used for InstrumentName
#(define format-key-info-markup
   (lambda (root-1 scale-1 root-2 scale-2 root-3 scale-3)
     (markup
       #:column (
       #:bold
       #:concat (
           root-3
           " "
           (symbol->string scale-3))
       #:italic
       (format #f "~a ~a"
         root-2
         (symbol->string scale-2))
       #:italic
       (let ((german-strg
               (format #f "~a-~a"
                 root-1
                 (symbol->string scale-1))))
         (if (eq? scale-1 'Moll)
             (string-downcase german-strg)
             german-strg))))))


\paper {
  print-all-headers = ##t
  indent = 3.5 \cm
}

\layout {
  \context {
    %% the "Instrument_name_engraver" has to be inserted ofc
    \GregorianTranscriptionStaff
    \consists "Instrument_name_engraver"
    instrumentName = ""
    \consists #annotate-key-engraver
  }
}

%% definig the music
exercise = {
  \clef treble
  \key c \major
  \omit Staff.TimeSignature
  \relative c'
  {
    c8[ d] e[ f]
  }
  \bar ""
  \pageBreak
}

\write-scores
  %% pitches to transpose:
  { c cis d }
  %% score-header-settings:
  #'(
     (title . "TITLE")
     (subtitle . "SUBTITLE")
     (composer . "COMPOSER")
     (piece . "PIECE")
     ;; etc
    )
  %% the music
  \new GregorianTranscriptionStaff \exercise


Though, I've no clue how to automagically read out the used
KeySignature _and_ put the result in a header.


Nevertheless,

HTH,
  Harm



reply via email to

[Prev in Thread] Current Thread [Next in Thread]