I was inspired by David's post, as I have also encountered patterns in
durations that I wish were less redundant to input. The snippet Malte
linked to is rather complex, although I suspect it is significantly more
air-tight at handling edge cases.
Here is a simpler (i.e. "one-pager") music function for applying a
specified rhythmic pattern to some music:
%%%%
\version "2.19.83"
applyRhythm = #(define-music-function
(rhythm notes) (ly:music? ly:music?)
"Overwrites the durations of a simple music expression with
those from another, repeating the rhythmic pattern as needed."
(define (extract-durations music)
(map (lambda (elem) (ly:music-property elem 'duration))
(filter (music-type-predicate '(rhythmic-event))
(ly:music-property music 'elements))))
(define (apply-duration element duration)
(let ((subelements (ly:music-property element 'elements)))
(if (null? subelements)
(set! (ly:music-property element 'duration) duration))
(map (lambda (subelement)
(set! (ly:music-property subelement 'duration) duration))
subelements)))
(define (apply-durations durations music)
(for-each apply-duration
(filter (music-type-predicate '(rhythmic-event event-chord))
(ly:music-property music 'elements))
(apply circular-list durations))
music)
#{ #(apply-durations (extract-durations rhythm) notes) #})
\fixed c' {
\time 6/8
\applyRhythm { 8. 16 8 } {
| g\mp a <g b> a-\accent fis g~
| <g b>\< c' <b d'>
}
<fis d'>4\mf r8
\applyRhythm { 8. 16 8 4. } {
| <e c'>( b <fis a> <d b^~>
| <e b>) r <c fis>\f <b, g>\accent
}
}
%%%%
-- Aaron Hill