Here’s an effect that you’ve all observed before while watching a movie in which the
wheels of a car are spinning or the blades of a propeller are rotating. And as the rotation
increases, you can sometimes observe the optical illusion of the rotating object standing still
and jittering around, and sometimes even reverse its direction. This effect is commonly referred
to as the wagon wheel effect and it exists because any analog or digital video that we
are used to in the conventional form, is not continuous by any means. It’s a series of
still pictures projected on a screen in rapid succession. This video was produced and is
hopefully being streamed at 24 frames per second. 24 still images, distributed within
a span of 1 second. What happens when we try to capture something fast. You get a lot of
visual artifacts and the wagon wheel effect is one of them. It happens when the successive
frames of images coincide with the previous frame’s position after the rotation. The
rotational speed required to achieve a standstill illusion depends on the general shape of the
wheel and the number of spokes it has. But simplifying the wheel to just 1 spoke, we
can see that when the rotation of the body is less than 12 rotations per second, we can
generally make out the direction of rotation based on these individual frames. At exactly
12 rotations per second, not much can be determined, and as you increase the rotational speed beyond
12 rotations per second, we can see that the individual frames tell a different story.
When given this set of still images , rendered at the right speed, there is only one possible
conclusion we can draw, that the rotation is in the opposite direction. The still frames
are essentially portraying a false perception of direction, because we broke the boundary
above which we don’t have enough frames to accurately depict the true picture, and
this phenomenon is called temporal aliasing. This seems awfully familiar to our earlier
discussions on aliasing within audio signals. We can almost substitute the same terminology
here, and say that the video is sampled at 24 frames a second, and that 12 frames is
the Nyquist limit we need to abide by. Infact aliasing doesn’t just occur in audio and
video signals, it occurs in any form of signal which is discrete and is constrained by some
sampling parameters.
Let’s get into temporal aliasing in audio signals. Before we delve into illustrating
how a low sampling rate coupled with high frequencies can cause aliasing, we’ll first
listen to what aliasing sounds like. And this is generally harder than it seems, because
modern signal paths are really good at eliminating aliasing. When an analog signal passes through
an analog to digital converter, it filters out all frequencies above the Nyquist rate,
and when the sampled digital signal passes through a digital to analog converter, essentially
the same process of filtering occurs. We can’t bypass these steps to force aliasing, because
they are baked into the analog circuitry. Our only hope is to introduce higher frequencies
within the signal in the digital domain. Even then, modern commercial applications and plugins
like pitch shifter, compressors and ring modulators, which actually create higher frequencies within
our digital audio signals, are aware that aliasing is a possibility when the signal
is processed, and they account for it by internally oversampling the signal. Sometimes this mechanism
is transparent, and you wouldn’t even know that it’s happening, and sometimes they
give you the option to choose the degree of oversampling. As a producer of music then,
you are well insulated from the effects of aliasing in most cases. But as a developer,
battling the effects of aliasing could be daunting. The aim of this video is to just
give enough clarity and understanding of aliasing, irrespective of what you plan to do, and hopefully
you can continue the investigation further depending on your needs and use cases.
We’re back in Audacity, with a project sampling rate of 8kHz. If you can recollect from the
video on the Sampling Theorem, we can’t generate a sinusoidal tone higher than the
Nyquist frequency of 4kHz. Today, we’ll bypass this rule and generate higher frequencies.
One way to do this is by programmatically telling Audacity to create a tone for you.
We can leverage a high level programming language, coincidentally called Nyquist, to write a
little snippet of code. The language is built tightly into Audacity, as it offers a prompt
where you can run and test pieces of code without the need for an external compiler
or interpreter. The Nyquist programming language is huge, with a lot of neat functionality,
which you can essentially use for sound synthesis, writing software instruments and effects and
even building plugins compatible with Audacity. But today we’re gonna look at something
simple. Let’s go Tracks > Add new track > and select a mono track. Let’s select
a good bit of the track and head over to Effect and select Nyquist Prompt. Over here, I’ll
type in return hzosc(7000). hzosc is a function which stands for Hertz Oscillator, and the
first parameter that it accepts is the frequency in Hz. So I’ve plugged in 7000 as the frequency.
By default, the function will return a sine tone with a frequency of 7kHz with the maximum
amplitude set to 1. And I’m returning control and the output back to Audacity by using the
return keyword. I can press Preview to listen to what it sounds like. Right, that doesn’t
sound like 7kHz. If I press ok, it’ll generate the tone within our selection. If we zoom
in to examine the waveform, it looks decently well sampled. If we do a spectrum analysis
of the tone in Sonic Visualizer, we see that it’s a very precise 1kHz representation.
Our original 7kHz tone has been transformed into 1kHz tone, when our sampling rate was
set to 8kHz. I’ll repeat this entire process with an input of 6kHz. This time, we get a
higher frequency representation of 2kHz. You can almost see a pattern here, but let’s
put a picture to this pattern. I want to generate a sinusoidal sweep from 0Hz, all the way to
the sampling rate of 8kHz. We’ll go back to the Nyquist prompt, and we’ll change
the command slightly to achieve the sweep. We’ll include a ramp function inside our
hzocs function. The ramp function creates a linear control signal from zero to one over
the duration of 1 second. But since we’re using the Nyquist prompt, the duration is
relative to our selection. We are then multiplying the control signal with a scalar value of
8000. This creates a linear ramped signal from 0 till 8000 over the duration of our
selection, and this control signal is passed into the frequency parameter of the hzosc.
This is the aliasing pattern we see. All frequencies above the Nyquist frequency of 4kHz are folded
back on to the original spectrum. It doesn’t stop there though, the folding happens constantly
at the sampling boundaries as the input signal frequency increases. This is what a 16kHz
sine sweep would look like, when sampled at 8kHz. The sampled signal is folded 3 times
over. We can plot a graph of the frequency over time for the original input signal and
the raw sampled output signal. Let’s draw a line cutting through a single frequency
we want to observe. Let’s say 1kHz. We see that 1kHz is a recurring frequency within
the sampled signal, but only appears once within the original input signal. Input frequencies
that are inferred as 1kHz are 7kHz, 9kHz, 15kHz, 17kHz, and so on. It keeps going. You
can find out all the possible aliases of a given frequency by this formula, where fs
is the sampling frequency, f is the our given frequency, and n is any whole number above
0.
A profound implication that can be stated from all this, is that there are an infinite
number of aliases for every sampled frequency. Even more profound is the fact that any sine
wave is indistinguishable from an infinite number of other sine waves after sampling.
And this where the problem lies. Let’s say that now, we regret not having had a filter
to cut off the frequency above the Nyquist, and we want to get rid of the folding effect
that has been plaguing our output sampled signal. How do we do this? We can’t. Once
an aliased frequency enters the sampled signal, it is indistinguishable from the all the other
valid frequencies. There is no telling them apart.
Let’s illustrate the sampling process. I’ll fix the sampling interval to be constant,
and I’ll vary the frequency alone. At a low enough frequency the sampling process
is quite nicely churning out data points that abide by the sampling theorem. As the frequency
of the signal increases, there are fewer data points representing a single cycle. As long
as the frequency is below the Nyquist, meaning that, as long as there are at least 2 data
points representing a cycle, we are good. But as the frequency increases beyond the
Nyquist, there are fewer than 2 data points representing a single cycle of the signal
and the sampled signal has now lost the ability to represent that frequency. But the data
points left behind by the input signal still exist however, and since there is always a
single bandlimited signal that can pass through all these data points, the alias of the original
frequency is born. Technically, the pattern of data points formed by this aliased signal
and by this legitimate signal are both the same and produce the same sampled output.
This is the reason that both the frequencies are indistinguishable once sampled.
And all of this is reason enough for putting so much emphasis on the input low pass filtering
stage in the ADC, from which point on will be referred to as the anti-aliasing filter.
A proper anti-aliasing filter would never allow frequencies higher than the Nyquist
to enter into the sampled signal. The same applies to software algorithms and components.
The reason we were able to achieve aliasing, is because we forced it. In the prompt, what
you write is what you get. We scripted high frequency sinusoids without referring to filtering,
and that’s what we got.
The effects of aliasing will never be as pronounced as how we portrayed it in the Audacity demo.
Aliasing usually manifests itself as an unintended consequence of working in the digital domain,
either during sound synthesis or signal processing. So let’s look at a real world example. We’ll
use square waves this time around. We’ll go to audacity, select 44.1kHz as our sample
rate. Go to generate, Tone, and select Square as our waveform and dial in 1370Hz. That sounds
pretty awful. It’s absolutely inharmonic. Why does this happen? Any waveform can be
reproduced by adding together a number of sine waves. A square wave is produced by adding
a fundamental sine tone along with all it’s odd harmonic partials. The harmonic series
will be discussed in further detail later, but all you need to know now is that the fundamental
frequency is our starting base frequency and a harmonic partial is an integer multiple
of the fundamental frequency. For square waves, we select only the odd numbered harmonic partials,
and these partials are scaled down by a factor of their index. If you add enough partials
together, you get a close approximation of the square wave, but you’ll never be able
to achieve the perfect square wave. That’s because you’d need an infinite number of
partials and an infinite bandwidth to represent them. But this is the digital domain after
all and you can essentially do anything you want. Audacity probably implements wavetable
synthesis to produce a square wave. In this case, the data points for a perfect square
wave are stored in a tabular form, and this table is scanned at the rate of the desired
frequency. This will give us a near perfect square wave, but along with it, comes a ton
of high frequency partials that will all be aliased back into our signal, because their
frequencies are above the Nyquist. If you look at the spectral analysis of the 1.37kHz
square wave we just produced, you can find about 8 of the highest intensity partials
are frequencies that should genuinely be in our spectrum, and all the rest of the lines
here are just low intensity, high frequency partials that have been folded back into the
signal over and over again, several times, as they all exceed the Nyquist frequency of
22.05kHz. The worst part about aliasing is that the partials lose their harmonic relationship
with the fundamental as soon as they are folded back into the signal, and this results in
a sound that is inharmonic and atonal. Aliasing is also irreversible, and near impossible
to get rid of at this point of time.
So what’s the solution? The solution should ideally be offered by the digital synthesizer
you are using. During the design of these synthesisers or effect units, aliasing should
be accounted for and avoided in the first place. In Audacity, if you go over Generate
and Tone, you can find that Audacity offers Square, no alias, as a waveform type. We’ll
plugin the same frequency to generate. Sounds promising, doesn’t seem like there is any
aliasing. And if you look at the spectrum analysis, you can find the 8 partials that
are meant to be in the signal, are the only 8 that are present when aliasing is taken
out of the picture. This was achieved by limiting the frequency content when generating our
square wave, and Audacity probably used additive synthesis, to choose only partials below the
Nyquist when generating the square wave.
But what do you do when your Synthesiser offers no defense against aliasing distortion? There
are ways to overcome most of the aliasing distortion. We can use oversampling and down-sampling.
Open a new project in Audacity, and select the project rate as a 192kHz. That’s a little
more than 4 times as high as 44.1kHz. We’ll generate a regular square wave that we know
will contain aliasing distortion, and click ok. Well, it’s not bad. It still contains
a bit of inharmonic roughness that’s caused due to aliasing, but it’s nowhere near bad
enough when compared to the signal generated when the project rate was set to 44.1kHz.
If we look at the spectrum, we can understand why this is the case. All we did by sampling
higher, is we moved the bar beyond which folding occurs from 22.05kHz, all the way up to 96kHz.
All of these frequency components are in the signal, but they’re above the audible limit
so we can’t hear them at all. The only ones we can hear are the frequency components that
were folded back at 96kHz, and traversed back all the way down into the audible range. However,
the intensity of these aliased components are considerably lower, and that’s the reason
you hear less aliasing distortion. At this point, the signal can be resampled down to
an appropriate sample rate. We’ll select the track, go to Tracks and resample, and
we’ll set it to 44.1kHz. Audibly we didn’t change any aspect of the signal when we resampled
down. Audacity used the appropriate anti-aliasing filter to remove these frequencies that we
weren’t able to hear anyway. Internally this is how a lot of plugins and digital synthesizers
work. They over sample and then down sample to get rid of aliasing. We used a rough factor
of 4, when oversampling, from 44.1kHz to 192kHz. Digital softwares are known to oversample
from a factor of 2, to even 16 or 32. Performing this task manually is not ideal at all, and
if your software doesn’t offer defence against aliasing, it's time you looked elsewhere.
I feel like I want to continue the discussion further, and talk about oversampling and decimation
in hardware audio interfaces. But I think it can wait, since there are a lot of technicalities
of digital audio that we haven’t even touched upon. So in the next video we’ll take an
indepth look at bit depth and quantization. We’ll look at exactly how our sampled data
points are represented in resolution and in format.