Not really important question from a math idiot (= me) that needs no quick reply, getting Audacity_2.0.1 out is more important.
Imagine a sequence of 10 notes with equal note length (e.g. 10 quarter-notes) that are played with increasing tempo, so that the first note is played with 100bpm and the last note is played with 200bpm. (The example is a bit unrealistic for real-life music but the numbers are easy to compute.)
What is the simplest math formula to compute the start and stop times in seconds of every note, in relation to the start-time of the first note?
The tempo slide happens during the “duration” of a note, so it’s not possible to compute the duration in seconds from the bpm-tempo at the start-time of a note, because at the stop-time of the same note the bpm-tempo already has changed.
What I need is a general math formula (not necessarily Nyquist code) to compute the start and stop times from a “tempo envelope”.
I do not need values for every sample of a sound, I only need the start and stop times of every note.
The goal is to archieve smooth tempo slides from slow to fast tempo or vice versa.
A further complication is that I have no idea if I need a linear, exponential, or logarithmic tempo slides.
Anybody an idea? Google is not really helpful here …
It depends on how “musical” you want to be.
Tempo increases are rarely linear in music and usually the increase in tempo is much greater between the last and first beat of the (next) bar than between other beats. The greatest increase is usually between the last beat of the accelerando and the first beat of the “new tempo”.
Here is my approach to your sliding problem. I thought to myself that it is nothing but a uniform acceleration problem. You may remember those formulas:
a = v1 - v0 /t
s (t) =a/2 * t^2 + v0 t
where a > acceleration (normally m/s^2)
v0 v1 > initial - and final velocity (m/s)
t > time in seconds
s(t) > position (m) at time t
BPM is nothing but a velocity value.
In the code that follows I changed it to seconds per beats.
So meters become seconds; seconds become beats and the acceleration is expressed in seconds per beats squared (!)… The displacement s(t) is now the Distance from the start as a time-value instead of a place in space. In Wikipedia are also formulas for not uniform or constant motion, which would be interesting to examine.
I hopefully didn’t make a mistake in my little program. The values seem to be the proper ones:
beat one starts with 100 bpm = 0.58 sec, what is correctly a bit less than the value of the constant tempo (0.6 s). at beat nine the duration is a little bit above 0.3 s and the 10th one would be below 0.3 s. Here the new tempo of 200 bpm would start. I tried to test it against a clicktrack, that afterwards was speeded up but it didn’t yield the exact same values, so please test it yourself, maybe Steve’s code produces also another output.
;; "NOTE" returns the start-time of the recent beat
;; end-time = start of next beat
;; BEATS:last beat, which is affected by accelaration
(DEFUN NOTE (BEATS BEAT-N BPM-START BPM-END)
;; beats are now counted from 0 upwards
((BEAT-N (1- BEAT-N))
;; Express original bpm-tempo as seconds per beat
(SPB-START (/ 60.0 BPM-START))
(SPB-END (/ 60.0 BPM-END))
;; Calculate the acceleration, which is actually negative,
;; because the seconds per note decrease.
(ACCEL (/ (- SPB-END SPB-START) BEATS )))
(+ (* SPB-START BEAT-N)
(* (/ ACCEL 2.0) (expt BEAT-N 2.0)))))
;; Prints out the values for 10 beats
;; the 10th value wouldn't be necessary, since there starts
;; the new constant bpm of 200 (=0.3 sec dur).
(DOTIMES (NUM 10)
(SETQ BEAT (1+ NUM))
(FORMAT T "Beat ~A, Start: ~A, Stop: ~A, Duration: ~A ~%"
BEAT (NOTE 9 BEAT 100 200)
(NOTE 9 (1+ BEAT) 100 200)
(- (NOTE 9 (1+ BEAT) 100 200) (NOTE 9 BEAT 100 200))))