# [sdiy] Digital accumulator VCO core?

Tom Wiltshire tom at electricdruid.net
Sat Feb 13 11:47:52 CET 2021

```==================
Electric Druid
Synth & Stompbox DIY
==================

> On 13 Feb 2021, at 04:27, Brian Willoughby <brianw at audiobanshee.com> 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

The “look ahead” you mention is indeed a difficulty, but luckily it’s not necessary, even for non-minimum-phase ordinary BLEPs. Instead, you just put the samples into a circular buffer. When you hit a reset point, you can add the BLEP into the buffered samples by starting at now-x samples and going forwards to now+x samples. Then you carry on generating more naive ramp samples until you hit the next reset, whereupon you add another BLEP correction into the buffer again.

Clearly the buffer needs to be big enough that you have room to ‘look ahead’ by the required amount when you hit a reset, and also long enough that the point you read samples from is long enough ago that a reset in a couple of samples time can’t affect it any longer. In practice this only means that the buffer needs to be a bit longer than the BLEP you’re using.

The advantages of this method is that the overlapping of the different BLEPs is dealt with without having to keep track of each one individually, and there’s no messing around with extra complications to make a minBLEP.

Tom

```