rehearsal tempo

What I specifically need is a way to play a track at slower speeds without changing the pitch so I can play along while I am learning. This might be best (if doable) as a Nyquist plug-in but is beyond my Nyquist programming skills. Some discussion can be found on Audacity’s Feature Requests wiki:
http://wiki.audacityteam.org/wiki/Feature_Requests (search for Change Speed/Tempo/Pitch)

At the most simple I envision a dialog which presents the user with about 10 predefined choices: 50%, 55%, 60%…90%, 95%. When the user selects a speed percentage a new track is created based upon the original–probably best in a new project window so the original track project window is not affected.

The code and math seem very simple for the transformation. Imagine we start out with a track with 10 samples (‘s’ is a generic sample, ‘_’ is an empty sample, ‘I’ is an interpolated sample–the average of the two samples next to it):
ssssssssss
(conceptually–the actual code would be smarter) if we wanted 50% we would make a new sample array which is twice as long putting an empty sample every other position:
s**sssssssss**
then go back and interpolate each empty sample:
sIsIsIsIsIsIsIsIsIsI

For each 5% change we would change the spacing:
55%:
ssIssIssIssIssI
60%:
sssIsssIsssIs
75%:
sssssIsssssI

I cannot envision a need for slower than 50% (and probably not even less than 75%) and I also don’t see a need for finer granularity. Slower speeds would mean that there would be more interpolated samples than “real” samples. Finer granularity would require one or more “tricky” algorithms to end up with non-regular patterns:
sIssIsIssIsIssI
sIssIsssIsIssIsssI
ssIsssIssIsssIssIsssI
sIssIsssIsIssIsssI
etc.–doable but a lot more work for limited gain in my personal usage!

Yes, very simple, but unfortunately will not work. That will change the speed and the pitch.

Consider a single cycle of a 441 Hz tone recorded as a sample rate of 44100 Hz. The wave will have 100 samples and will have a duration of 1/441 seconds (about 2.3 milliseconds).
Now add an extra sample between each of those samples (interpolated from the values either side). You now have 199 samples (200 if you add one at the end) so now the length has stretched to double the size (double duration) but there is still only one wave cycle. New length = 2/441 (approx 4.5 milliseconds) and the frequency is 220.5 Hz.

To make it work you need much bigger pieces of audio. The minimum length selection that would work would be one cycle of the waveform. That’s easy if you’re working with a single fixed frequency, but rather more tricky with complex (real world) sounds as the length of the cycles is constantly changing, and each “period” of the waveform (positive going zero crossing to the next positive going zero crossing) may contain hundreds of different frequencies, some of which have completed a cycle and some of which will be part way through.

I read that Roger Dannenberg had written a Nyquist effect for time stretching, but it uses the function (yin) which is not available in the Audacity implementation of Nyquist.

A while ago I had a look at the opposite effect of speeding up audio using a simple “overlap-add” method. Considering the lack of sophistication of the method I think it sounds surprisingly good on quite a range of material.

If you want to have a play with the code, this will run from the Nyquist Prompt, but only works with mono tracks:

(setq segments (truncate (mult 10 (get-duration 1))))

(defun env (length) ; overlap will be 0.05 seconds
  (abs-env
  (sum 1 (mult 0.5 (seq
    (sum -1 (osc (hz-to-step 10) 0.05 *SINE-TABLE* -90.0))
    (const 0.0 length)
    (sum -1 (osc (hz-to-step 10) 0.05 *SINE-TABLE* 90.0)))))))

(setf newsound (s-rest 0))

(defun next (s-in start stop)
  (mult (env 0.1)
    (extract-abs start stop (cue s-in))))


(dotimes (i segments)
  (setq t1 (/ i 10.0))
  (setq t2 (+ t1 0.2))
  (setf nclip (next s t1 t2))

  (setf newsound 
    (sim
      (at-abs 0 (cue newsound))
      (at-abs (* t1 0.5) (cue nclip)))))

newsound

;(extract-abs 0 (/ (+ 1 segments) 20.0) newsound)

;;;;;;;;;;;;;;;;;;;;;;;

(setq segments (truncate (mult 10 (get-duration 1))))

(defun env (length) ; overlap will be 0.05 seconds
  (abs-env
  (sum 1 (mult 0.5 (seq
    (sum -1 (osc (hz-to-step 10) 0.05 *SINE-TABLE* -90.0))
    (const 0.0 length)
    (sum -1 (osc (hz-to-step 10) 0.05 *SINE-TABLE* 90.0)))))))

(setf newsound (s-rest 0))

(defun next (s-in start stop)
  (mult (env 0.1)
    (extract-abs start stop (cue s-in))))


(dotimes (i segments)
  (setq t1 (/ i 10.0))
  (setq t2 (+ t1 0.2))
  (setf nclip (next s t1 t2))

  (setf newsound 
    (sim
      (at-abs 0 (cue newsound))
      (at-abs (* t1 0.75) (cue nclip)))))


 newsound

There I go thinking! Will try your mono approach, thanks!

Seemed to work but in the opposite direction–a 4:15 duration track was reduced and sped up to 3:15. What I need is the opposite – a 4:15 should become a 5:15 duration track. What values would I need to change to see a 10%, 20% & 30% slow down in apparent tempo?

Yes I know :slight_smile:
I wrote:
<<< A while ago I had a look at the opposite effect of speeding up audio using a simple “overlap-add” method. >>>

For a slowing down effect you would need to duplicate the “segments”. The tricky bit is getting them back together, each in the right place.

Ah well, this will have to go on my back burner as I am busy with my new “webmaster for the band” job (or is it an adventure?); thanks for the help!

It’s been on my back burner for so long it’s probably stuck to the bottom of the pan.