Start and stop times of notes with sliding tempo?

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 …

  • edgar

If you mean the key signature rhythm goes up, then the quarter notes would get shorter as a direct ratio of the speedup. Everything’s 20% faster.

If the key signature rhythm doesn’t change, then each note duration stays the same and they overlap.

Did you miss a definition in the question? Or did I miss the question altogether?

Koz

I only wanted to tell that at least half of my problem is meanwhile solved.

In a tempo slide from START-BPM to END-BPM over a number of BEATS, the duration of every beat propagates by a constant multiplication factor of:

     1 / (BEATS-th root of (END-BPM / START-BPM))  ; because time = 1 / tempo
  =      (BEATS-th root of (START-BPM / END-BPM))  ; invert bpm-ratio instead
  =  (START-BPM / END-BPM) ^ (1 / BEATS)           ; nth-root of x = x^(1/n)

Or in Nyquist code:

(defun tempo-slide-factor (beats start-bpm end-bpm)
  (expt (/ (float start-bpm) end-bpm) (/ 1.0 beats)))

Then the [edit:] durations of the beats in seconds are:

 1st beat = (60 / start-bpm) * (tempo-slide-factor ^ 0)
 2nd beat = (60 / start-bpm) * (tempo-slide-factor ^ 1)
 3rd beat = (60 / start-bpm) * (tempo-slide-factor ^ 2)
 
 Nth beat = (60 / start-bpm) * (tempo-slide-factor ^ (N-1))

I’m still searching for a math simplification of the following sum to compute the [edit:] start times of the beats in seconds:

(x * y^0) + (x * y^1) + (x * y^2) ... + (x * y^(n-1))

   N-1
  ----,
  
   >    x*(y^n)
  /
  ----'
   n=0

But I’m tired now, I will tell more details tomorrow…

  • edgar

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”.

For a simple linear tempo increase:

(setq start-speed 100) ; bpm
(setq end-speed 200)
(setq number-of-beats 10)


(setq start-speed (/ start-speed 60.0))     ; bpm
(setq end-speed (/ end-speed 60.0))

(setq start-beat-duration (/ start-speed))  ; seconds
(setq end-beat-duration (/ end-speed))

(setq change (/ (- end-beat-duration start-beat-duration) number-of-beats))

(setf output (s-rest 0))
(setq time 0)
(setq dur start-beat-duration)

(abs-env
  (dotimes (i number-of-beats)
    (setf output 
      (sim
        (at 0 output)
        (at-abs time (pluck 60 0.2))))
    (setq time (+ time dur))
    (setq dur (+ dur change))))

output

Hello all

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.

RJ

;; "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)
(LET*
;; 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))))