Hi all,

FWIW, here's something which tabulates the notes used in an excerpt and
presents them in ascending order.

I think this might be useful in handbell music (which the example assuredly
is not).

Any suggestions for improving this are welcome.

--David
\version "2.18"

#(define (get-pitch elt)
   (ly:music-property elt 'pitch))

#(define (extract-pitches lst result) 
   (cond
    ((null? lst) result)
    ((ly:pitch? (get-pitch (car lst)))
     (set! result (append result (list (get-pitch (car lst)))))
     (extract-pitches (cdr lst) result))
    ((ly:music-property (car lst) 'elements)
     (append
      (extract-pitches (ly:music-property (car lst) 'elements) result)
      (extract-pitches (cdr lst) '())))
    (else (extract-pitches (cdr lst) result))))

extractPitches =
#(define-scheme-function
  (parser location lst)
  (ly:music?)
  (extract-pitches
   (extract-named-music lst '(EventChord NoteEvent))
   '()))

%% quoted/adapted from http://lsr.di.unimi.it/LSR/Snippet?id=122

#(define (make-note-req p d)
   (make-music 'NoteEvent
     'duration d
     'pitch p))

#(define (make-note elts)
   (make-music 'EventChord
     'elements elts))

#(define (seq-music-list elts)
   (make-music 'SequentialMusic
     'elements elts))

notesFromPitchList =
#(define-scheme-function
  (parser location lst)
  (list?)
  (seq-music-list
   (map
    (lambda (pitch)
      (make-note (list (make-note-req pitch (ly:make-duration 2 0)))))
    (sort
     (delete-duplicates lst)
     (lambda (a b) (ly:pitch<? a b))))))

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

%% Music taken from http://www.lilypond.org/doc/v2.19/Documentation/b9/lily-02539259.ly

global = { \key g \minor}

partI = \relative c' {
  \voiceOne
  fis8 d' ees g, fis4 g
  r8 a16 bes c8 bes16 a d8 r r4
  r2 r8 d16 ees f8 ees16 d
  ees4 ~ 16 d c bes a4 r8 ees'16 d
  c8 d16 ees d8 e16 fis g8 fis16 g a4 ~
  8 d, g f ees d c bes
  a2 g\fermata \bar "|."
}

partII = \relative c' {
  \voiceTwo
  d4 r4 r8 d'16 c bes8 c16 d
  ees8 d c ees a, r r4
  r8 fis16 g a8 g16 fis g2 ~
  2 r8 d' ees g,
  fis4 g r8 a16 bes c8 bes16 a
  bes4. <g b>8 <a c> r <d, g> r
  <ees g>4 <d fis> d2
}
partIII = \relative c' {
  \voiceOne
  r2 r8 d ees g, fis4 g r8 a16 bes c8 bes16 a
  bes2 ~ 8 b16 a g8 a16 b
  c4 r r2
  R1
  r8 d ees g, fis4 g
  r8 a16 bes c8 bes16 a b2
}
partIV = \relative c {
  \voiceTwo
  d4 r r2
  r8 d ees g, fis4 a
  d,8 d'16 c bes8 c16 d ees2 ~
  8 ees16 d c8 d16 ees fis,8 a16 g fis8 g16 a
  d,8 d'16 c bes8 c16 d ees8 c a fis'
  g f ees d c bes a g
  c a d d, g2\fermata
}

%% \score and \layout must be stripped when assigning music expression to variable?

Bach =
<<
  \set Score.currentBarNumber = #28
  \bar ""
  \new PianoStaff <<
    \new Staff = "RH" <<
      \global
      \new Voice = "voiceI" { \partI }
      \new Voice = "voiceII" { \partII }
    >>

    \new Staff = "LH" <<
      \clef "bass"
      \global
      \new Voice = "voiceIII" { \partIII }
      \new Voice = "voiceIV" { \partIV }
    >>
  >>
>>

%% full score

\score {
  \Bach
  \layout {
    \context {
      \Staff
      \remove "Time_signature_engraver"
    }
    \context {
      \PianoStaff
      \override StaffGrouper.staff-staff-spacing.padding = #1
    }
  }
}

% How many notes?

\markup {
  \line {
    "There are"
    #(number->string
      (length
       (delete-duplicates
        #{ \extractPitches \Bach #})))
    "different pitches in this excerpt."
  }
}

%% pitches used in example, in ascending order

\markup \vspace #1

\markup { Notes used: }

notesUsed = \notesFromPitchList \extractPitches \Bach

\score {
  \new StaffGroup <<
    \new Staff = "up" {
      \global
      #(skip-of-length #{ \notesUsed #})
    }
    \new Staff = "down" {
      \clef bass
      \global
      \autochange { \notesUsed }
    }
  >>
}
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to