Can't figure out why seq is adding the rest of audio track

Hi all,

I’m running into an issue where when use the seq function the second sound is carried forward until the end of the selection. Instead of returning the result of both short sounds played right after each other, I receive the first short sound and then the next selected sound except it keeps going until the end of the selection, way past what I stored in the variable.

Here is my code:

(setf seclen (get-duration 1))
(setf seclen (truncate seclen))
(print seclen)

;length of clips
(setf len 0.5)

;generate random number in range of clip
(setf secFloat (/ (float (random (* seclen 100))) 100))

;gen random clip
(setf whole (extract-abs secFloat (+ secFloat len) s))
(play whole)

;main loop
(dotimes (i 4) 

;generate random number in range of clip
(setf secFloat (/ (float (random (* seclen 100))) 100))

;gen random clip
(setf one (extract-abs secFloat (+ secFloat len) s))
(play one)

;add clip to end of running total
(setf whole 

(seq (cue whole) (cue one))

)

;(play whole)

)

(force-srate 44100 whole)

I’m using version 3 syntax btw.

What I would like the code to do is take a selection, store a short randomly selected clip in a variable and add that to the previous clip in a loop, so the result is a randomly generated track that jumps around constantly.
This is my first time doing any audio processing, so apologies if this question is trivial.

Thanks.

This is tricky, and it catches me out every time I encounter it. The issue is to do with how Nyquist handles the logical stop time for sounds.

A few asides about the code:

The Nyquist variable “LEN” has special meaning in Audacity. It is the length of the selection in samples. To avoid confusion, it’s better to only use LEN for that purpose.

Nyquist (based on XLISP) is case insensitive. As with Lisp, the usual convention is to name variables as hyphen-separated-lower-case. (A common gotcha for people coming from a C / C++ background, is to forget that Nyquist sees “secFloat” the same as “secfloat” the same as “SECFLOAT”.)

Do you specifically want “secFloat” to be an exact number of centiseconds? If you just want secFloat to be a float value in the range 0 to seclen, you could define it as:

(setf sectionf (* (rrandom) seclen))

or, as you require this several times, you could define a function:

(defun rand-section(max-length)
  "Return random value between 0 and max-length"
  (* max-length (rrandom)))

On to the main problem:


SEQ:

Evaluates the first behavior beh1 according to time and each successive behavior at the logical-stop time of the previous one. The results are summed to form a sound whose logical-stop is the logical-stop of the last behavior in the sequence…

EXTRACT-ABS:

Returns a sound which is the portion of beh between start and stop, independent of the current warp. The result is shifted to start according to warp.

We have a conflict between what you want to happen (extracted portions of S added end to end), and what SEQ is trying to do (form a sequence based on the logical stop time of each sound in the sequence). The logical stop time of each segment is the STOP time of EXTRACT-ABS.

Probably the easiest solution is to create new sounds from the “S” data so that the sounds we are sequencing are not tied to the start / stop times of the sound “S”.
We can do this by copying the sample values into an array, then create a new sound from the array.

;version 4

(setf seclen (get-duration 1))
(setf seclen (truncate seclen))

;length of clips
(setf dur 0.5)
;length of clips in samples
(setf ln (truncate (* dur *sound-srate*)))

(defun rand-section(max-length)
  "Return random value between 0 and max-length"
  (* max-length (rrandom)))


(defun get-section(sig cue-time)
  "Create a new sound from SIG with a start time of CUE-TIME"
  (let* ((start (rand-section seclen))
         (stop (+ start dur))
         (segment (extract-abs start stop (cue sig))))
    (setf ar (snd-fetch-array (snd-copy segment) ln ln))
    (snd-from-array cue-time *sound-srate* ar)))

(simrep (i 5)
        (get-section *track* (* i dur)))

Thank you so much for your reply! Not only did you explain what was wrong with my use of the function and how to fix it, you corrected my program as well! I appreciate the convention tips as well.
Appreciate the help and now have a better understanding of how to use Nyquist and work with sound.