There are two ways to write a tremolo on a single note. You can use the
"\repeat tremolo" form or add a colon with the tremolo duration after a
note. While these are engraved identically, they are not represented
the same way internally. The \unfoldRepeats command is able to unfold
the "\repeat tremolo" form but not the abbreviated colon form. Take the
following example:

%%%
\version "2.24.4"
timpani = \new Staff
\with {
  instrumentName = "Timpani"
  midiInstrument = "timpani"
} {
  \time 2/2 \tempo 2 = 80
  \clef bass
  c4 g, c g, |
  \repeat tremolo 16 c32  % does unfold
  g,2:32  % does not unfold
}

% sheet music
\score {
  \timpani
  \layout {}
}

% MIDI file
\score {
  \unfoldRepeats \timpani
  \midi {}
}
%%%

The roll on the C will be unfolded by \unfoldRepeats and rendered in
the resulting MIDI file, but the roll on the G will not. This is
because the roll on the C is a "TremoloRepeatedMusic" event with a 32nd
note inside, while the roll on the G is just a half note with a
"TremoloEvent" articulation attached to it. I decided to tackle this
problem for the fun of it yesterday and wrote a function called
unfoldTremolos (included as an attachment to avoid the email system
adding unwanted line breaks), which will convert all notes with a
"TremoloEvent" articulation into a "TremoloRepeatedMusic" event that
can get unfolded by \unfoldRepeats.

Now, if we combine that with \unfoldRepeats, the colon form of tremolo
will also get unfolded and be heard in the MIDI file.

%%%
\include "unfoldTremolos.ily"
\score {
  \unfoldRepeats \unfoldTremolos \timpani
  \midi {}
}
%%%
unfoldTremolos =
#(define-music-function (music) (ly:music?)
  (music-map
    (lambda (m)
      (define (name-is? x name) (equal? (ly:music-property x 'name) name))
      (define trem (find (lambda (x) (name-is? x 'TremoloEvent)) 
(ly:music-property m 'articulations)))
      (if trem
        ; replace this note m with a TremoloRepeatedMusic event containing m
        (set! m
          (make-music 'TremoloRepeatedMusic
            'repeat-count
              (ly:moment-main (ly:moment-div (ly:music-length m) 
(ly:make-moment (/ 1 (ly:music-property trem 'tremolo-type)))))
            'element
              (music-clone m
                'duration (ly:make-duration (ly:intlog2 (ly:music-property trem 
'tremolo-type)))
                ; keep all articulations except for the tremolo and tie
                'articulations
                  (remove
                    (lambda (m) (or (name-is? m 'TremoloEvent) (name-is? m 
'TieEvent)))
                    (ly:music-property m 'articulations))
              )
          )))
      m)
    music)
)

Reply via email to