How to skip x every y seconds

I tried to Google an NYQ effect; I found a similar effect that repeats x every y seconds. https://forum.audacityteam.org/t/repeat-every-x-seconds-y-times/55758/1 But I wanted to skip some time in a certain amount of time. I tried changing the NY code with no luck, and Google can’t find the exact effect. Could you post the code in Nyquist for that effect or direct me to a downloadable link with it?

For instance, I want to skip a certain amount of time every amount of time. Skipping a second every second would make the file half as long, and repeating a second every second like the other effect would make it twice as long.

I want it to be similar to Seek, but adjustable in how long it takes before jumping back or forward, and how far.

I found the opposite, repeating, but how would I do the skipping?

PS: Do I put web links in the Code Display, or is that just for NYQ?

Provided that the length to skip is not longer than the length to repeat, this should work:

;version 4
;type process
;control dur "Seconds to repeat" float "" 2 0.1 5
;control skip "Seconds to skip" float "" 1 0 5
;control rep "Repeats" int "" 2 1 10

(setf step (truncate (* dur *sound-srate*)))
(setf skip (truncate (* skip *sound-srate*)))

(defun repeat (sig)
  (when (> skip step)
    (throw 'err "Skip duration must be smaller than repeat length."))
  (let ((out (s-rest 0))
        (time 0))
    (do ((ar (snd-fetch-array sig step step)(snd-fetch-array sig step step)))
        ((not ar) out)
      (dotimes (j rep)
        (setf out
          (sim out
            (at-abs time
              (cue (snd-from-array 0 *sound-srate* ar)))))
        (setf time (+ time dur)))
      (when (> skip 0)
        (snd-fetch-array sig skip skip)))))

(catch 'err (multichan-expand #'repeat *track*))

Run the code in the Nyquist Prompt effect (see: Nyquist Prompt - Audacity Manual)

Thank you, now I can make it sound like a CD playing fast, and use “Reverso” and “Reverse” to sound like it is rewinding, though I have to apply it multiple times to go over 2x speed.

However, I have a new problem. (This has to do with pitch-correction in speed change.)

I got the audio to slow down, but the pitch is low,

(force-srate 44100 (stretch-abs (/ 3 60) (sound *track*))))

and so I increase pitch,

(pitshift(sound *track*) 3 1.0)

but how to combine them in the same effect? I tried this

(force-srate 44100 (stretch-abs 3.0 (sound *track*))))
(pitshift(sound *track*) 3.0 1.0)

I even tried with “+” and “&”, tried adding extra parenthesis on start and end, it will either apply one of the commands of the effect or do nothing.

The reason I want to do this is so when I slow down the sample rate with pitch change, the pitch change corrects the sound with speed.

Also, is there an alternate time-stretch function with no pitch-change Nyquist command I can use? If not, how can I combine sample-rate and pitch-change to do the same thing, or how to repeat and skip with a duration fast enough to sound like so? (Like I said, the skip only goes to double speed.)

I got close to slowing it down by 60x with this, but there has got to be a simpler way to add it to a list in a switch, and less robotic.

(setf step (truncate (* 0.01 *sound-srate*)))
(setf segments (truncate (/ len step)))

(defun repeat (sig)
  (let ((out (s-rest 0))
        (time 0))
    (dotimes (i segments out)
      (setf ar (snd-fetch-array sig step step))
      (dotimes (j 60)
        (setf out
          (sim out
            (at-abs time
              (cue (snd-from-array 0 *sound-srate* ar)))))
        (setf time (+ time 0.01))))))

(multichan-expand #'repeat *track*)

Also, I’ll let you know if I need help getting “force-srate” to work on different rates, because the speed effect only works on one rate, but I should be able to figure that out. But just in case, if anyone has an idea of how to sync altered speed with the correct rate (any instead of just converting to 44100) or replace it with another command setting, please, let me know.

The reason that does not work is because track refers to the original track audio in both lines of code.
(also there is one too many “)” at the end of the first line)

Try this (below)
“Speed change = 0.5” means “half speed”.
“Pitch change = 2” means “double pitch” (an octave higher).
In the first line of code, we change the value of track to the stretched sound, then the second line of code applies pitch shift to the new value of track.

;version 4

;control speed "Speed change ratio" float "" 0.5 0.1 10
;control pitch "Pitch change ratio" float "" 2 0.1 10

(setf *track* (force-srate 44100 (stretch-abs (/ speed) (sound *track*))))

(pitshift *track* pitch 1.0)

OK, I got everything but the last to work…

(cond
  ((= mins 2)
    (force-srate (* *sound-srate* (/ 60 1.0)) *track*))
  ((= mins 1)
    (force-srate (* *sound-srate* (/ 1.0 1.0)) *track*))
  ((= mins 0)
    (force-srate (* *sound-srate* (/ 1.0 60)) *track*))
  ((= mins 3)
    (setf *track* (force-srate (* *sound-srate* (/ 1.0 60) (sound *track*))
    (pitshift *track* pitch (/ 1.0 60.0)
  ((= mins 4)
    (setf *track* (force-srate (* *sound-srate* (/ 60 1.0) (sound *track*))
    (pitshift *track* pitch (/ 60 1.0)
)))

I need to make 2 commands here, but this wasn’t working. I got speed to adjust with pitch, now I’m trying to do the same as 0 & 2, with 3 & 4, but adjust pitch to normal. (Yes, I know 1 would have no effect.) Here is the switch.

;control mins "Convert what to minutes?" int "0=Hours Adjust Pitch, 1=Minutes 2=Seconds Adjust Pitch, 3=Hours Preserve Pitch 4=Seconds Preserve Pitch" 0 0 4

If anything, do you need more code to make an example? Also, I got the speed to change at normal srate, but now I want to do the same effect with corrected pitch.

Help? I tried googling and found stretch-to-length, but I don’t know how to put the code from that into this, I tried. “Nyquest returned the value” came up a few times… Is there another typo?

That will fail because the parentheses don’t match up correctly.
It starts to go wrong here:

  ((= mins 3)
    (setf *track* (force-srate (* *sound-srate* (/ 1.0 60) (sound *track*))
    (pitshift *track* pitch (/ 1.0 60.0)

Tip: Use NotePad++ (free from: Downloads | Notepad++)
Enable “parentheses matching” and set the code language to “Lisp”.

This would be much better as a “choice” widget
See: Missing features - Audacity Support

As a choice widget:

;version 4

;control option "Convert what to minutes?" choice "Hours Adjust Pitch,Minutes,Seconds Adjust Pitch,Hours Preserve Pitch,Seconds Preserve Pitch" 0

(print option)

When you want to compare a variable with a series of values, it’s better to use “CASE” rather than “COND”.

Example using “COND”:

;version 4
;control val "Val" int "" 0 -5 5
(cond
  ((= val 0) (print "zero"))
  ((= val 1) (print "one"))
  ((= val 2) (print "two"))
  (t  (print "default")))

Example using “CASE”:

;version 4
;control val "Val" int "" 0 -5 5
(case val
  (0 (print "zero"))
  (1 (print "one"))
  (2 (print "two"))
  (t (print "default")))

See here: XLISP case

I’m still having the problem. When I try to set to 3, it fails and tells me it returned 3. Here is the entire file.

;nyquist plug-in

;version 4

;type process

;name "Convert time to minutes"

;action "Making minutes..."

;control text "Have you heard a long book you want to hear in 30 seconds instead of half an hour? Want to hear audio in a time elapsed video at normal speed? OK, first of all..."
;control mins "Convert what to minutes?" int "0=Hours 1=Minutes 2=Seconds" 0 0 3
;control text ""
;control text "Hours to Minutes will be 60x shorter. Minutes are shorter than Hours."
;control text "Minutes to Minutes will do no change. Minutes are equal to Minutes. (Consider this a Bypass command.)"
;control text "Seconds to Minutes will be 60x longer. Minutes are longer than Seconds."
;control text ""
;control text "Also, you will need to be sure the quality is still clear enough, and that you have been trained seriously, TREMENDOUSLY WELL to comprehend sounds at these speeds."
;control text ""
;control text "Notes and tips:"
;control text "*You can use Hours to Minutes twice for Hours to Seconds."
;control text "*Similarly, to do the alternate and convert Seconds to Hours, use Seconds to Minutes twice."

(cond
  ((= mins 2)
    (force-srate (* *sound-srate* (/ 60 1.0)) *track*))
  ((= mins 1)
    (force-srate (* *sound-srate* (/ 1.0 1.0)) *track*))
  ((= mins 0)
    (force-srate (* *sound-srate* (/ 1.0 60)) *track*))
  ((= mins 3)
    (setf *track* (force-srate (* *sound-srate* (/ 1 60) (sound *track*)))
    (pitshift *track* pitch 60.0)))
)

I saw that the parentheses were highlighted, and checked to see if it was on LISP. 0, 1 and 2 work fine, but 3 keeps returning the value. Could you please give me more detail? What do I do to change tempo only on a certain setting on a switch like this?

This;

(setf *track* (force-srate (* *sound-srate* (/ 1 60) (sound *track*)))
(pitshift *track* pitch 60.0)))

should be:

(setf *track* (force-srate (* *sound-srate* (/ 1.0 60)) (sound *track*)))
(pitshift *track* 60 1))

or better:

(setf *track* (force-srate (/ *sound-srate* 60) (sound *track*)))
(pitshift *track* 60 1))

Also, the “;action” header is now obsolete.


I would write it like this:

;nyquist plug-in
;version 4
;type process
;name "Stretch to minutes"

;control option "Convert what to minutes?" choice "Hours,Minutes,Seconds,Hours (same pitch)" 0

(case option
  (0 (force-srate (/ *sound-srate* 60) *track*))
  (1 "")  ;Do nothing
  (2 (force-srate (* *sound-srate* 60) *track*))
  (3 (setf *track* (pitshift *track* 60 1))
     (force-srate (/ *sound-srate* 60) *track*)))