lilypond-user
[Top][All Lists]
Advanced

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

Re: Ambitus with shape notes


From: Thomas Morley
Subject: Re: Ambitus with shape notes
Date: Fri, 25 Aug 2017 18:18:28 +0200

2017-08-12 12:05 GMT+02:00 Lukas-Fabian Moser <address@hidden>:
> Here is an improved version:
>
>
> \version "2.19.44"
>
> #(define (nth n l)
>   (if (or (> n (length l)) (< n 0))
>     (error "Index out of bounds.")
>     (if (eq? n 0)
>       (car l)
>       (nth (- n 1) (cdr l)))))
>
> #(define (scale-notehead scale tonic)
>    (lambda (grob)
>      (let ((mod-position (modulo (- (ly:grob-property grob 'staff-position)
> tonic)
>                                7)))
>      (nth mod-position scale)
>      )
>    )
>    )
>
> aiken = #(list 'do 're 'miMirror 'fa 'sol 'la 'ti)
> sacredHarp = #(list 'fa 'sol 'la 'fa 'sol 'la 'mi)
>
>
> % Standard definitions for \aikenHeads or \sacredHarpHeads may be
> % found in lilypond/usr/share/lilypond/current/ly/property-init.ly:
> %
> %
> % aikenHeads      = \set shapeNoteStyles = ##(do re miMirror fa sol la ti)
> % aikenHeadsMinor = \set shapeNoteStyles = ##(la ti do re miMirror fa sol)
> % funkHeads =  \set shapeNoteStyles = ##(doFunk reFunk miFunk faFunk solFunk
> laFunk tiFunk)
> % funkHeadsMinor =  \set shapeNoteStyles = ##(laFunk tiFunk doFunk reFunk
> miFunk faFunk solFunk)
> % sacredHarpHeads = \set shapeNoteStyles = ##(fa sol la fa sol la mi)
> % sacredHarpHeadsMinor = \set shapeNoteStyles = ##(la mi fa sol la fa sol)
> % southernHarmonyHeads =   \set shapeNoteStyles = ##(faThin sol laThin
> faThin sol laThin miThin)
> % southernHarmonyHeadsMinor =  \set shapeNoteStyles = ##(laThin miThin
> faThin sol laThin faThin sol)
> % walkerHeads =  \set shapeNoteStyles = ##(doWalker reWalker miWalker
> faWalker solFunk laWalker tiWalker)
> % walkerHeadsMinor =  \set shapeNoteStyles = ##(laWalker tiWalker doWalker
> reWalker miWalker faWalker solFunk)
>
>
> \layout {
>   \context {
>     \Voice
>     \consists "Ambitus_engraver"
>   }
>   \override AmbitusNoteHead.style = #(scale-notehead sacredHarp 2)
> }
>
> \relative {
>   \sacredHarpHeads
>   \clef violin
>   \key d \major
>   cis'4 d e fis g a b cis d
> }
>
> The \override AmbitusNoteHead.style = #(scale-notehead sacredHarp 2) now
> works in the following way: It expects a scale (I predefied sacredHarp and
> aiken) and a number which gives the position of the tonic root of your key
> in the staff - middle line is 0, and so on; I chose d major, and using
> violin clef, a d is on position 2 (two steps above the middle line).
>
> The reason it has to be this way is, that at the time the ambitus is
> printed, you know neither clef nor key signature; so it's easiest to specify
> the desired graphic position of the tonic note.
>
> Best
> Lukas

Hi,

just back from holidays, reading all the mails ...

The code above causes an error (programming error: must have stem dir
for note head) and the note-heads are wrongly rotated. See:

\layout {
  \context {
    \Voice
    \consists "Ambitus_engraver"
  }
  \override AmbitusNoteHead.style = #(scale-notehead sacredHarp 1)
}

\relative {
  \sacredHarpHeads
  \clef violin
  \key c \major
  cis'4 d e fis g a b cis d
}

So I come up with the code below.
It reads the tonic from the context as well as the
'shapeNoteStyles'-vector of note-head styles.
I didn't figure how to circumvent the error mentioned above while
setting 'style, so I recreated the stencil.

\version "2.19.64"

#(define (get-stencil font cands)
  (cond ((null? cands) point-stencil)
        ((ly:stencil-empty? (ly:font-get-glyph font (car cands)) X)
         (get-stencil font (cdr cands)))
        (else (ly:font-get-glyph font (car cands)))))

shapedAmbitusNoteHead =
\applyOutput Staff.AmbitusNoteHead
  #(lambda (grob ctx c)
     (let* ((tonic (ly:context-property ctx 'tonic))
            (tonic-pitch-notename (ly:pitch-notename tonic))
            (shape-note-styles (ly:context-property ctx 'shapeNoteStyles)))

       (if (vector? shape-note-styles)
           (ly:grob-set-property! grob 'before-line-breaking
             (lambda (grob)
               (let* ((staff-pos (ly:grob-property grob 'staff-position))
                      (note-head
                        (vector-ref
                          shape-note-styles
                          (modulo (- staff-pos tonic-pitch-notename 1) 7)))
                      (layout (ly:grob-layout grob))
                      (props (ly:grob-alist-chain grob))
                      (font (ly:paper-get-font layout props))
                      (note-head-candidates
                        (list
                          (format #f "noteheads.~a2~a"
                                     (if (> 0 staff-pos) "u" "d")
                                     note-head)
                          (format #f "noteheads.s2~a" note-head)
                          "noteheads.s2")))
               (ly:grob-set-property! grob 'stencil
                 (get-stencil font note-head-candidates))))))))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\layout {
  \context {
    \Voice
    \aikenHeads
    %\aikenHeadsMinor
    %\funkHeads
    %\funkHeadsMinor
    %\sacredHarpHeads
    %\sacredHarpHeadsMinor
    %\southernHarmonyHeads
    %\southernHarmonyHeadsMinor
    %\walkerHeads
    %\walkerHeadsMinor

    \consists "Ambitus_engraver"
  }
}

$@(map
  (lambda (p)
    #{
      \relative {
        \shapedAmbitusNoteHead
        \time 9/4
        \key $p \major
        cis'4 d e fis g a b cis d
      }
    #})
  (event-chord-pitches #{ c d e f g a b #}))





HTH,
  Harm



reply via email to

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