On Tue, Nov 30, 2010 at 10:58 PM, robert bristow-johnson
<r...@audioimagination.com> wrote:

> there is a theory that you can design (on the fly)
> optimal crossfade envelopes for any normalized correlation between 0 and 1.
> if you want, i can dig up the notes and equations about it.

I found it tempting enough to try and see if I would come up with the
same equations. :) So here goes, from my part...

For a time position t=0..1 inside the cross-fade, we would like to mix
the two signals, x faded in, y faded out, with gains that satisfy the
proportion gain_x/gain_y = t/(1-t). That is the same proportion as
with a linear fade, which we consider ideal in case the signals are
fully and positively correlated. We will consider the two cross-faded
signals as noise. The amplitude of noise is described by its standard
deviation, stddev_x and stddev_y in this case. For two (normally
distributed?) random variables x and y, there is an equation for the
standard deviation of their sum, given the standard deviations of the
individual random variables and the correlation coefficient R, which
can take values in range -1 (full negative correlation) to 0 (no
correlation) to 1 (full correlation):

stddev_x_plus_y = sqrt(stddev_x ^ 2 + stddev_y ^ 2 + 2 * R * stddev_x
* stddev_y)

That came straight out of the Wikipedia page "Sum of normally
distributed random variables".

If we take into account the gains that we apply, we must modify the
formula a bit:

stddev_mixed = sqrt((gain_x * stddev_x)^2 + (gain_y * stddev_y)^2 + 2
* R * gain_x * stddev_x * gain_y * stddev_y)

Now, if we again consider the behavior of the linear fade between two
fully and positively correlated signals, it will give:

stddev_mixed_linear_correlated = sqrt((t * stddev_x)^2 + ((1-t) *
stddev_y)^2 + 2 * 1 * t * stddev_x * (1-t) * stddev_y) = stddev_x * t
+ stddev_y * (1-t)

That looks correct. It's a linear fade between the amplitudes of the
two signals. We'd like to see the same for any value of R. So, we
write a constraint for gain_x and gain_y:

sqrt((gain_x * stddev_x)^2 + (gain_y * stddev_y)^2 + 2 * R * gain_x *
stddev_x * gain_y * stddev_y) = stddev_x * t + stddev_y * (1-t)

We wanted gain_x and gain_y to be related by gain_x/gain_y = t/(1-t),
so we can plug in gain_y = gain_x * (1-t) / t:

sqrt((gain_x * stddev_x)^2 + (gain_x * (1-t) / t * stddev_y)^2 + 2 * R
* gain_x * stddev_x * gain_x * (1-t) / t * stddev_y) = stddev_x * t +
stddev_y * (1-t)

That's quite a mess, but I managed to beat this out of it using
Wolfram Alpha (available on-line):

gain_x = (t * (stddev_x * t - stddev_y * t +stddev_y)) /
sqrt(stddev_x^2 * t^2 - 2 * stddev_x * stddev_y * R * t * (t-1) +
stddev_y^2 * (t-1)^2)

Quite a monster still. For stddev_x and stddev_y you could use the
square root of the sum of squared differences to the mean, calculated
from the samplepoints within the fade. However, normally you would
deal with signals that have the same amplitude, so we set stddev_y =
stddev_x, resulting in:

gain_x = t / sqrt(2 * t * (R + t - 1 - R * t) + 1)

That should be good enough for practical purposes. To calculate
gain_y, you'd replace t with 1-t. The last formula (and probably also
the previous one) works OK for values of R other than -1. You don't
have to have R >= 0. For uncorrelated noise signals, R calculated from
the samplepoints would be somewhere around 0, so it actually wouldn't
be that uncommon for it to be slightly negative.

-olli
--
dupswapdrop -- the music-dsp mailing list and website:
subscription info, FAQ, source code archive, list archive, book reviews, dsp 
links
http://music.columbia.edu/cmc/music-dsp
http://music.columbia.edu/mailman/listinfo/music-dsp

Reply via email to