# Kernel BLEP for aliasing reduction

Hi,
I’m trying to implement a BLEP oscillator but i’m not sure how to generate a correct kernel.
I’ve tried the following:

``````int num_zero_crossings = 1;
int oversampling = 2048;
long n = num_zero_crossings * oversampling * 2 + 1;
double blep_table[n];

double sum = 0;
double val = 0;
for (int i = 0; i < n; i++){
double t = (double) (i) / (double) (n - 1);
val = Sinc(num_zero_crossings + 2 * t * num_zero_crossings);
val *= 0.42 - 0.5 * cos(2.0 * PI * t) + 0.08 * cos(4.0 * PI * t); //Apply blackmann
sum += val;                                                       // To integrate
blep_table[i] = sum;
}

for (int i = 0; i < n; i++){
blep_table[i] = blep_table[i] / sum; // normalize
if (i > n / 2 - 1) {                  // subtract unit step
blep_table[i] -= 1;
}
blep_table[i] *= 2;
}
``````

with:

``````static inline double Sinc(double x){
double pix;
if(x == 0){
return 1;
}
else{
pix = PI * x;
return sin(pix) / pix;
}
}
``````

But I feel like I’m doing something wrong. Could someone comment on this ?
Best regards, Louis

The mistake in your code is that you totally discard the negative half of the sinc function. I think you meant something like this instead:

`val = Sinc(-num_zero_crossings + 2 * t * num_zero_crossings);`

Then the other mistake is to use BLEP instead of minBLEP (more practical to use because the response is completely causal). And then to use minBLEP instead of polyBLEP

1 Like

Hi pichenettes,

``````val = Sinc(-num_zero_crossings + 2 * t * num_zero_crossings);
``````

I did a mistake when I wrote it here.
Yes i’m aware about polyblep but the idea is to apply more than 2 points correction. Is it possible with polyblep ?
Concerning minblep, I’ve heard that this method introduce more problem than it solves and that linear BLEP worth the effort. I should also mentionne I want to implement hard sync.

About the BLEP kernel is the window applied at the right moment (before integration) ?
Thanks again for your help !

I’ve run your code with this modification and the output seemed correct. What’s your problem exactly?

When I try to use it:

``````void lfo_perform64(t_lfo *x, t_object *dsp64, double **ins, long numins, double **outs, long numouts, long sampleframes, long flags, void *userparam){
double *in = ins[0];
double *out = outs[0];

double next_sample = x->last_sample;

while (sampleframes --){
double this_sample = next_sample;
next_sample = 0;
double phase_inc = *in++ / x->samplerate;
x->phase += phase_inc;
if (x->phase >= 1){
x->phase -= 1;
double t = x->phase / phase_inc;
next_sample -= DoBlep2(x, t);
this_sample -= DoBlep1(x, t);
}
next_sample += (x->phase * 2) - 1;
*out++ = this_sample;
}
x->last_sample = next_sample;
}
``````

with

``````static inline double DoBlep1(t_lfo *x, double t){
double blep_table_center = x->blep_table_size / 2.0 - 1;
double index = t * blep_table_center;
return LinInterpo(x->blep_table, index);
}
``````

and

``````static inline double DoBlep2(t_lfo *x, double t){
double blep_table_center = x->blep_table_size / 2.0 - 1;
double index = (1 + t) * blep_table_center;
return LinInterpo(x->blep_table, index);
}
``````

The interpolation is:

``````static inline double LinInterpo(double *buffer, double index){
long x0 = (long)index;
if (x0 != index ){
long x1 = x0 + 1;
return buffer[x0] + ((buffer[x1] - buffer[x0])) * (index - x0);
}
else{
return buffer[x0];
}
}
``````

When I Replace DoBlep1 and DoBlep2 by:

``````static inline double DoPolyBlep1(double t){
t -= 1;
return t*t + t+t + 1.0;
}
``````

and

``````static inline double DoPolyBlep2(double t){
return t+t - t*t - 1.0;
}
``````

Everything works as expected (no noise appearing).

The aliasing reduction is okay but sometime I got some noise appearing in my freq analyser.
I suspected the kernel because when I replace the DoBlep1 and Doblep2 by approximation (polyblep) there is no problem !
But maybe I should go with minblep or 4 point polyblep if it’s possible ?
What do you think about minblep ? Did it really introduce more problems ? Or is it as simple as using a more complex kernel and then forgot about lookahead ?
Thanks again for your help !

Your code looks strange… When `x->phase` exceeds 1.0, it should be wrapped in the [0, 1[ range.

1 Like

yes, sorry an other mistake … I edited my last post

It would help if you posted directly your project - the actual code you’re trying to run. After all, there could be a bug in LinInterpo… and we’re not going very far if all the mistakes I detect are copy/paste error from your code to the other.

An oddity: in DoBlep1, you do `t = 1 - t`and then use `(1 - t)`when computing the index. So t is not changed at all?

1 Like

Hey pichnettes,
You’re right, I didn’t see the oddity. I Edited my code adding the interpolation part. I also add the polyblep function I use to compare with the BLEP. I didn’t post all the project because it’s a max msp external, so I thought it won’t be good for clarity but I will if you think it’s needed.
Thanks again for your help, I really appreciate this !

1 Like