I am working on an audio system where I need to implement an equal power crossfade between two signals over a specified number of samples. Initially I implemented a linear fade but this creates a dip in the middle of the crossfade which I don't want. I tried a few other methods that I found on Google but they either make a dip in another part of the curve or even make the sound louder.

If I have float samples ranging from -1.0 to 1.0 and I want to crossfade between them over the course of x samples, keeping the perceived volume the same over the entire crossfade, what would be the correct formula for calculating the curve? Preferably I want to have a value like 0.001 represent the minimum level that the fade in starts at and the fade out goes to. 1.0 should be the maximum. Thanks in advance for any advice!

if the two audio signals are totally uncorrelated, the the squares of the two crossfade gains should add to 1. so, to prevent that dip, your crossfade function will look more like $\sqrt{\frac{1}{2}(1+t)}$ and $\sqrt{\frac{1}{2}(1-t)}$ rather than $\frac{1}{2}(1+t)$ and $\frac{1}{2}(1-t)$ for $-1 \le t \le +1$. note, for constant power crossfades, at the midpoint of the crossfade ($t=0$), both crossfade gains are at $\sqrt{\frac{1}{2}} \approx 0.707$ rather than at $\frac{1}{2}$. that's what addresses the dip you want to avoid.

if your two audio signals are somewhere between totally uncorrelated and totally correlated, you need to determine the degree of correlation (that's what cross-correlation is all about), and then the crossfade functions can be determinied analytically. i have posted to music-dsp a little theory about it. it's not perfectly rigorous, but i think it works.

• Thanks for the detailed reply! I must confess though that this is a little above my head. I don't know how I might determine correlation and how then to calculate a factor by which to multiply my samples. Would you possibly be able to show some pseudo code? Assuming buf1 and buf2 contain my samples, samples specifies the number of samples that the entire crossfade should take and min_level specifies the silence level that I have determined (probably something like 0.001). Given those parameters, how might one write a function to perform crossfades on arbitrary signals? – Philip Bennefall Mar 2 '14 at 17:52
• I should perhaps also mention that I don't have access to the entire audio segment when I start the crossfade, I process it in chunks that are not known until right before that chunk must be processed. Given that, what is my best bet for a generalized algorithm? – Philip Bennefall Mar 2 '14 at 17:58
• think of the cross-correlation with a lag of 0 as a dot product or, more generally, an inner product: $$R_{xy} = \sum_n x[n] \ y^*[n] \ w[n-k]$$ $w[n-k]$ is a window function to localize the summation to the neighborhood of sample $k$. – robert bristow-johnson Mar 2 '14 at 20:49
• I'm using what's known as a screen reader (a program used to read the screen if you're blind), and it's having a lot of trouble with the symbols in the formulae. Would you possibly be able to update your answer with some C style code or pseudo code to show the procedure? In particular, I don't understand with what factor to multiply each sample to get the desired curve. – Philip Bennefall Mar 3 '14 at 7:40
• I also don't find math notation readable. – NateS Aug 24 '16 at 7:02

As people in the other answer have been asking for a code snippet (and as I don't have enough reputation to comment on answers), here's the other answer implemented in C# (which should be easy enough to convert to other languages)

/*
returns a float array with two indexes representing the volumes of the left (index 0) and right (index 1) channels
when t is -1, volumes = 0, volumes = 1
when t = 0, volumes = 0.707, volumes = 0.707 (equal-power cross fade)
when t = 1, volumes = 1, volumes = 0
*/

float[] volumes = new float;
volumes = Math.Sqrt(0.5f * (1f + t));
volumes = Math.Sqrt(0.5f * (1f - t));
return volumes;
}

• well, i added 10 to your rep. i think you can comment to your own answer, no? – robert bristow-johnson Jan 8 '17 at 3:43

This is a continuation of the (music-dsp) thread started by Element Green titled: "Algorithms for finding seamless loops in audio"

As far as I know, it is not published anywhere, although I have recently been informed that a similarly-themed paper by Marco Fink, Martin Holters, and Udo Zölzer has been presented at the 2016 DAFx conference, which is a while after I first "weblished" the theory below. A few years ago, I was thinking of writing this up and publishing it (or submitting it for publication, probably to JAES), and had let it fall by the wayside. I'm "publishing" the main ideas here on StackExchange (and earlier on music-dsp list) because of some possible interest here (and the hope it might be helpful to somebody), and so that "prior art" is established in case of anyone like IVL is thinking of claiming it as their own. I really do not know how useful it will be in practice. It might not make any difference. It's just a theory.

## Introduction:

This is about the generalization of the different ways we can splice and crossfade audio that has these two extremes:

1. Splicing perfectly coherent and correlated signals
2. Splicing completely uncorrelated signals

I sometimes call the first case the "equal-voltage crossfade" because the crossfade envelopes of the two signals being spliced add up to one. The two envelopes meet when both have a value of $\frac12$. In the second case, we use an "equal-power crossfade", the square of the two envelopes add to one and they meet when both have a value of $\sqrt{\frac12}=$ 0.707 .

The questions I wanted to answer are:

• What does one do for cases in between, and how does one know from the audio, which crossfade function to use?
• How does one quantify the answers to these questions?
• How much can we generalize the answer?

## Set up the problem:

We have two continuous-time audio signals, $x(t)$ and $y(t)$, and we want to splice from one to the other at time $t=0$. In pitch-shifting or time-scaling or any other looping, $y(t)$ can be some delayed or advanced version of $x(t)$.

e.g. $y(t) = x(t+P)$

where $P$ is a period length or some other "good" splice displacement. We get that value, $P$, from an algorithm we call a "pitch detector".

Also, it doesn't matter whether $x(t)$ is getting spliced to $y(t)$ or the other way around, it should work just as well for the audio played in reverse. And it should be no loss of generality that the splice happens at $t=0$, we define our coordinate system any damn way we damn well please.

The signal resulting from the splice is

$$v(t) = a(t)y(t) \, + \, a(-t)x(t)$$

By restricting our result to be equivalent if run either forward or backward in time, we can conclude that "fade-in" function (say that's $a(t)$) is the time-reversed copy of the "fade-out" function, $a(-t)$.

For the correlated case (equal-voltage crossfade): $a(t) + a(-t) = 1 \qquad \forall t$

For the uncorrelated case (equal-power crossfade): $a^2(t) + a^2(-t) = 1 \qquad \forall t$

This crossfade function, $a(t)$, has well-defined even and odd-symmetry parts:

$$a(t) = a_\mathrm{e}(t) + a_\mathrm{o}(t)$$

where

\begin{align} \text{even part:} \qquad a_\mathrm{e}(t) = a_\mathrm{e}(-t) &= \tfrac12 \big( a(t) + a(-t) \big) \\ \\ \text{odd part:} \qquad a_\mathrm{o}(t) = -a_\mathrm{o}(-t) &= \tfrac12 \big( a(t) - a(-t) \big)\\ \end{align}

And it's clear that

$$a(-t) = a_\mathrm{e}(t) - a_\mathrm{o}(t) \ .$$

For example, if it's a simple "linear crossfade" (equivalent to splicing analog tape with a diagonally-oriented razor blade):

$$a(t) = \begin{cases} 0 & \text{for } t \le -1 \\ \\ \tfrac{1}{2}(1+t) & \text{for } -1 \le t \le +1 \\ \\ 1 & \text{for } t \ge +1 \\ \end{cases}$$

This is represented simply, in the even and odd components, as:

\begin{align} a_\mathrm{e}(t) &= \tfrac12 \\ \\ a_\mathrm{o}(t) &= \begin{cases} \tfrac12 t & \text{for } |t| \le +1 \\ \\ \tfrac12 \operatorname{sgn}(t) & \text{for } |t| \ge +1 \\ \end{cases} \\ \end{align}

where $\operatorname{sgn}(t)$ is the sign function:

$$\operatorname{sgn}(t) \triangleq \begin{cases} -1 & \text{for } t < 0 \\ 0 & \text{for } t = 0 \\ 1 & \text{for } t > 0 \\ \end{cases}$$

a shorthand: $\operatorname{sgn}(t) = \frac{t}{|t|}$ .

This is an equal-voltage crossfade, appropriate for perfectly correlated signals; $x(t)$ and $y(t)$. There is no loss of generality by defining the crossfade to take place around $t=0$ and have two time units in length. Both are simply a matter of offset and scaling of time.

Another equal-voltage crossfade would be what I might call a "Hann crossfade" (after the Hann window):

\begin{align} a_\mathrm{e}(t) &= \tfrac12 \\ \\ a_\mathrm{o}(t) &= \begin{cases} \tfrac12 \sin(\tfrac{\pi}{2}t) & \text{for } |t| \le +1 \\ \\ \tfrac12 \operatorname{sgn}(t) & \text{for } |t| \ge +1 \\ \end{cases} \\ \end{align} Some might like that better because the derivative is continuous everywhere. Extending this idea, one more equal-voltage crossfade is what I might call a "Flattened-Hann crossfade":

\begin{align} a_\mathrm{e}(t) &= \tfrac12 \\ \\ a_\mathrm{o}(t) &= \begin{cases} \tfrac{9}{16} \sin(\tfrac{\pi}{2}t) + \tfrac{1}{16} \sin(\tfrac{3\pi}{2}t) & \text{for } |t| \le +1 \\ \\ \tfrac12 \operatorname{sgn}(t) & \text{for } |t| \ge +1 \\ \end{cases} \\ \end{align}

This splice is everywhere continuous in the zeroth, first, and second derivative. A very smooth crossfade.

As another example, an equal-power crossfade would be the same as any of the above, but where the above $a(t)$ is square rooted:

$$a(t) = \begin{cases} 0 & \text{for } t \le -1 \\ \\ \sqrt{\tfrac12(1+t)} & \text{for } -1 \le t \le +1 \\ \\ 1 & \text{for } t \ge +1 \\ \end{cases}$$

This is what we might use to splice to completely uncorrelated signals together. We can separate this into even and odd parts as:

\begin{align} a_\mathrm{e}(t) &= \begin{cases} \tfrac12\left(\sqrt{\tfrac12(1+t)} + \sqrt{\tfrac12(1-t)}\right) & \text{for } |t| \le +1 \\ \\ \tfrac12 & \text{for } |t| \ge +1 \\ \end{cases} \\ \\ a_\mathrm{o}(t) &= \begin{cases} \tfrac12\left(\sqrt{\tfrac12(1+t)} - \sqrt{\tfrac12(1-t)}\right) & \text{for } |t| \le +1 \\ \\ \tfrac12 \operatorname{sgn}(t) & \text{for } |t| \ge +1 \\ \end{cases} \\ \end{align}

## Which crossfade function to use?

Now we shall make a definition and an assumption. We shall define an inner product of two general signals as:

$$\langle x,y \rangle \triangleq \langle x(t),y(t) \rangle = \int\limits_{-\infty}^{\infty} x(t) \cdot y(t) \, \cdot \, w(t) \ \mathrm{d}t$$

$w(t)$ is a window function that is symmetrical about $t=0$ and is probably wider than the crossfade. Strictly speaking, if you were coming at this from out of a graduate course in metric spaces or functional analysis, one of the components (probably $y(t)$) should be complex conjugated, but since $x(t)$ and $y(t)$ are always real, in this whole theory, I will not bother with that notation. This means, only in this context, that the inner product is commutable:

$$\langle x,y \rangle = \langle y,x \rangle$$

This inner product is a degenerate case of the more general cross-correlation evaluated with a lag of zero:

$$R_{xy}(\tau) \triangleq \langle x(t),y(t+\tau) \rangle = \int\limits_{-\infty}^{\infty} x(t) \cdot y(t+\tau) \, \cdot \, w(t) \ \mathrm{d}t$$

If $y(t)$ is a time-offset copy of $x(t)$, then $R_{xy}(\tau)$ is the autocorrelation of $x(t)$, or $R_{xx}(\tau)$, but also accounting for the time offset in the lag, $\tau$.

So $$\langle x,y \rangle = R_{xy}(\tau) \bigg|_{\tau=0} = R_{xy}(0)$$

A measure of signal energy or average power is:

$$R_{xx}(0) \triangleq \langle x,x \rangle = \int\limits_{-\infty}^{\infty} \big( x(t) \big)^2 \, \cdot \, w(t) \ \mathrm{d}t$$

Now, the assumption that we are going to toss in here is that the mean power of the two signals that we are crossfading, $x(t)$ and $y(t)$, are equal.

$$\langle x,x \rangle = \langle y,y \rangle$$

We are assuming that we're not crossfading this very quiet tone or sound to a very loud sound that is 60 dB louder. Similarly, the resulting spliced sound, $v(t)$, has the same mean power of the two signals being spliced:

$$\langle v,v \rangle = \langle x,x \rangle = \langle y,y \rangle$$

So, assuming we lined up $x(t)$ and $y(t)$ so that we want to splice from one to the other at $t=0$, and scaled $x(t)$ and $y(t)$ so that they have the same mean power in the neighborhood of $t=0$, then the inner product is a measure of how well they are correlated. We shall define this normalized measure of correlation as:

$$r \triangleq \frac{\langle x,y \rangle}{\langle x,x \rangle} = \frac{\langle x,y \rangle}{\langle y,y \rangle}$$

If $r=1$, they are perfectly correlated and if $r=0$, they are completely uncorrelated.

We will make the additional assumption that our pitch detection algorithm will find some lag, $P$, where the correlation is at least zero correlated. We should not have to deal with splicing negatively correlated audio (that would have quite a "glitch" or a bad splice). If the two signals, $x(t)$ and $y(t)$, have no DC component, then their autocorrelations and their cross-correlations to each other must have no DC component. That means there will be values of $\tau$ such that $R_{xy}(\tau)$ are either negative or positive. If it was theoretical white noise, $R_{xx}(\tau)$ would be zero for $|\tau| > 0$ and $R_{xx}(0)$ would be the noise variance or power. But $R_{xx}(\tau)$ cannot be negative for all values of $\tau$, even for all values of $\tau \ne 0$.

For the splicing done in a time-domain pitch shifting or time scaling algorithm, we can find a value of $\tau$ so that $R_{xx}(\tau)$ is non-negative and we want to choose $\tau = P$ (the measured period) so that has the highest value of $R_{xx}(\tau)$. Then define

$$y(t) = x(t+P)$$

and then

$$\langle x,y \rangle = R_{xy}(0) = R_{xx}(P)$$

Now we shall also assume that the crossfade function, $a(t)$, is completely uncorrelated and even statistically independent from the two signals being spliced. $a(t)$ is a volume control that varies in time, but is unaffected by anything in $x(t)$ or $y(t)$.

We shall also assume something called "ergodicity". This means that time averages of $x(t)$ and $y(t)$ (or functions of or combinations of $x(t)$ and $y(t)$)are equal to statistical averages. If this window, $w(t)$ is scaled (or normalized) so that its integral is 1,

$$\int\limits_{-\infty}^{\infty} w(t) \ \mathrm{d}t = 1$$

then all these inner products (which are time averages) can be related to "expected values" (which are statistical or probabilistic averages):

\begin{align} \langle x,y \rangle &= \int\limits_{-\infty}^{\infty} x(t) \cdot y(t) \, \cdot \, w(t) \ \mathrm{d}t \\ &= \operatorname{E}\Big[x(t) \cdot y(t)\Big] \\ \end{align}

If $x(t)$ and $y(t)$ are thought of as sorta "random" processes (rather than well defined deterministic functions), the expected value is unmoved no matter what $t$ is. But if the envelope $a(t)$ is considered deterministic, then it simply scales $x(t)$ or $y(t)$ and is treated as a constant in the expected value. So at some particular time $t_0$,

\begin{align} \langle a(t_0)\cdot x,y \rangle &= \operatorname{E}\Big[a(t_0)\cdot x(t) \cdot y(t)\Big] \\ &= a(t_0)\cdot \operatorname{E}\Big[x(t) \cdot y(t)\Big] \\ &= a(t_0)\cdot \langle x,y \rangle \\ \end{align}

This is a little sloppy, mathematically, because I am "fixing" $t$ for $a(t)$ to be $t_0$, but not fixing $t$ for $x(t)$ or $y(t)$ (so that "time averages" for $x(t)$ and $y(t)$ can be meaningful and equated to statistical averages).

Recall that

$$v(t) = a(t)y(t) \, + \, a(-t)x(t)$$

Then:

\begin{align} \langle v,v \rangle &= \Big\langle \big(a(t)y(t)+a(-t)x(t)\big),\big(a(t)y(t)+a(-t)x(t)\big) \Big\rangle \\ \\ &= \Big\langle \big(a(t)y+a(-t)x\big),\big(a(t)y+a(-t)x\big) \Big\rangle \\ \\ &= \Big\langle a(t)y,\big(a(t)y+a(-t)x\big) \Big\rangle + \Big\langle a(-t)x,\big(a(t)y+a(-t)x\big) \Big\rangle \\ \\ &= a(t)\Big\langle y,\big(a(t)y+a(-t)x\big) \Big\rangle + a(-t) \Big\langle x,\big(a(t)y+a(-t)x\big) \Big\rangle \\ \\ &= a(t) \left( \big\langle y,a(t)y \big\rangle + \big\langle y,a(-t)x \big\rangle \right) + a(-t) \left( \big\langle x,a(t)y \big\rangle + \big\langle x,a(-t)x \big\rangle \right) \\ \\ &= a(t) \left( a(t)\big\langle y,y \big\rangle + a(-t)\big\langle y,x \big\rangle \right) + a(-t) \left( a(t)\big\langle x,y \big\rangle + a(-t)\big\langle x,x \big\rangle \right) \\ \\ &= a^2(t)\langle y,y \rangle + 2a(t)a(-t)\langle x,y \rangle + a^2(-t)\langle x,x \rangle \\ \end{align}

Since $\langle v,v \rangle = \langle x,x \rangle = \langle y,y \rangle$, we can divide both sides of the above equation by $\langle v,v \rangle$ and get to the key equation of this whole theory:

$$1 \ = \ a^2(t) \ + \ 2r \,a(t)a(-t) \ + \ a^2(-t)$$

Given the normalized correlation measure, we want the above equation to be true all of the time. If $r=0$ (completely uncorrelated), one can see we get an equal-power crossfade:

$$a^2(t) + a^2(-t) = 1$$

If $r=1$ (completely correlated), one can see that we get an equal-voltage crossfade:

$$a^2(t) + a^2(-t) + 2a(t)a(-t) = \big( a(t)+a(-t) \big)^2 = 1$$

or, assuming $a(t)$ is non-negative,

$$a(t) + a(-t) = 1 .$$

Recall that

\begin{align} a(t) &= a_\mathrm{e}(t) + a_\mathrm{o}(t) \\ \\ a(-t) &= a_\mathrm{e}(t) - a_\mathrm{o}(t) \\ \end{align}

and substituting into

$$a^2(t) \ + \ a^2(-t) \ + \ 2r \,a(t)a(-t) \ = \ 1$$

results in

$$\big(a_\mathrm{e}(t) + a_\mathrm{o}(t)\big)^2 \ + \ \big(a_\mathrm{e}(t) - a_\mathrm{o}(t)\big)^2 \ + \ 2r \,\big(a_\mathrm{e}(t) + a_\mathrm{o}(t)\big)\big(a_\mathrm{e}(t) - a_\mathrm{o}(t)\big) \ = \ 1$$

Blasting through that gets:

$$(1+r)a_\mathrm{e}^2(t) + (1-r)a_\mathrm{o}^2(t) \ = \ \tfrac12$$

This means that, if $r$ is measured and known (from the correlation function) we have the freedom to define either one of $a_\mathrm{e}(t)$ or $a_\mathrm{o}(t)$ arbitrarily (as long as the even or odd symmetry is kept) and solve for the other. We can see that square rooting is involved in solving for either $a_\mathrm{e}(t)$ or $a_\mathrm{o}(t)$ and there is an ambiguity for which sign to pick. We shall resolve that ambiguity by adding the additional assumption that the even-symmetry component, $a_\mathrm{e}(t)$, is non-negative.

$$a_\mathrm{e}(t) = a_\mathrm{e}(-t) \ge 0$$

Given a general and bipolar odd-symmetry component function,

$$a_\mathrm{o}(t) = -a_\mathrm{o}(-t)$$

then we solve for the even component (picking the non-negative square root):

$$a_\mathrm{e}(t) = \sqrt{ \frac{1}{2(1+r)} - \frac{1-r}{1+r} \, a_\mathrm{o}^2(t) }$$

The overall crossfade envelope would be

\begin{align} a(t) &= a_\mathrm{e}(t) \ + \ a_\mathrm{o}(t) \\ \\ &= \sqrt{ \frac{1}{2(1+r)} - \frac{1-r}{1+r} \, a_\mathrm{o}^2(t) } \ + \ a_\mathrm{o}(t) \\ \end{align}

## Implementation:

Given a particular form for the odd part, $a_\mathrm{o}(t)$ (linear or Hann or Flattened-Hann or whatever is your heart's desire), and for a variety of values of $r$, $0 \le r \le 1$, a collection of envelope functions, $a(t)$, are pre-calculated and stored in memory. Then, when pitch detection or loop matching is done, a splice displacement that is optimal is determined, and if autocorrelation of some form is used in determining a measure of goodness (or "seamlessness", using Element Green's language) of that loop splice, that autocorrelation is normalized (by dividing by $R_{xx}(0)$) to get $r$ and that value of $r$ is used to choose which pre-calculated $a(t)$ from the above collection is used for the crossfade in the splice.

• i might like some comment from anyone, but especially Olli Niemitalo, MattL. and Jazzmaniac, but anyone else that has fiddled with correlation and cross-correlation and is about as rigorous or more rigorous with the math than me. i want to "refactor" this again into a more formal manner that might look publishable. – robert bristow-johnson Jun 21 '18 at 4:59
• Maybe I should just dump my write-up somewhere. – Olli Niemitalo Jun 21 '18 at 6:25
• maybe here as another answer. and we should try to harmonize our symbols and notation. – robert bristow-johnson Jun 21 '18 at 6:25
• but we sorta got scooped by the Fink et. al. crowd, in terms of publishing, @OlliNiemitalo . we shoulda done this back in 2011. we can still maybe co-author something. – robert bristow-johnson Jun 21 '18 at 6:26

There are many good answers here. Additional information can be found in this paper: SIGNAL-MATCHED POWER-COMPLEMENTARY CROSS-FADING AND DRY-WET MIXING

This is a rather math heavy paper that employs statistical signal processing methods. However, it will give you a more rigorous understanding if you are up to the task. Good Luck!

New contributor
Josh Griffin is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
• looks like we have a lot in common, Josh. – robert bristow-johnson 2 days ago
• Haha guess I didn't see you linked this as well! – Josh Griffin 2 days ago
• yeah, @Olli and i were thinking of the same thing. i have an equation just like your Eq. (11), which is, in my opinion, the key equation. in my treatment, i have split the crossfade function up into an even and odd component and then derive the even component given any arbitrary odd component (the odd component can be a smoothstep function). also, i noticed in your paper that you have correlation coefficient, $r<0$. i am thinking that you can always find an offset so that $0 \le r \le 1$. – robert bristow-johnson 2 days ago

Another trick:

Use linear cross-fade if two signals are identical and cosine-sine cross-fade for 90° of similarity.

Cossine-sine function:

$$a(t) = \begin{cases} 0 & \quad \text{if } t \text{ < 0}\\ \cos \frac {πt}{2} & \quad \text{if } 0 \leq t \leq 1\\\ 1 & \quad \text{if } t > 1\\ \end{cases}$$

$$b(t) = \begin{cases} 0 & \quad \text{if } t \text{ < 0}\\ \sin \frac {πt}{2} & \quad \text{if } 0 \leq t \leq 1\\\ 1 & \quad \text{if } t > 1\\ \end{cases}$$

why not test yourself, as example use cosine similarity to measure similarity....

% 256 samples of sine and cosine

outfs= 0.9*sin(2*pi*440/44100*(1:256));
outss= 0.9*cos(2*pi*440/44100*(1:256));

vla=0;
vlb=0;
dotp=0;
for n=1:length(outss)
vla = vla + outss(n)^2;
vlb = vlb + outfs(n)^2;
dotp = dotp + (outfs(n) * outss(n));
end
R =dotp / (sqrt(vla) * sqrt(vlb))


Results are between [-1 and 1]

 1 == perfect cosine
-1 == perfect negative cosine
0 == 90° of similarity (totally uncorrelated)


If the two signals are negatively correlated (-1), you can maybe flip the sign of the other signs and apply linear crossfade