Thank you David. Your code is well above my level for now, but it'll be
great study material. Is it for 2.25.x? I haven't quite got it working yet,
but that's probably my fault.

On Mon, 6 Feb 2023 at 23:24, David Kastrup <d...@gnu.org> wrote:

> "Adam M. Griggs" <adammgri...@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