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 >