[sdiy] Digital accumulator VCO core?

Richie Burnett rburnett at richieburnett.co.uk
Sat Feb 13 10:20:45 CET 2021

You absolutely have to permit the step-corrections to overlap! Otherwise you either have to avoid playing high notes or each BLEP will truncate the one before and you will get horrendous aliasing.

One good way to get your head round the BLEP process is to think of it generating the sample values that you would have got if you recorded a real analogue sawtooth oscillator through a top-quality soundcard. Try this with a soundcard that has a good ADC. What do you get? You get a sawtooth looking bunch of samples but with various amounts of wiggles just before and just after most of the discontinuities in the saw waveform. Where do these little pre-ripples and post-ripples come from? The anti-aliasing filter that comes before the ADC in the soundcard. The filter that band-limits the analogue sawtooth with its otherwise infinite spectrum before it gets sampled, to prevent it aliasing!

The BLEP method is really just an efficient implementation of what happens in real life when you sample an analogue waveform with a decent audio interface. It's directly synthesising the digital samples that you would have picked from an analogue sawtooth waveform after having band-limited it first.

The little ripples in the BLEPs applied to anti-alias a naive sawtooth waveform are nothing more than points picked from a pre-calculated lookup table of what a step-discontinuity looks like after its been shoved through a really good band-limiting (anti-aliasing) filter.

In the case of polyBLEP those equations used to calculate what to do to the sample before and the sample after the discontinuity are just approximating a nice smooth band-limited step by some pretty crude low-order polynomials. They're a huge simplification, but they're also surprisingly effective for just modifying two samples! This is particularly so for suppressing spectral components that alias back down to low frequencies below the fundamental of the tone you're generating, which are the most annoying ones.

PolyBLEP combined with modest x2 oversampling (96 kHz) gives results that are surprisingly good. Running it at 96kHz moves most of the aliased components that remain are into the ultrasonic region above 20khz where you can't hear them. (Or you can lowpass filter at 20kHz and drop the sample rate down to 48khz afterwards to remove them if they bother you.) Not bad for modifying just one sample before and one sample after each step, and the neat thing is that you only need to evaluate a simple quadratic. Something that is lightening fast and accurate on a DSP. (You don't need the long lookup table in ROM like you do with BLEP, and risk suffering cache miss stalls on modern micros.)

At the other end of the quality scale a BLEP modifying about 16 samples either side of each discontinuity can give you a sawtooth with less than 1 dB of ripple all the way up to 20kHz then down in the noise-floor by 24kHz, with no discernable aliased components and no oversampling! But you'll have to deal with lots of interpolated lookup table reads, and lots of overlapping BLEPs at high pitches. So you won't get much polyphony for a given account of DSP power, but that's the price you would pay for this "laboratory test equipment" quality rendering!!!


Sent from my Xperia SP on O2

---- Brian Willoughby wrote ----

>On Feb 12, 2021, at 15:49, Mike Bryant wrote:
>>> If you do a polyblep you correct the sample just before and just after the transition to "blend" the fractional-sample-position step into whole samples, but I don't get what the curve is supposed to be or how you design it.
>>> Gordonjcp
>> I might be wrong (I've been adding sinewaves together for so long I've never used these techniques) but on a quick read I think one way of looking at it is you are effectively generating a copy of just the aliases then subtracting them from the signal so they (mostly) cancel out the problematic ones.
>The paper, "Hard Sync without Aliasing" by Eli Brandt is a good one.
>You start with the ideal impulse or ideal step function, each of which can be converted into the other via integration or differential. The ideal impulse is a single non-zero sample surrounded only by zero samples. The ideal step is a series of zero samples followed by an instant change to a maximum sample (value 1.0 in float).
>Then you have band-limited versions of the above. A sinc signal is sin(x)/x and a windowed-sine pulse is a finite excerpt of that. You can use integration to turn sinc into step, but it looks like one edge of a square wave with Gibbs phenomenon - ringing.
>One minor problem with sinc is that there's a lot of signal before the peak, and just as much after. Thus, if you want an impulse that's band-limited, you have to know well in advance (look-ahead). One good way around this is to use a minimum-phase version. There's still a small lead up to the peak, but not multiple bumps, and then the rest of the energy bounces around after the largest peak (which is slightly reduced by the transformation).
>If you calculate integration on a minimum-phase windowed-sinc pulse, then you get the minimum-phase band limited step waveform. This is what is called a MinBLEP.
>Any time you need to jump (discontinuity) in your waveform, such as a ramp reset, just mix in the MinBLEP *instead* of jumping instantly. There is extra calculation, because an instant jump only requires one sample to reach the new value, whereas the MinBLEP is a train of samples that have to be mixed with whatever samples follow the discontinuity.
>For a ramp, most samples are only a small change from the previous sample, and don't need the MinBLEP. But those reset events do require the MinBLEP. When you mix the sawtooth, I think you use the jump to determine the amplitude of the MinBLEP, so it's scaling rather than mixing for that one sample, and then the subsequent samples are a mix of the sawtooth and MinBLEP until you hit the end of the MinBLEP and it reverts to pure sawtooth.
>What I don't know it whether you're supposed to allow MinBLEP mixing to overlap. Theoretically, they should probably all get mixes, so your engine needs to handle multiple overlapping MinBLEPs. However, I suppose it might just be the case that you should avoid letting the fundamental frequency get high enough that overlap would occur. In other words, however long the MinBLEP is in samples, that's also a hard limit for your minimum period length - at least if you want to avoid the extra math of mixing more than one MinBLEP.
>Then there's the question of infinite MinBLEP if you really take things to the extreme.
>Brian Willoughby
>Synth-diy mailing list
>Synth-diy at synth-diy.org
>Selling or trading? Use marketplace at synth-diy.org

More information about the Synth-diy mailing list