Overlapping COS BLEPs for PWM

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

Hi folks, I am experimenting with bandlimited oscillators. Currently, I want to create an antialiased pulse generator with modulated pulse width and FM. It is a simple java algorithm where a phase variable is incremented until the phase is >=1. Them a sync appears (rising slope). For the falling slope, another t2 is incremented faster, dependent of the width. Then a second sync occurs. Since I made quite good experiences with a cos BLEP (cos(x)+cos(2x)/2-0.5), especially when oversampled. I start these BLEPs when the sync appears (up and down). The BLEPs are continued in the following samples, since fired.
The oscillator is able to handle inter-sample sync. When a falling edge and a rising edge appears, the BLEPs were mixed together (added). In some cases, the addition leads to a offset which seems too high (expecially in case of 2 sample distance). The naive value of the pulse (-1,1) is also added, but I am not sure how to deal with that exactly.
It seems to be a better approach to derive the BLEP function (-sin(x)-sin(2x)), then sum the values and integrate the whole thing. But this leads to significant integration errors which are phase dependent, quite ugly and even noisy. Well, this is not a sinc function where I did not have these problems. But sinc has the disadvantage that it must be "predicted", which makes modulation difficult.
The question is: When you have (any) BLEPs which overlap in some samples, how do you deal with that, while avoiding integration?

Post

Usually the way to do BLEPs (or BLITs for that matter) is that you have an output ring(*) buffer (at least half BLEP-length longer than the blocksize you're processing) and whenever you need to insert a BLEP you just mix (=add) the whole thing into the buffer at once. Since "insert BLEP" then becomes a bulk operation, you don't need to track them separately and overlapping is a complete non-issue... plus you get to use SIMD to mix the things faster. This also avoids any issues with "prediction" with linear phase BLEPs, you just mix your naive waveform at an offset and BLEPs without.

(*) In practice, you don't really need a ring-buffer with the complicated (=slow) indexing that comes with it.. rather just use a regular straight buffer and then shift the tail to the beginning (and clear the rest of it) between blocks. As long as the average buffer is longer than the BLEPs this is usually more efficient than complicating your logic to deal with modulo indexing (which also complicated the SIMD optimizations that make BLEPs relatively cheap).

Post Reply

Return to “DSP and Plugin Development”