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:
- Splicing perfectly coherent and correlated signals
- 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} \approx 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$, the splice displacement, from an algorithm we call a "pitch detector". If the signal were periodic, we would want that value to be an integer number of cycles or periods of similarity. If less periodic, we still want as much in common between $x(t)$ and $x(t+P)$ (in the neighborhood of $t=0$) as possible.
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) $$
$$ r = \frac{\langle x,y \rangle}{\langle x,x \rangle} = \frac{R_{xx}(P)}{R_{xx}(0)} $$
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 . $$
Generalizing the crossfade function:
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.