lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: rall. autocalculation function in Scheme


From: David Kastrup
Subject: Re: rall. autocalculation function in Scheme
Date: Mon, 06 Feb 2023 15:23:52 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux)

"Adam M. Griggs" <adammgriggs@gmail.com> writes:

> Hello list,
>
> I'm trying to create a Scheme function that will automatically calculate
> and enact a *rall*. as a sequence of \tempo assignments. I am aware of the
> basic *rall*., *rit*., and *accel*. functions in "articulate.ly" but I
> wanted something I have a little more control over.

What I am using is

tempoChange =
#(define-music-function (interval endscale thenscale music)
   (ly:duration? scale? (scale? 1) ly:music?)
  "Make a gradual tempo change over @var{music}, essentially changing speed 
after
every duration of @var{interval}, approaching a factor of speed of 
@var{endscale}
compared to the start.  Afterwards, tempo is switched to @var{thenscale} of the
original speed (default 1).  If @var{thenscale} is 0, the speed reached at the
end is just maintained and can be overriden with an explicit @samp{\\tempo}
command if required."
   (define (scaletempo oldscale newscale)
     (make-apply-context
      (lambda (ctx)
        (set! (ly:context-property ctx 'tempoWholesPerMinute)
         (ly:moment-mul (ly:context-property ctx 'tempoWholesPerMinute)
                 (ly:make-moment (/ newscale oldscale)))))))

   (let* ((muslen (ly:moment-main (ly:music-length music)))
          (intlen (ly:moment-main (ly:duration-length interval)))
          (steps (/ muslen intlen))
          (endfactor (scale->factor endscale))
          (thenfactor (scale->factor thenscale)))
     (make-simultaneous-music
      (list music
            (context-spec-music
             (make-sequential-music
              (let loop ((rsteplst (iota (1+ steps) endfactor (/ (- 1 
endfactor) steps)))
                         (res (if (positive? thenfactor)
                                  (list (scaletempo endfactor thenfactor))
                                  (list))))
                (if (null? (cdr rsteplst))
                    res
                    (loop (cdr rsteplst)
                          (cons* (scaletempo (cadr rsteplst) (car rsteplst))
                                 (make-skip-music (ly:make-duration 0 0 intlen))
                                 res)))))
             'Score)))))


Here are some usages in a time track:

  \tag layout {
    \tempo "rall"
    \skip 1*2 |
  }
  \tag midi {
    \tempoChange 4 2/3 {
      \skip 1.
    }
    \tag countin \skip 2
  }

  \tag layout {
    \tempo "rit."
    \skip 2 |
    \skip 1*2 |
  }
  \tag midi {
    \tempoChange 8 ##e0.5 0 {
      \skip 2 |
      \skip 1*2 |
    }
  }

Note that ##e0.5 is the same as #1/2 or #5/10 , namely an exact
rational, but written with decimal notation.  That can be handy for
fine-tuning since incrementally tweaking decimal notation tends to be
more hands-on than tweaking fraction notation.


-- 
David Kastrup



reply via email to

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