About BLEP minBLEP - polyBLEP and bandlimited ramps

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

Post

Hi to everyone,

I'm trying to get the BLEP concept and I think I have it, apply the preintegrated impulse response of the "channel-medium" to the known shape signal/type of discontinuity (sinc), even though I have some weak point parts that I want to ask to.

I'm reading this paper linked below, I'm interested in the Polyblep part starting in pdf page 45, it seems interesting because it lets you skip the table part, but I'm not sure I'm getting the concept.

http://lib.tkk.fi/Dipl/2007/urn009585.pdf

When I plot the spline approximation residual I get this.

Image

If you observe it doesn't have the response ripples before and after the step, I always thought that after a sudden change you can't have a straight line (DC) because it needs infinite harmonics, if I'm right this graph is representing from the sample before the discontinuity to the sample after, skipping all the ripples that have to occur in the DC part of a square by example. I'm right ? could be enough antialiasing doing it in this way ? maybe the graph is expressing something that i don't get.

Another question is, I heard that to have a bandlimited ramp i only have to integrate the bandlimited step, easy, but does this ramp can be applied to any frequency triangle wave discontinuity ? i mean, in the square an sawtooth the module of the discontinuity doesn't vary with frequency, it's always a 90 degree angle (ideally), in the triangle it does vary, is a bandlimited ramp usefull for any triangle like discontinuity type ? i don't think so because if it is why not use a bandlimited ramp to limit the 90 degree discontinuity?

I think that the solution could be a polynomial with the ramp module parameter, isn't it ? instead of applying a step applying a ramp of module M.

if you can use the ramp for everyting could also be used to bandlimit an linear ADSR envelope right to get the maximum speed possible?

Thanks for reading.
Last edited by rafa1981 on Thu Apr 16, 2009 11:13 am, edited 2 times in total.

Post

Just forgot to say that the residual polynomial negative part is the red graph and the positive the green one.

Post

Come on! anyone? If you don't reply I'll send Chuck Norris to your house. :D

Image

Seriosly, I need a little help if possible.

Post

rafa1981 wrote:Hi to everyone,

Another question is, I heard that to have a bandlimited ramp i only have to integrate the bandlimited step, easy, but does this ramp can be applied to any frequency triangle wave discontinuity ?
Yes! You have to scale it to the ramp of the triangle. The higher the frequency the higher the multiplier. Another way to get the triangle is to integrate the bandlimited pulse. Then you have to scale the pulse amplitude to the triangle frequency. The difference between the BLIT, BLEP, BLAM (or whatever) is the placement of the integration stage.

Sry, can't answer your first question, but please don't send Chuck Norris to my house!

Post

Thanks by your reply Kunn, you have saved your live :)

In the triangle case I thought in a constant module ramp plus amplification, but it does invalidate any PWM.

With integration happens the same, as well I think that the beautyness of BLEP is to skip integration stages.

And it can be used in an ADSR, but thanks anyway.

Post

rafa1981 wrote: i don't think so because if it is why not use a bandlimited ramp to limit the 90 degree discontinuity?

I think that the solution could be a polynomial with the ramp module parameter, isn't it ? instead of applying a step applying a ramp of module M.

if you can use the ramp for everyting could also be used to bandlimit an linear ADSR envelope right to get the maximum speed possible?
You probably can use ramps instead of steps, but for one step you have to use two ramps!

Ramps can be used for linear envelopes only I guess.

Post

rafa1981 wrote:Thanks by your reply Kunn, you have saved your live :)

In the triangle case I thought in a constant module ramp plus amplification, but it does invalidate any PWM.
Hmmh... for saws/pulses you have a discontinuity, which you band-limit by patching in the difference between the continuous time discontinuity and the response of your chosen kernel to the C0 discontinuity (any polynomial or polyphase FIR or whatever lowpass you happen to like).

Typically you approximate this by integrating the kernel, then substracting the continuous step (to sort of leave the "pure discontinuity response") and then add that (suitably scaled) back to the trivially sampled signal afterwards. And when you hard-sync a saw, you scale the discontinuity response to match the magnitude of the discontinuity, right?

In the exact same way, a triangle has discontinuities in the first derivative. Hence you need a pure discontinuity-in-first-derivative response, which you can create in various ways, but generally integrating your kernel twice, and substracting the anti-derivative of a step is the easiest method.

Note that the resulting BLAMP isn't really concerned with the actual slope. It is only concerned with changes in the slope (discontinuities in derivative). Hence if you solve the derivatives of the PWM triangle (which depend on frequency; trivial to do analytically anyway) to get the magnitude of the discontinuity in the derivative, you can easily scale BLAMPs to match.

If you wanna hard-sync your (PWM or not) triangle too, then at each (general) discontinuity, you need to consider the size of the signal discontinuity (if any) and patch in a suitably scaled BLEP, then consider the size of the discontinuity in the derivative, scale the BLAMP, and add it all together.

You can do that for any number of higher derivatives too (say you wanna do piece-wise quadratic or cubic waveshapes).. though each derivative needs to be handled separately, and numerical accuracity (especially when integrating the responses numerically) can degrade the filter performance pretty badly (though for polybleps you could integrate analytically, and even sum the different derivatives as functions and only sample the total.. haven't tried polybleps personally though).

Oh and regarding ADSR band-limiting.. yeah sure, but then you also need to oversample it to avoid aliasing from the multiplication... but if you feel like it (I personally do audio-rate envelopes but even I'm not crazy enough to bother band-limiting them).

Post

Note that one could also do band-limited FM (on a finite-derivative carrier) by considering the modulation signal as a series 0th order holds (or use higher-order approximations but it gets damn expensive damn fast) and then patch such discontinuity-in-derivative at each sample. The remaining error then would be that which is caused by the approximation of the modulator's continuous-time reconstruction by 0th order holds (which should be irrelevant for even the fastest "LFO rates", but might matter at higher audio rates).

Post

Thanks by all the information mystran, I have work to do to undestand all the theory behind what are you saying because is not obvious speaking, at least for me.

BTW, Chuck Norris is so effective :)

Post

I'll try to make it easier for you.

When you take a derivative of a triangle you get a pulse wave. Instead from being in the range of -0.5...0.5 (or -1...1), this ones range is proportional to the triangle frequency. Say -0.05...0.05 for some lower and -0.1...0.1 for some higher frequency. Now instead of adding a usual BLEP you add 0.1*BLEP for lower one and 0.2*BLEP for higher and when you integrate you get bandlimited triangle. But with BLAM you have your BLEP preintegrated and you just add x*BLAM to the triangle (x = f( frequency, PWM )).

Post

kunn wrote:I'll try to make it easier for you.

When you take a derivative of a triangle you get a pulse wave. Instead from being in the range of -0.5...0.5 (or -1...1), this ones range is proportional to the triangle frequency. Say -0.05...0.05 for some lower and -0.1...0.1 for some higher frequency. Now instead of adding a usual BLEP you add 0.1*BLEP for lower one and 0.2*BLEP for higher and when you integrate you get bandlimited triangle. But with BLAM you have your BLEP preintegrated and you just add x*BLAM to the triangle (x = f( frequency, PWM )).
OK, it says the same as mystran but explained more at my actual knowledge level, direct to implementation point of view, thanks, good to have the rigurous and the easy to undestand version.

Post

mystran wrote:Note that one could also do band-limited FM (on a finite-derivative carrier) by considering the modulation signal as a series 0th order holds (or use higher-order approximations but it gets damn expensive damn fast) and then patch such discontinuity-in-derivative at each sample. The remaining error then would be that which is caused by the approximation of the modulator's continuous-time reconstruction by 0th order holds (which should be irrelevant for even the fastest "LFO rates", but might matter at higher audio rates).
Basically are you saying that if I'm working with 0th order holds, aliasing can be reduced inserting scaled bleps in the modulator signal according to its variation between values, and if 1st order hold could be done equally but patching with scaled triangle like discontinuities, really interesting, seriously, thanks for sharing your knowledge.

Post

mystran wrote:Note that one could also do band-limited FM (on a finite-derivative carrier) by considering the modulation signal as a series 0th order holds (or use higher-order approximations but it gets damn expensive damn fast) and then patch such discontinuity-in-derivative at each sample. The remaining error then would be that which is caused by the approximation of the modulator's continuous-time reconstruction by 0th order holds (which should be irrelevant for even the fastest "LFO rates", but might matter at higher audio rates).
Basically are you saying that if I'm working with 0th order holds, aliasing can be reduced inserting scaled bleps in the modulator signal according to its variation between values, and if 1st order hold could be done "equally" but patching with scaled triangle like discontinuities, really interesting, seriously, thanks for sharing your knowledge.

Post

Finally now I'm working on it, I think I'm near the solution at all.

I decided to construct a polynomial for 4 samples (4 before, 4 later) to be able to calculate with SIMD. Before implementing I need some feedback about the residuals, does they seem OK for a -1 to 1 signal range ?.

Image

BTW, could be necessary some smoothing in the 4th sample to make the function end in 0 and make it continuous? By now I have prototiped to do it with an exponential fade in the third sample.

Thanks!

Post

Now I have it working at all, I'm happy with the sound, the CPU performance, and the fact that there is no wavetable involved in none of my oscillators.

Finally I ended implementing four 4th degree polynomials, one for each sample interval, the good thing is that it is so easy to calculate them with SSE instructions...

Code: Select all

//--------------------------------------------------------
__forceinline void Triangle::BlampPoly(short i, const short ch, const float magnitude)
{
	Channel[ch].Results->m128f[i] = _mm_mul_ps( Channel[ch].Times->m128f[i], 
												BlampCoeffsDeg4->m128f );
	Channel[ch].Results->m128f[i] = _mm_add_ps( Channel[ch].Results->m128f[i], 
												BlampCoeffsDeg3->m128f );
	Channel[ch].Results->m128f[i] = _mm_mul_ps( Channel[ch].Results->m128f[i], 
												Channel[ch].Times->m128f[i] );
	Channel[ch].Results->m128f[i] = _mm_add_ps( Channel[ch].Results->m128f[i], 
												BlampCoeffsDeg2->m128f );
	Channel[ch].Results->m128f[i] = _mm_mul_ps( Channel[ch].Results->m128f[i], 
												Channel[ch].Times->m128f[i] );
	Channel[ch].Results->m128f[i] = _mm_add_ps( Channel[ch].Results->m128f[i], 
												BlampCoeffsDeg1->m128f );
	Channel[ch].Results->m128f[i] = _mm_mul_ps( Channel[ch].Results->m128f[i], 
												Channel[ch].Times->m128f[i] );
	Channel[ch].Results->m128f[i] = _mm_add_ps( Channel[ch].Results->m128f[i], 
												BlampCoeffsDeg0->m128f );
	SSEAux1->m128f = _mm_set1_ps(magnitude);
	Channel[ch].Results->m128f[i] = _mm_mul_ps( Channel[ch].Results->m128f[i], 
												SSEAux1->m128f );
}
... and calculate the exact placement time is 7 sums/subs, 2 muls and 3 divides in the PWM case.

I think that the weakness of this method is that is limited to short time responses/windowing of the blep residuals, the strongest point is the fact that the impulse is exactly placed between samples, aka infinite oversampling.

I'm not sure about trying the 8 samples before/after version, maybe for a Bass Synth, but it could be CPU hurting at high frequencies.

The worst thing is that i don't know a method to integrate sin(pi·x)/pi·x analitically, I also don't know it it could be cheaper to approximate the curve with splines/bezier instead of 4th polynomials, if anyone can help with this it will apreciate, also if anyone is interested in the method we can share.

By the moment here is the current sound.
http://www.mediafire.com/?dnnel1uvdc2

Post Reply

Return to “DSP and Plugin Development”