Roger
Thanks for your very full response and improved/corrected version of
crossfadein.ny and crossfadeout.ny. I wasn't imagining that my approach was very
good (being a nyquist novice) and it's good to see it done properly.
Others
I had not realised that Roger's post had not gone to audacitydevel and
assumed that somebody else (who knows more about nyquist) would pick up on these
changes and make them. My mistake. I have now committed them, at this late
stage.
Martyn
In a message dated 16/10/2006 03:04:36 GMT Daylight Time, rbd@...
writes:
Yes, there's a problem with crossfadein.ny
Martyn's fix will work, but I think it's not the best approach.
Currently, the code is basically this:
(setq a (diff (const 1) (ramp 1)))
(mult s (diff (const 1) (mult a a)))
The problem is that CONST is computed at the default control rate of
2205Hz, so the last 1/2205 seconds of the CONST signal is a ramp to zero
rather than 1. RAMP is a special case and doesn't have this problem. The
simplest fix is to use 1 instead of (CONST 1):
(setf a (sum 1 (scale 1 (ramp 1))))
(mult s (sum 1 (scale 1 (mult a a))))
But this now has the problem that A is a global variable that will
accumulate samples. At 2205 * 4 = 8820 bytes/second, that may not be a
problem, but it sets a bad example, so let's make A a local variable.
The full plugin text is below (but read on, I'm not done):
;nyquist plugin
;version 2
;type process
;name "Cross Fade In"
;action "CrossFading In..."
(let ((a (sum 1 (scale 1 (ramp 1)))))
(mult s (sum 1 (scale 1 (mult a a)))))
Finally, where did this function come from? It looks a bit like an equal
power law, but it's not, so I wonder if that's a mistake.
Theory: assume you are crossfading from one signal to another and both
have the same constant power, and they are decorrelated enough that
there is no outofphase cancellation or inphase construction. Then the
power of the mix is the sum of the input powers, which are proportional
to the squares of the input amplitudes. So if x varies from 0 to 1
through the crossfade, and f(x) is the crossfade function, we want
f(x)^2 + (1  f(x)^2) = 1. This is satisfied by f(x) = sqrt(x). Although
there are an infinite number of other solutions, I think this is the
most common.
If the goal was to make an equalpower crossfade function, the plugin
should be the following:
;nyquist plugin
;version 2
;type process
;name "Cross Fade In"
;action "CrossFading In..."
(mult s (sndexp (sndscale 0.5 (sndlog (ramp)))))
This code can be simplified to
(mult s (sndsqrt (ramp)))
when Audacity updates to the latest version of Nyquist.
The matching crossfadeout.ny plugin is:
;nyquist plugin
;version 2
;type process
;name "Cross Fade Out"
;action "CrossFading Out..."
(mult s (sndexp
(sndscale 0.5 (sndlog
(sum 1 (sndscale 1 (ramp)))))))
Roger
Begin forwarded message:
> From: MartynShaw@...
> Date: October 7, 2006 2:22:44 PM PDT
> To: audacitydevel@...
> Subject: Re: [Audacitydevel] moving clips when selected + crossfade
> ReplyTo: audacitydevel@...
>
> ...
>>> 2. working with windows you can use effects > fade (in/out) *and*
> effects >
>>> crossfade (in/out). is there any difference? and: users who like to
> create a
> ...
>
> I've never had chance/excuse to look at Nyquist before but I think I
can see
> where the nasty click at the end of the fadein is coming from
(testing on a
> generated tone), and how to fix it, but I am not convinced it's the
way to go.
>
> If I read the manual correctly at
> _http://www.cs.cmu.edu/~rbd/doc/nyquist/part6.html#index362_
(http://www.cs.cmu.edu/~rbd/doc/nyquist/part6.html#index362)
> , in crossfadein.ny
> (ramp 1)
> generates a ramp with a length 1s and the sample rate of
*controlsrate*.
> This appears to be 2205Hz, although I don't see where this is set.
After
> further processing this signal is multiplied by the audio, which is at a
> different sampling rate (normally!), and so the processed ramp is
upsampled, leading
> to a nasty on the last 20 samples (if the audio is at 44100Hz).
>
> One fix is to do, in crossfadein.ny could read
> (controlsrateabs *soundsrate* (setq a (diff (const 1) (ramp 1))))
> (controlsrateabs *soundsrate* (mult s (diff (const 1) (mult a a))))
> or
> (setcontrolsrate *soundsrate*)
> (setq a (diff (const 1) (ramp 1)))
> (mult s (diff (const 1) (mult a a)))
>
> Am I right here? Any nyquist experts out there?
> Martyn
