[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Creating click tracks for an arbitrary time signature and length of
From: |
Aaron Hill |
Subject: |
Re: Creating click tracks for an arbitrary time signature and length of music |
Date: |
Thu, 19 Dec 2019 17:10:31 -0800 |
User-agent: |
Roundcube Webmail/1.3.8 |
On 2019-12-19 3:03 pm, Matt Wallis wrote:
What I want to do is to automatically create a click track for any
length of music, and any time signature. For example, if the music is
L measures in length, and the numerator of the time signature is N,
and the denominator is D, then I want a click track that looks like
this:
\repeat unfold <L> \drummode { wbh<D> \repeat unfold <N-1> { wbl\pp
}}
I am certain that this can be done using scheme, but I can't figure
out how (I'm a scheme novice).
Here's a quick-and-dirty way to achieve close to what you want:
%%%%
\version "2.19.83"
clickTrack = #(define-music-function (beat meter)
((ly:duration? #f) fraction?)
(let* ((beat (if (ly:duration? beat) beat
(make-duration-of-length
(ly:make-moment (/ 1 (cdr meter))))))
(meter-moment (ly:make-moment (/ (car meter) (cdr meter))))
(beat-moment (ly:duration-length beat))
(beat-count (floor (ly:moment-main
(ly:moment-div meter-moment beat-moment))))
(final-moment (ly:moment-mod meter-moment beat-moment))
(final-duration (make-duration-of-length final-moment))
(needs-final? (ly:moment<? (ly:make-moment 0) final-moment)))
(make-sequential-music
(map (lambda (n)
(cond
((eqv? 0 n) #{ \drummode { wbh $beat \ff } #})
((eqv? beat-count n) #{ \drummode { r $final-duration } #})
(else #{ \drummode { wbl $beat \pp } #})))
(iota (if needs-final? (1+ beat-count) beat-count))))))
clickTrackDuring = #(define-music-function (beat meter music)
((ly:duration? #f) fraction? ly:music?)
(let* ((music-length (ly:music-length music))
(meter-moment (ly:make-moment (/ (car meter) (cdr meter))))
(repeat-count (floor (ly:moment-main
(ly:moment-div music-length meter-moment)))))
(if (ly:duration? beat)
#{ \repeat unfold $repeat-count \clickTrack $beat $meter #}
#{ \repeat unfold $repeat-count \clickTrack $meter #})))
melody = \fixed c' {
\time 4/4
\repeat unfold 2 { | { e2 g } } \bar "||"
\repeat unfold 2 { | \tuplet 3/2 { e2 g e } } \bar "||"
\repeat unfold 2 { | { e4 g b g } } \bar "||"
\repeat unfold 2 { | \tuplet 5/4 { e4 g b g e } } \bar "||"
\repeat unfold 2 { | \tuplet 6/8 { e8 g b d' b g } } \bar "||"
}
\score {
\new Staff { \melody }
\layout { }
}
\score {
<<
\new Staff { \melody }
\new DrumStaff { \clickTrackDuring 4/4 \melody }
>>
\midi { \tempo 4 = 100 }
}
%%%%
Firstly, \clickTrack is a function for generating one measure of
clicking based on a desired beat and meter. The beat defaults to the
denominator of the meter if unspecified. If the beat duration does not
divide the measure perfectly, a final rest is inserted to pad out the
measure. Here are examples of use:
%%%%
\repeat unfold 8 \clickTrack 2 4/4 % click on 1 and 3
\repeat unfold 8 \clickTrack 4/4 % click on all four
\repeat unfold 8 \clickTrack 4. 6/8 % click on 1 and 4
\repeat unfold 8 \clickTrack 4 6/8 % click on 1, 3, and 5
\repeat unfold 8 \clickTrack 6/8 % click on all six
%%%%
Secondly, \clickTrackDuring is a very basic wrapper for \clickTrack that
automatically repeats the click measure to cover the duration of the
specified music. Note that no attempt is made to handle music that
changes time signature nor music with \partial measures or other funny
business. If you had a anacrusis, you would need to manually offset the
music:
%%%%
% Assume \musicWithPickup begins with \partial 4
\clickTrackDuring 3/4 { s2 \musicWithPickup }
%%%%
-- Aaron Hill