# Aliasing Square Wave

I'm having a really weird issue with generating waveforms from frequencies C1 to C8.

When I generate sine waves, everything sounds good; no problems whatsoever. However, when I generate a square wave... BAM weird aliasing issues on the higher frequencies (around C6 to C8). I have no idea what I'm doing wrong at this point.

I'm going to take a wild guess here but I'm thinking it might be because square waves have a lot of harmonics so it's not producing the higher harmonics correctly when I reach a higher frequency... thus the really high harmonics are getting aliased. Would like someone to confirm with me/guide me to a solution to this. Is it possible to try to implement a filter or is there a better solution ?

Thanks!

I'm setting my sample rate to 44.1 kHz and here are my functions for waveform generation:

float generateSin {
sample = sinf(_phs);

_phs += _phs_incr;
_phs = wrapPhase(_phs);
}

float generateSqr {
sample = sinf(_phs);
if (sample > 0) sample = 1;
else if (sample < 0) sample = -1;

_phs += _phs_incr;
_phs = wrapPhase(_phs);
}
• what is the meaning of "sampling rate" here? Are you coding an analog simulator ? please clarify the context. May 4, 2016 at 20:38
• @Fat32 I'm generating audio so sampling rate is for audio dac. I just learned about BLITs between posting this and now so I implemented that and it pretty much helped solve the problems!
– yun
May 4, 2016 at 21:09
• ok fine!... May be you could remove the question then, or just describe the answer ? May 4, 2016 at 21:20
• @Fat32 did last night!
– yun
May 5, 2016 at 13:32

My guess is there's a problem with your wrapPhase function.

If I use the R implementation of it below (C8 shown), then I get all sorts of funny results. That's the second image. Removing it from the iteration (but including it in the calculation), makes for much cleaner signals (the first image).

R Code Below

#30582

wrapPhase <- function(phi)
{
return(phi %% 2*pi)
}

# https://en.wikipedia.org/wiki/Piano_key_frequencies
cs <- c(32.7032, 65.4064, 130.813, 261.626, 523.251, 1046.50, 2093.00, 4186.01)
c1 <- cs[1]
c8 <- cs[8]

fs <- 44100

phs <- rep(0,T + 1)
phs_incr <- c8 / fs * 2 * pi

T <- 1000

sample <- rep(0,T)
sqr_wave <- rep(0,T)

for (t in seq(1,T))
{
sample[t] <- sin(wrapPhase(phs[t]))

if (sample[t] > 0)
{
sqr_wave[t] <- 1
}
else
{
sqr_wave[t] = -1;
}

print(sample[t])

phs[t+1] <- phs[t] +  phs_incr
#phs[t+1] <- wrapPhase(phs[t+1]);
}

phi <- seq(-pi, pi, 0.001*pi)
phi_wrap <- rep(0, length(phi))

for (k in 1:length(phi))
{
phi_wrap[k] <- wrapPhase(phi[k])
}

plot(sample[1:50], col="blue", type="l")
lines(sqr_wave[1:50], col="green")
• This wasn't the answer I arrived at but I'm confused, what is the blue line?
– yun
May 4, 2016 at 21:09
• The $\color{blue}{blue}$ line is the sinusoid, the $\color{green}{green}$ line is the square wave.
– Peter K.
May 4, 2016 at 21:11

After brainstorming/researching for a little longer, I've realized that there are things called Bandlimited Waveforms; these waveforms basically get rid of the aliasing issues that exist within waveforms with harmonics (triangle, square, sawtooth for example).

The cause of my issue was that even though I had the right sampling rate for my base tones, they did not support the harmonics that my square waves had, thus creating aliasing. I found out this is a common problem for many others and my implementation of my square wave would be perfect for LFOs/lower frequencies.

Anyways, I implemented a Bandlimited Square Wave and BAM! problem solved!!! no more aliasing! NOW there's a problem with trying to implement a bandlimited PWM but that's another problem for later ;0