0
$\begingroup$

Trying to figure out how to synthesize a Bandlimited PWM in my audio code in C.

I have already figured out a bandlimited pulse wave but I can't really figure out how to translate that to PWM. I have used the Polynomial Bandlimited Step (PolyBLEP) approach to get a nice bandlimited pulse wave.

Here's my code:

float generateSample() {
    float sample = 0;
    sample = sinf(phase);
    if (sample >= dutyCycle) sample = 1;
    else if (sample < 0) sample = -1;

    float t = phase/(2*M_PI);
    sample += poly_blep(t, phase_incr);
    sample -= poly_blep(fmod(t + 0.5, 1.0), phase_incr);

    phase += phase_incr;
    phase = wrapPhase(phase);

    return sample;
}

// Phase Wrapper
float wrapPhase(float phs) {
    if (phs >= (2*M_PI)) phs -= (2*M_PI);
    return phs;
};

double poly_blep(double t, double phs) {
    double dt = phs / (2*M_PI);
    // 0 <= t < 1
    if (t < dt) {
        t /= dt;
        return t+t - t*t - 1.0;
    }
    // -1 < t < 0
    else if (t > 1.0 - dt) {
        t = (t - 1.0) / dt;
        return t*t + t+t + 1.0;
    }
    // 0 otherwise
    else return 0.0;
}

I'm guessing here that I have to adjust my t variable in generateSample() to fit the PWM's duty cycle (ranges from 0.5->1) but I'm not totally sure how to do that... any help is appreciated!

Thanks! :)


EDIT: Guess I wasn't clear, but I'm producing audible tones with a pulse wave. The PWM controls the pulse width of the pulse wave. I was encountering aliasing issues before I implemented a bandlimited waveform. With a duty cycle of 50%, there are no aliasing issues. However when I try to increase the duty cycle, I encounter aliasing issues again and it sounds audibly not what I want it to sound like

$\endgroup$
  • $\begingroup$ Why doesn't the code work? What are you expecting to control the PWM with? It's not clear to me how we can answer this, as I'm not sure what the question is. $\endgroup$ – Peter K. May 11 '16 at 14:47
  • $\begingroup$ @PeterK. Hi sorry I wasn't clear enough. I'm producing audible tones with a pulse wave. The PWM controls the pulse width of the pulse wave. I was encountering aliasing issues before I implemented a bandlimited waveform. With a duty cycle of 50%, there are no aliasing issues. However when I try to increase the duty cycle, I encounter aliasing issues again and it sounds audibly not what I want it to sound like. $\endgroup$ – yun May 11 '16 at 14:59
  • 1
    $\begingroup$ Have a look to this post, it may help you to understand how the FFT and the duty cycle are related: behindthesciences.com/signal-processing/… $\endgroup$ – Behind The Sciences May 12 '16 at 6:06
0
$\begingroup$

Hey guys I figured it out through reading this: enter link description here and this: Pulse wave Wikipedia

Basically, I was reading that a bandlimited pulse wave could be synthesized with two bandlimited sawtooth waves. One of the saw waveforms will be out of phase with the other to create a rectangular waveform (50% duty cycle is sqr wave). To do PWM, just shift the phase of the out of phase saw waveform. I implemented this and it totally worked!

The wiki explanation:

A pulse wave can be created by subtracting a sawtooth wave from a phase-shifted version of itself. If the sawtooth waves are bandlimited, the resulting pulse wave is bandlimited, too.

Great learning experience and I'm sure there's a more efficient way to do it and will still be looking out for that. Hopefully this helps another person who is having the same problem one day!

$\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.