Nyquist do* does not return audio

I’m trying to generate a bunch of sine waves at different frequencies each followed by silence

(do* (i 500 (setq i (500 + i)))                            ; DO* loop with var I
  ((eql i 2500) (stretch-abs 200.0 (hzosc 2500)))                ;   test and result
    (stretch-abs 200.0 (hzosc i)) (const 0.0 [120]))

When I run this, audacity tells me “Nyquist did not return audio” I don’t see what I am doing wrong here. I checked the syntax and that’s right (as far as I can tell)

Hi, and welcome to the forum. I’ll move this topic to the main “Nyquist” page as it isn’t actually a plug-in (yet).

Some notes on your code:

You don’t need ‘setq’ in the above line, but you do need annother ‘(’ at the start of the bindings. XLISP do*

(do* ((i 500 (+ 500 i)))

You can use “=” here

((= i 2500) (stretch-abs 200.0 (hzosc 2500)))

and probably don’t need to use “stretch-abs”, but see below

What are the square brackets? They are not legal.
In the manual Nyquist Functions
the notation: (const value [duration]) means that duration is an optional argument. You don’t use the square brackets.
For example, if you want to generate 3 seconds of silence (in a “generate” plug-in)

(const 0 3)

or in a “process” effect it could be:

(abs-env (const 0 3))

but note that this is generated at the control rate control-srate

Rather than using const to generate silence, you can use s-rest

(s-rest 3)

My question is, what exactly are you trying to do in this line:

Hi Steve, a little correction, the step increase has to be:

(do* ((I 500 (+ 500 i)))

for e.g. counting upwards from 500 to 2500 in 500-steps.
I think that one should rather use
seqrep instead.
The main line had to accumulate the sounds anyway, e.g.

(setf snd (seq snd (seq (hzosc ...) (s-rest 3))))

and snd would be returned as the result.
And of course all embedded in abs-env to make the sound independent from the selection.

Thanks Robert, a typo on my part. I’ve corrected my previous post.

Not necessary if it is a “generate” type plug-in.
“process” plug-ins automatically stretch the environment according the the selection length, but “generate” plug-ins don’t. (This is one of the main reasons why I would like Audacity to have a “Nyquist Generate Prompt” effect built in, in addition to the “Nyquist Prompt” effect.)

I assumed the nyquist prompt when I was referring to the abs-env since the effect has no plug-in header yet.

Am I mistaken or isn’t there a Nyquist Generate Prompt already posted by Edgar?
A goody would be to be able to generate an arbitrary number of tracks at the same call.
This would be nice for the analyse menu too however (to e.g. split a track in different frequency bands or to extract a certain informative curve).

Yes there is (and updated by myself), but it is implemented as a Nyquist plug-in, with all the limitations that that entails.
It is actually very easy to implement as a built-in effect, but was considered to be too esoteric for mainstream release.

Thanks! I don’t believe how much I misread that…

I’m trying to generate 200 s of a monotone at frequency i (which varies) followed by 120 s of silence and then monotone at a new frequency again.

You were not far off :wink:

Using a similar code structure:

(abs-env  ; required if used in the 'Nyquist Prompt' effect.
  (let ((result 0)) ; You cannot sum to NIL
    (do* ((hz 500 (+ 500 hz))
          (start 0 (+ 400 start)))
         ((= hz 2500) result) ; stop at 2500 and return 'result'
      (setf result
        (sum result
             ; OSC provides a 'duration' argument.
             (at start (osc (hz-to-step hz) 200)))))))

Note that the silence is implied by specifying the start time for each tone rather than generating silence.
If you want 200 seconds of silence at the end, you could have:

(abs-env  ; required if used in the 'Nyquist Prompt' effect.
  (let ((result 0)) ; You cannot sum to NIL
    (do* ((hz 500 (+ 500 hz))
          (start 0 (+ 400 start)))
         ((= hz 2500) result) ; stop at 2500 and return 'result'
      (setf result
        (sum result
             ; OSC provides a 'duration' argument.
             (at start (osc (hz-to-step hz) 200))
             (at start (s-rest 400)))))))

Note that this will stop when (= hz 2500). If you want the final tone to be 2500 Hz, then use (> hz 2500).

As Robert wrote, for this case it would probably be better to use SEQREP Nyquist Functions
Something like:

(setq initial-hz 500)
(setq final-hz 2500)
; number of times to repeat must be an integer
(setq repeats (truncate (/ limit-hz final-hz)))

  (seqrep (i repeats) (sim (s-rest 400)
                           (osc (hz-to-step (* (1+ i) 500)) 200))))