To avoid nasty click-sounds at the beginning or end, a Nyquist envelope is defined as always to start and end with a zero-sample. Because your envelope ends with 1.0, Nyquist adds a fade to zero at the end.
The solution is described in the Nyquist manual under Piece-wise Linear Functions
If you really want a linear ramp to reach its final value at the specified time, you need to make a signal that is one sample longer.
But this reads easier than it really is, because "pwl" envelopes are computed with *control-srate* (in Audacity always 44100/20=2205Hz), not with *sound-srate* (the sample rate of the Audacity track). That's the reason why the zero-fade at the end is more than one sample long. One sample in *control-srate* are several samples in *sound-srate*.
Below is a "fade" function where you can give "fade-out" (at the beginning) and "fade-in" (at the end) with times in seconds. If no "fade-in" time is given, then the "fade-in" at the end will be the same time as the "fade-out" at the beginning.
Code: Select all
(defun fade (sound fade-out &optional fade-in)
(let* ((seconds (/ len *sound-srate*)) ; length of sound in seconds
(end-out (/ fade-out seconds)) ; end of fade-out in Nyquist time
(start-in (- 1.0 (if fade-in ; start of fade-in in Nyquist time
(/ fade-in seconds)
(len+1 (* (/ 1.0 len) (1+ len)))) ; Nyquist time at len + 1 sample
(progv '(*control-srate*) (list *sound-srate*)
(mult sound (pwl 0.0 1.0 end-out 0.0 start-in 0.0 1.0 1.0 len+1)))))
"progv" sets *control-srate* temporarily to *sound-srate*, so the "pwl" envelope gets computed with *sound-srate* precision.
Code: Select all
(fade s 0.2 0.5) ; 0.2 seconds fade-out, 0.5 seconds fade-in
(fade s 0.3) ; 0.3 seconds fade-out, 0.3 seconds fade-in
Note that currently there is no check if "fade-in" + "fade-out" together are longer than the sound itself, so "pwl" will compute nonsense in this case.