Attempt of an answer…
Example 1
(setq mysound (sim s (at 0.5 (cue s))))
(stretch-abs 1 (cue mysound))
steve: If the length of “s” is L, then the length of “mysound” is 1.5(L)
(stretch-abs 1 …) does not stretch the sound to 1 second, it maps each unit of logical time maps to 1 unit of real time.
edgar: attempt of an explanation…
;; The first line is computed with the global *warp* time-stretch,
;; where a value of 1.0 equals to the length of the Audacity sound.
;; The start-time of (AT 0.5 ...) will be:
;; 0.5 * <length-of-Audacity-sound>
;; SIM will produce a sound with a total length of:
;; 1.5 * <length-of-Audacity-sound>
;;
(setq mysound (sim s (at 0.5 (cue s))))
;; Here the *warp* time-stretch value to (cue mysound) is 1.0,
;; where the value of 1.0 equals to the length of one second.
;; The (cue mysound) object already has a length of 1.5 seconds,
;; so the sound object returned by (stretch-abs 1 ...) will have
;; a total length of 1.0 * 1.5 seconds.
;;
(stretch-abs 1 (cue mysound))
Until here we have a sound with a total length of 1.5 seconds. But when the 1.5-seconds sound gets returned to Audacity, the build-in STRETCH-ABS in the Audacity Nyquist interface will stretch the 1.5-seconds sound to ‘1.5 * ’, so the effective code from the Audacity perspective works like this:
(stretch-abs <length-of-Audacity-sound>
(setq mysound (sim s (at 0.5 (cue s)))))
(stretch-abs <length-of-Audacity-sound>
(stretch-abs 1 (cue mysound)))
That’s why, as the final result, a sound with a length of ‘1.5 * ’ will get inserted into the Audacity track.
The problem here is: Because of the build-in STRETCH-ABS in the Audacity Nyquist interface, to the Nyquist programmer it seems as if STRETCH-ABS produces ‘mysterious’ results when used in Audacity Nyquist plugin code.
To me myself, understanding the effects caused by the build-in WARP and STRETCH-ABS behaviours in the Audacity Nyquist interface was the most difficult part when I tried to find out how to work with Nyquist in Audacity some years ago, but once I understood how this works, the mystery of the Nyquist time behaviours had been disappeared…
Example 2
(defun mysound (s-in)
(sim s (at 0.5 (cue s-in))))
(stretch-abs 1 (mysound s))
steve: (stretch-abs …) is applied to the (mysound) function,
which means that the “0.5” in the (at 0.5 …) function is mapped to 0.5 seconds.
So the length of the returned audio is L + (0.5 seconds)
edgar: again an attempt of some kind of explanation…
;; The MYSOUND function is called by STRETCH-ABS [below]
;; with a the *warp* time-stretch value of 1.0 seconds.
;; The start-time of (AT 0.5 ...) will be:
;; 0.5 * 1.0 seconds
;; SIM will produce a sound with a total length of:
;; <length-of-Audacity-sound> + (0.5 * 1.0) seconds
;;
(defun mysound (s-in)
(sim s (at 0.5 (cue s-in))))
;; Here (stretch-abs 1 ...) stretches (mysound s) to a length of
;; 1.0 * (<length-of-Audacity-sound> + 0.5 seconds)
;;
(stretch-abs 1 (mysound s))
With the ‘defun’ call resolved, the code from the Audacity perspective looks like this:
(stretch-abs <length-of-Audacity-sound>
(stretch-abs 1 (sim s (at 0.5 (cue s-in))))
Here again, the stretch effect of (stretch-abs 1 …) gets counter-acted by the build-in STRETCH-ABS in the Audacity Nyquist interface.
Considerations
The problem with the build-in WARP and STRETCH-ABS is not so easy as one might think:
When using Nyquist for music composition [that’s what Nyquist was made for] or in Audacity in ‘generate’ plugins, imagine a simple Nyquist code line like:
(osc 60)
A Nyquist programmer expects this code to produce a sound with the exact length of the Audacity selection, but this is only possible if the warp time-stretch value is bound to the length of the Audacity selection, so the resulting sound can be stretched to a fitting length by the build-in STRETCH-ABS function in the Audacity Nyquist interface.
With a warp time-stretch value bound to 1.0 seconds and without the build-in STRETCH-ABS function the code from above would have the effect that the Audacity selection would be changed by the plugin code to a length of one second as soon as the sound gets returned to Audacity, what is clearly not the result that an Audacity user expects from using a Nyquist plugin.
So the build-in WARP and STRETCH-ABS are twofold, they are very useful for music composition and Audacity ‘generate’ plugins, but on the other side you have to be very careful if you try to time-shift parts of an Audacity selection in Nyquist ‘process’ plugins [Audacity ‘Effect’ menu].
The warp variable has a second important purpose, it synchronizes the time behaviour of sounds and envelopes, which in Nyquist have different sample-rates. But this is a different discussion, it has nothing to do with the questions above, but is also important to know and to keep in mind.
Preliminary Conclusion
I think it would be very helpful to develope or document some ‘standard strategies’ for using time behaviours in Audacity ‘process’ plugins. Here are some ideas I used in the past in several plugins.
If you need behaviours in seconds, Roger suggested to use the Nyquist ABS-ENV macro:
(abs-env (osc 60))
This will produce a sine-wave of exactly one second length, but it will also produce the nasty effect of changing the length of the Audacity selection as soon as the sound gets returned to Audacity. But ABS-ENV could help to solve the problems with AT. There are also some other ABS functions like AT-ABS etc., which also must be investigated for their exact behaviour in Audacity.
Warning: the one-second example has turned out to be nonsense, see below…
A way to compute a ‘real second’ with Nyquist in Audacity:
;; len (get-duration 1.0)
;; ------------- = ------------------
;; *sound-srate* *one-second*
(setq *one-second* (/ len (* *sound-srate* (get-duration 1.0))))
If you copy the following code into the text window of the Audacity Nyquist prompt:
(setq *one-second* (/ len (* *sound-srate* (get-duration 1.0))))
(stretch-abs *one-second* (osc 60))
It will produce the same result like ABS-ENV above.[/color]
Any further ideas? What are the most difficult problems in practical Nyquist programming with Audacity?