0
$\begingroup$

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);
}
$\endgroup$
  • $\begingroup$ what is the meaning of "sampling rate" here? Are you coding an analog simulator ? please clarify the context. $\endgroup$ – Fat32 May 4 '16 at 20:38
  • $\begingroup$ @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! $\endgroup$ – yun May 4 '16 at 21:09
  • $\begingroup$ ok fine!... May be you could remove the question then, or just describe the answer ? $\endgroup$ – Fat32 May 4 '16 at 21:20
  • $\begingroup$ @Fat32 did last night! $\endgroup$ – yun May 5 '16 at 13:32
1
$\begingroup$

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).

Without using <code>wrapPhase</code> in correcting phase value

With using <code>wrapPhase</code> for corrections.


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")
$\endgroup$
  • $\begingroup$ This wasn't the answer I arrived at but I'm confused, what is the blue line? $\endgroup$ – yun May 4 '16 at 21:09
  • $\begingroup$ The $\color{blue}{blue}$ line is the sinusoid, the $\color{green}{green}$ line is the square wave. $\endgroup$ – Peter K. May 4 '16 at 21:11
1
$\begingroup$

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

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.