creating a loop with many small files

hello friends, i have googled many a time to find a solution to this issue of mine but to no avail, so i have come here to ask for help.

i have 15 small files of around 0.05 sec length each. these files need to be randomly arranged over and over into a 10+ second loop so that i can re-save it and apply it properly to a project i’m working on. however, doing this manually is a complete and horrific chore. i have found a nyquist prompt already but it only supports one piece of audio being repeated, while i need several repeated and also chosen at random.

can anyone help me with this or at least point me in the right direction?

Are they all the exact same length?

Do you mean that the order is random throughout the 10 seconds, and then repeats,
or do you mean the15 files are in a random order, and that pattern repeats for 10 seconds?
If you mean the former, do all 15 files have to be used before any of them can repeat?
Can there be the same file more than once in succession?

Maybe it would be easier if you told us what the 15 files are, and what it is that you are trying to do? (what is this for?)

aye i could’ve been clearer.

they’re all the exact same length, they’re perfectly chopped bits of the start of gunshots, and the way i’m trying to apply them in code right now prevents me from just playing them again and again in the actual code, i need a loop instead. i don’t wanna sound like i’m rattling off job details but basically:

randomly select any, add at start of track
0.05 sec later, randomly select any and add again (overlapping if it happens, so i guess on another track - they’re all the same length but because they’re gunshots i might want them to bleed a little into each other)
repeat until 0.05 sec intervals add up to some respectable length, such as ten seconds
ideally all 15 used before any repeat and no direct repeats of the same

the same effect if you just wrote a program to play one at random every 0.05 sec, but obviously hardcoded into an audio file. i took a look at nyquist and it looked like alien language compared to lua so i gave up pretty quick :frowning:

Super, that makes things a lot easier than if they had been different lengths.
I’ll get back to this when I’ve played with some code…


Nyquist is based on XLisp, and like all LISP languages, it uses “S-Expressions”. There is a basic pattern to almost everything in LISP languages - once you “get” this, it all becomes a lot easier to understand:

(command arguments)

The “command” will usually be the name of a function or macro, and there may be 0 or more arguments.

Simple example:
In normal arithmetic we might write:

4 + 3 = 7

The numbers 4 and 3 are the “arguments” and “+” (addition) is the function. “7” is the result that is returned from adding 4 and 3.
In Nyquist, we put the function name “+” first, followed by the arguments, and enclose the entire statement in parentheses:

(+ 4 3)

which returns the value “7”.
(Try running that in the Nyquist Prompt (Nyquist Prompt - Audacity Manual)

We can also nest functions such that one statement is passed as an argument to another function.
Example pass the statement (+ 4 3) as an argument:

(* 2 (+ 4 3))

Here the outer function "" (multiply) is passed two arguments, “2” and “(+ 4 3)”.
(Notice that arguments are separated by spaces rather than commas)
As might be expected, (
2 (+ 4 3)) returns “14”.

The same pattern occurs over and over again in Nyquist. For example, to generate a 440 Hz tone withing the current track selection:

(hzosc 440)

The function “hzosc” is an oscillator, and we pass the argument “440” to tell it to generate a frequency of 440 Hz.

What is the length of each sound?

I’m assuming that your tracks are mono. This will only work with mono tracks

  1. Import all of your sounds into one project.
  2. “Tracks menu > Align > End to End”
  3. “Tracks menu > Mix > Mix and Render”

You should now have all the sounds on one track, one after another.

  1. Set the values in the first three lines as required, and apply this code using the Nyquist Propmpt:
(setf dur 0.3)  ;length of one sound
(setf total 10)  ;total length required (seconds)
(setf interval 0.05) ;required interval between the start of one sound and the next


;; Calculate the number of sounds in the selection.
(setf count (truncate (/ (get-duration 1) dur)))
;; Total number of sounds required
(setf repeats (round (/ total dur)))

;make a list from 0 to number of sounds "count".
(setf sndlist ())
(defun make-list ()
  (dotimes (i count)
    (push i sndlist)))


(defun get-one-snd (n sig)
  (extract-abs (* n dur) (* (1+ n) dur) sig))


(defun get-sound-ref ()
  (when (null sndlist)
    (make-list))
  (let ((n (nth (random (length sndlist)) sndlist)))
    (setf sndlist (delete n sndlist))
    n))


(let ((sig *track*))
  (extract-abs 0 total
    (let ((out (s-rest 0))
          oneshot)
      (dotimes (i repeats out)
        (setf oneshot
            (set-logical-stop (get-one-snd (get-sound-ref) sig) dur))
        (setf out
          (sim out
              (at-abs (* i interval) (cue oneshot))))))))

works like a charm, and very interestingly done too, i would have guessed that the sounds being separate wouldve been easier to manipulate than having them in order in one track.

sorry for not being there to respond though, the tracks are stereo, is mono only a nyquist limitation?

It’s a limitation of that code.
Getting this to work correctly was quite tricky - making it work with multiple channels is possible, but even trickier.

Effects in Audacity act on one track at a time. If the sounds are in separate tracks, it would be necessary to temporarily store them somewhere that Nyquist can access them when it moves onto the track where it writes them back to Audacity.
Also, Nyquist effects are one of 4 types:

  • process: “Effects”
  • Generate
  • Analyze
  • Tool

Each type has different capabilities afforded to it by Audacity.
“Generate” and “Tool” type plug-ins are the only ones that can add a new track.
“Process”, “Analyze” and “Generate” type plug-ins are the only ones that iterate over the selected tracks.
“Process” and “Analyze” are the only ones that pass the selected track audio to Nyquist.
“Process” and “Generate” are the only ones that accept audio returned from Nyquist.

By having all of the clips on one track, we can run Nyquist as a “process” type effect, which can read the selected audio and replace it with the processed audio.

thanks for the code either way, i find mono things i need to loop often enough too. this’ll be loads of help. thanks again!