Tutorial: BLEPs (using PolyBLEPs but extensible)

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

FFT comparison (1000 hz saw):
Image

Post

Tale wrote:
mystran wrote:Well, mm.. don't have a picture to post, but basically a bit cleaner than DPW.
Well, I do:
Thanks for the pictures. Yeah, you can trade-off different functions. The one you propose (0.5*x^2) amounts to treating the step as a linear segment rather than a smooth-step. The choice makes some sense, but for whatever reason the one I used appears to be popular in literature.

Anyway, I don't really have an opinion on particular step-functions to use, I just picked something that worked reasonably well. Normally I'd use longer tabulated BLEPs (usually 16 taps or so). Really should extend the code above to illustrate how to do this exactly.

Post

Everyone should keep in mind of course the examples are generated with a very minimal filter. The filter I use for example produces zero passband distortion and provides 120db in 1/5th octave. This means say you're running at 48khz, harmonics roll off from 24khz to 19.2khz and then are -120db. Same response for all orders.

It does this in eight samples rather than two, so it is not much more expensive.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

Nice, perfect to get me started!
PhasePhckr (modular MPE VSTi) G+
Fatar88Lux (dyi MIDI brain) bitbucket
Assault Opera - sound cloud | spotify

Post

no function version :hihi:
(*in1 and *in3 are mix and pw. w is unit phasor of course)

Code: Select all

		float out = blepDelay;	blepDelay = 0;	
		p += w;
		while (true) {
			if (pulseStage == 0) {	if (p < *in3) break;
				float t = (p - *in3) / (widthDelay - *in3 + w);	float t2 = t * t;
				out += *in1 * t2 * (t - .5f * t2);
				t = 1 - t;	t2 = t * t;
				blepDelay -= *in1 * t2 * (t - .5f * t2);
				pulseStage = 1;
			}
			if (pulseStage == 1) {	if (p < 1) break;
				float t = (p - 1) / w;	float t2 = t * t;
				out -= t2 * (t - .5f * t2);
				t = 1 - t;	t2 = t * t;	
				blepDelay += t2 * (t - .5f * t2);
				pulseStage = 0;
				while (p >= 1) p -= 1;
		}	}
		blepDelay += (1 - *in1) * p + (bool)pulseStage * *in1;
		*out1 = *out2 = out + out - 1;
		widthDelay = *in3;
this was nice to get :)
you come and go, you come and go. amitabha neither a follower nor a leader be tagore "where roads are made i lose my way" where there is certainty, consideration is absent.

Post

Cool stuff! Now I want to code :D

Post

NoWay wrote:Cool stuff! Now I want to code :D
No way!!! :o

sorry, couldn't resist...

Post

Hi mystran! Hi all!
Thanks for a cool tutorial! But I have a question about using this oscillator design with "more-than-2-points" bleps. I spent some time and think about this problem.
First, I created implemetation of a delay line. Then incorporated this buffer in my code, that is based on this tutorial. My oscillator works well, but it have 2-sample delay in time (I use 4-point BLEP: 2 before and 2 after).
So, I have a question. Is this delay normal for an oscillator? Or do I need to change my design to compensate for the delay?
Thanks in advance!

Post

sithpz wrote: Mon Oct 29, 2018 2:42 pm Hi mystran! Hi all!
Thanks for a cool tutorial! But I have a question about using this oscillator design with "more-than-2-points" bleps. I spent some time and think about this problem.
First, I created implemetation of a delay line. Then incorporated this buffer in my code, that is based on this tutorial. My oscillator works well, but it have 2-sample delay in time (I use 4-point BLEP: 2 before and 2 after).
So, I have a question. Is this delay normal for an oscillator? Or do I need to change my design to compensate for the delay?
Thanks in advance!
Assuming linear-phase BLEP (and really that's the only "sane" option anyway), you always need delay (or "latency") worth half the BLEP length. The best you can do is compensate by adding matching delays to all parallel signal paths (eg. modulation signals to all the modules that are on the signal path after the oscillators) so they align in time (and then report the final latency to host in a plugin, so it aligns with other tracks), but one could argue it's not necessarily worth the trouble if your delay is just 2 samples.

Post

Hi, mystran!

Oh! Thanks. This is very usefull info for me. In my oscillator' implemetation I used 4-points PolyBLEP. Now I whant to try a table-based approach. I found in a Will Pirkle' book info about, how to build BLEP tables (using windowed sinc-integration). But I have a question. What is a 'linear-phase BLEP'? And how can I build BLEP FIR filter? (This is a FIR filter that has a kernel based on the BLEP table? etc...)

Thanks!

Post

sithpz wrote: Tue Oct 30, 2018 1:42 pm What is a 'linear-phase BLEP'?
It's a "BLEP" that has linear-phase.

Post

Do You mean BLEP based on a Si(x)? (with possible prior windowing sinc(x))

Post

sithpz wrote: Tue Oct 30, 2018 2:42 pm Do You mean BLEP based on a Si(x)? (with possible prior windowing sinc(x))
https://en.wikipedia.org/wiki/Linear_phase

Post

There are multiple ways to generate minimum phase or variations of FIR kernels (always remember: "BLEP" is merely a specific type of FIR kernel, nothing special. The somewhat unique part is only in how the kernel is applied and not what it itself is.)

Generally speaking you'll always need to transform from linear phase to any other version of a FIR kernel. So unless you're sampling an impulse response or similar to end up with anything else you can safely assume the windowed kernel you generate is linear phase to start.

Yes for example sinc(phase) * window(phase) = linear phase.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

If I want a continuous sinc(x) integral approximation, parameterised to time with arbitrary scale, to use whenever my signals are supposed to make a band-limited step, is that something which has been solved by an established method?

Deeply sorry if this is a duplicate question, it's that I'm finding that the literature on sinc functions is deep and vast

The route of summing cos(n*t)/N for all natural numbers up to N (lowpass kernel i.e. sinc approximation), then integrating to sin, does lead to an impractical example of what I'm looking for
You do not have the required permissions to view the files attached to this post.

Post Reply

Return to “DSP and Plugin Development”