lilypond-user
[Top][All Lists]
Advanced

[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



reply via email to

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