This is a little note for anyone just getting started in Nyquist. Like me. Perhaps this will save somebody some confusion and astonishment.
Consider the following code evaluated in Nyquist:
(setq envelope-var (pwl 1 1 1))
(display "envelope-var" (snd-extent (stretch 4.0 envelope-var) 1000000))
(defun envelope-fun () (pwl 1 1 1))
(display "envelope-fun" (snd-extent (stretch 4.0 (envelope-fun)) 1000000))
You might expect snd-extent to produce the same results for the two cases: we’re starting with the same envelope function (pwl 1 1 1) and stretching it by the same amount (stretch 4.0 ). Let’s see what happens:
envelope-var : (SND-EXTENT (STRETCH 4 ENVELOPE-VAR) 1000000) = (0 1)
envelope-fun : (SND-EXTENT (STRETCH 4 (ENVELOPE-FUN)) 1000000) = (0 4)
T
Oho! The extent of envelope-var ends at 1, the extent of (envelope-fun) ends at 4.
An expert should correct me if I’m wrong about this, but the crucial difference is when (pwl 1 1 1) is evaluated. For envelope-var, the pwl function is evaluated BEFORE stretch is called. In envelope-fun, pwl is evaluated within the context of the stretch. Behind the scenes, pwl looks at the global warp variable to determine its start and stop times (more accurately, the mapping between local and global times). So when pwl is evaluated to set envelope-var, stretch is not in effect, so the result isn’t subjected to stretching. On the other hand, when (envelope-fun) calls pwl, stretching is already in effect, so the result is properly stretched.
Moral: make sure you don’t evaluate a behavior until you’re in the correct evaluation context.
(uh, did I get that right?)