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