## Q: band limited difference curve

DSP, Plug-in and Host development discussion.
antto
KVRAF
2499 posts since 4 Sep, 2006 from 127.0.0.1
hi guys
think of a sawtooth made out of sine waves up to a given number
subtract a naive sawtooth out of this and you see the curve i'm talking about..
bl_saw(phase,H) - saw(phase)
// H is the number of harmonics (>= 1)
// note: the output of the bl_saw is divided by (pi/2)

now, adding sine waves is not cheap, especially when you must put lots of harmonics (on lower notes)

i know there are antialiasing/bandlimited techniques already, but let's not talk about these right now..

if this curve can be approximated easily like so approx(phase,H) where H is the number of harmonics - then this could be added to a naive sawtooth (or square) and you get a bandlimited waveform!

here's some plots:

the actual difference curve at different values of H

my best approx so far, as you can see, it's wrong in the first and last part

Code: Select all

``````h = floor(h); if (h <= 0.0) { h = 0.0; }
h = 1.0 + h + h;
x = -1.0 * ((cos(x*pi*h)) / (2.0+pi*h*sin(x*pi)) * 2.0);
``````
it kinda reminds of sinc() but not exactly
i'm fairly not good at maths, so i turn to you, any ideas?
Last edited by antto on Sat Jan 01, 2011 5:19 am, edited 1 time in total.
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.freenode.net >>> #kvr

xoxos
Mr Entertainment
12018 posts since 30 Apr, 2002 from i might peeramid
this may be qed, have a look at bandlimited impulse trains (there are links in a ~2 week recent thread).

apparently integration is far too technical a concept for any of the dozens of calculus and statistics texts i've read so far to be informative to me (integration could be just bloody adding the value of each new sample, but they don't like to say just bloody this or just bloody that).

a "sawtooth can be produced from the b.l.i.t. (that kind of blit and not the other, table kind of blit) by integration" (which is apparently better to say than "a sawtooth can be produced by adding each sample to the sum of previous samples" *if* i understand it, which is improbable).

i did actually naively superimpose a blimptrain with a naive saw, except it was a few weeks ago and i don't recall if it bandlimited effectively or was a mess. ymmv :p
you come and go, you come and go. amitabha xoxos.net free vst. neither a follower nor a leader be
where there is certainty, consideration is absent.

mystran
KVRAF
4981 posts since 12 Feb, 2006 from Helsinki, Finland
Sounds like your trying to reinvent BLEPs, which work by mixing a trivial version of the wave together with what is essentially the difference between a band-limited and trivial waves (or rather steps, since endless ramp is just an endless ramp, band-limited or not so only the discontinuities need handling).

There's also the PolyBLEP variation which works by using polynomials to approximate the band-limited steps... or something to that effect anyway.
If you'd like Signaldust to return, please ask Katinka Tuisku to resign.

antto
KVRAF
2499 posts since 4 Sep, 2006 from 127.0.0.1
thanks mystran, but isn't BLEP/BLIT based on sinc() ?
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.freenode.net >>> #kvr

Urs
u-he
22406 posts since 8 Aug, 2002 from Berlin
antto wrote:thanks mystran, but isn't BLEP/BLIT based on sinc() ?
Yes. And a bandlimited sawtooth is very much a naive sawtooth filtered with a sinc kernel - only so and so many harmonics are left.

Interesting approach though

antto
KVRAF
2499 posts since 4 Sep, 2006 from 127.0.0.1
"filtered" is not "simple"
my idea was a simple curve to be "added" to the naive sawtooth
like (sawtooth(phase) + approx(phase,H))
thus, sinc() won't work (it's kinda similar)

when H=1 there is only the fundamental harmonic, so the approx curve added to a sawtooth results in a sinewave (with an amplitude of (1.0/(pi/2.0)))

EDIT: here's a comparison:

red/green are at H=1 ... the other two are at H=6
as you can see the error is in the first part
this plot shows sawtooth with the difference curve added (the real one vs my current approximitation)
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.freenode.net >>> #kvr

kunn
KVRist
77 posts since 18 Nov, 2007 from Estonia
antto wrote:thanks mystran, but isn't BLEP/BLIT based on sinc() ?
yes, but it's all pre-calculated. u just add the BLEP to naive sawtooth at discontinuity - fixed number of additions per period (64 for me).

antto
KVRAF
2499 posts since 4 Sep, 2006 from 127.0.0.1
i'm getting close, but the approximitation starts to get ugly
well, at the end tables might be used, so hope is not lost, we'll see
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.freenode.net >>> #kvr

antto
KVRAF
2499 posts since 4 Sep, 2006 from 127.0.0.1
after i figured this is a very tough problem, i decided to make a compromise
i chose to get the best result at H=1 and let the error rise with H (which is kinda acceptable)

as you can see, there is some smallish error when H=8, but when H=1 it's very accurate..
the code behind this is very ugly right now..
my next step is to render a sawtooth sweep with this approximitation and hear/examine the quality, if it's okay the next step would be to try and optimize the code

the code right now (don't scream):

Code: Select all

``````h = floor(h); if (h <= 0.0) { h = 0.0; }
h = 1.0 + h + h;
x = x - floor(x);
double z = h * (x <= 0.5 ? (x) : (x * -1.0 + 1.0));
double zz = x;
double z1 = z * 3.3706376;
double z2 = z * z;
double z3 = z * z2 * 0.3711588;
z2 = z2 * 10.722356;
double fix = sin((z1 + z3)) / (1.2696905 + (z1 + z2 + z3) * (1.6725743));
x = ( ( cos(x * pi * h) ) / ( (2.0) + pi * h * sin(x * pi) ) * (2.0) );
x = x + fix * (zz < 0.5 ? 1.0 : -1.0);
``````
*eeeek*
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.freenode.net >>> #kvr

antto
KVRAF
2499 posts since 4 Sep, 2006 from 127.0.0.1
http://www.box.net/shared/ulra3ii0im
here's how it sounds, it turns out anything else than H=1 and the correction fails too much (the fix variable)
the correction itself is something like a weird variation of a rational function
i can add more stuff in it with hope to minimize more of the error..
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.freenode.net >>> #kvr

CalabiYauGuy
KVRer
28 posts since 28 May, 2010 from York, UK
There's one major problem with this algo...

The name is made entirely out of consonants, and BLDC doesn't sound as neat and goofy as BLIT and BLEP. :O

*drumroll* *crickets*

Okay.

It does sound pretty good though, but there is a bit of aliasing when the freq goes very high, but I don't think synths ever allow you to play that high anyway. You still have to do a DSF each time, though, don't you?
Programmer, artist and researcher.

Check out my online portfolio:
http://1stcreativesolutions.co.uk/bvera/

antto
KVRAF
2499 posts since 4 Sep, 2006 from 127.0.0.1
a better name? sure!
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.freenode.net >>> #kvr

helium
KVRist
327 posts since 13 Nov, 2002 from Germany, Darmstadt
edit : deleted my comment

antto
KVRAF
2499 posts since 4 Sep, 2006 from 127.0.0.1
i think i'll also try cos(x)/x
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.freenode.net >>> #kvr

Swiss Frank
KVRist
131 posts since 29 Aug, 2011
antto wrote:BLDC
Hey Antto, weird, I've thought the exact same thing.

My soft synth mostly uses "mipmaps" of wavetables internally, but isn't set up to make a good-sounding hard sync.