[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