SynthMaker

Fast Soft Clip / Saturation Algo

Archive · 2008 47 old posts

From the original SynthMaker forum (2004–2014), with its members’ names and dates.

exonerate ·

I've developed a soft clip / saturation (not sure what to call it really) Algorithm 🙂

This is the code.....

streamin in; streamin amount; streamout out;

float F1=1;

movaps xmm1,in; movaps xmm2,xmm1; mulps xmm1,xmm1; mulps xmm1,amount; addps xmm1,F1; divps xmm2,xmm1; movaps out,xmm2;

And yes theres one divide but It's trivial in such a small piece of code 🙂

The algo is that simple its probably already known by everyone but me. 🙂

I've up loaded an OSM here.....http://www.box.net/shared/hzlkc1bwck , I've double sampled the code in the OSM, made quite a difference actually.

Cheers 😉

Exo

oddson ·

Any chance of a code/pseudo-code version for those of us who don't speak assembly? 🙂

exonerate ·

oddson wrote: Any chance of a code/pseudo-code version for those of us who don't speak assembly? 🙂

oh yeah good point:)

basically it's

out = in / (((in*in)*amount)+1);

Nu Audio Science ·

Very cool 🙂

NAS

Andrew J ·

Here's another one. I can't remember where I got the original formula from, so if anyone recognises it, please let me know so I can credit it properly.

streamin in; streamout out;

float x; float a,b;

x = in * 2; a = x - (x < 0 & (x+x)); b = (6+a*(3+a)); out = (x*b)/(a*b+12);

streamin in;streamout out; int absmask=2147483647; float F6=6;float F3=3;float F12=12; movaps xmm0,in;addps xmm0,xmm0; movaps xmm1,xmm0;andps xmm0,absmask; movaps xmm2,xmm0;addps xmm0,F3; mulps xmm0,xmm2;addps xmm0,F6; movaps xmm3,xmm0;mulps xmm3,xmm2; addps xmm3,F12;mulps xmm1,xmm0; divps xmm1,xmm3;movaps out,xmm1;

infuzion ·

exonerate wrote: I've double sampled the code in the OSM, made quite a difference actually.

I don't understand what your double sampling does? I might not understand the concept...

Acrobat ·

Andrew J wrote: Here's another one. I can't remember where I got the original formula from, so if anyone recognises it, please let me know so I can credit it properly.

Same situation here, I think I've recollected from a thread, last autumn approx... 😕

No, EDIT, it's the SM stock overdrive!

exonerate ·

infuzion wrote: exonerate wrote: I've double sampled the code in the OSM, made quite a difference actually.

I don't understand what your double sampling does? I might not understand the concept...

Its basically oversampling by 2, It will limit aliasing, I'm not much of an expert on this stuff but Its seems from what I've read it's standard procedure to oversample things like saturation, distortion or overdrive ect... which can cause aliasing.

Although I've just tested it and it doesn't noticeably remove any aliasing. I thought it made a difference in a test I did before but it doesn't seem too actually.

Cheers 😉

Exo

exonerate ·

I made this because I wanted an efficient way to clip the output of my synth, you can use hard clipping. With min/max but this will cut the top and bottom off the waveform if it goes above 1 or below -1.

With soft clipping you get a more natural sound, it adds a bit of colouration but this is a good thing I think as long as it's not over done.

What I plan to do is put the soft clip at the end of my signal chain in mono and then find the perfect setting using the knob, then I'll remove the knob and use a static value in stead.

When I get round to making some more filters I'll probably use it in them as well. 🙂

cheers 😉

Exo[/code]

Acrobat ·

thx for sharing, I'll test on Alieno where I use hardclipping and that's not fair.. with such a tool, I could raise the overall level and be safe it won't go creeeeaaauouk 🙂

Andrew J ·

Acrobat wrote: No, EDIT, it's the SM stock overdrive!

Aha - so it is! Thanks Andrea. Well there's my hand-optimised ASM version for everyone anyway!

Acrobat ·

Andrew J wrote: Acrobat wrote: No, EDIT, it's the SM stock overdrive!

Aha - so it is! Thanks Andrea. Well there's my hand-optimised ASM version for everyone anyway!

thx, actually I use that drive in Modo, my new synth in development, and I'm already at 10% CPU so it will be good to calm down things a bit... 🙂

Tom7777 ·

Acrobat, did you know thats a name of a 3d app, just wanted to let you know if you didn't, names are a annoying thing as there usually already taken even if it seems unique.

sunsynth ·

Thanks exo,

now i think i add a saturator 2 my project 2 😉

Walter

Acrobat ·

Tom7777 wrote: Acrobat, did you know thats a name of a 3d app, just wanted to let you know if you didn't, names are a annoying thing as there usually already taken even if it seems unique.

Oh thx... mmh. at least it's not an audio app, I'll think about it, sure I can come out with something else...

Andrew J ·

exonerate wrote: Its basically oversampling by 2

Sorry exo but its not - its just running the same instructions a second time and making no difference to the output.

To get a benefit from oversampling you need to interpolate extra samples and feed them into a decimating filter (which does your low pass filtering and down sampling). The point of oversampling is to reduce the roll-off requirements in order to make it easier to build a good decimating filter which is computationally "cheaper".

So without any filtering on the output of the clipper, you're not removing any aliases. And without making use of interpolated samples you can't make use of a "cheap" decimator.

Now having said all that, your clipper is second order, so I think the aliases should fall above Nyquist anyway. On the other hand, the one I posted looks like its cubic so would need 2x oversampling and then decimating.

Regards, Andrew

Acrobat ·

Andrew J wrote: exonerate wrote: Its basically oversampling by 2

Sorry exo but its not - its just running the same instructions a second time and making no difference to the output.

To get a benefit from oversampling you need to interpolate extra samples and feed them into a decimating filter (which does your low pass filtering and down sampling). The point of oversampling is to reduce the roll-off requirements in order to make it easier to build a good decimating filter which is computationally "cheaper".

😕 😕 ..perhaps like in SVF filter, dividing by 0.3333333333 and summing up the results? I don't get very well the whole oversampling affair, maybe it's just over my head... if you have some spare time, why don't you write a wiki tutorial on that argument? 😕

aliasant ·

Acrobat wrote: Andrew J wrote: exonerate wrote: Its basically oversampling by 2

Sorry exo but its not - its just running the same instructions a second time and making no difference to the output.

To get a benefit from oversampling you need to interpolate extra samples and feed them into a decimating filter (which does your low pass filtering and down sampling). The point of oversampling is to reduce the roll-off requirements in order to make it easier to build a good decimating filter which is computationally "cheaper".

😕 😕 ..perhaps like in SVF filter, dividing by 0.3333333333 and summing up the results? I don't get very well the whole oversampling affair, maybe it's just over my head... if you have some spare time, why don't you write a wiki tutorial on that argument? 😕

Feel comfort in the fact that your not alone Acrobat....

Acrobat ·

aliasant wrote: Feel comfort in the fact that your not alone Acrobat....

Yeah well ATM when I look at oversampling it's like a star that's collapsing or exploding, it might be that I will get it or maybe I'll just peacely took over an' ask: another Martini please...

infuzion ·

Andrew J wrote: Acrobat wrote: No, EDIT, it's the SM stock overdrive!

Aha - so it is! Thanks Andrea. Well there's my hand-optimised ASM version for everyone anyway!

I'm sure it was on the forum before becoming a stock module. BTW, great job in the ASM optimization! Put it on the WIKI yet?

Tom7777 ·

Oh thx... mmh. at least it's not an audio app, I'll think about it, sure I can come out with something else...

Np, it happened with a synth called cobalt which was going to be called litewave or something similar and there was a 3d app called that so they changed it. It probably wouldn't matter but its up to the company that registered the name i guess so always good to have another option just in case.

exonerate ·

Andrew J wrote: exonerate wrote: Its basically oversampling by 2

Sorry exo but its not - its just running the same instructions a second time and making no difference to the output.

To get a benefit from oversampling you need to interpolate extra samples and feed them into a decimating filter (which does your low pass filtering and down sampling). The point of oversampling is to reduce the roll-off requirements in order to make it easier to build a good decimating filter which is computationally "cheaper".

So without any filtering on the output of the clipper, you're not removing any aliases. And without making use of interpolated samples you can't make use of a "cheap" decimator.

Now having said all that, your clipper is second order, so I think the aliases should fall above Nyquist anyway. On the other hand, the one I posted looks like its cubic so would need 2x oversampling and then decimating.

Regards, Andrew

Yeah I don't really understand how the double sampling works but the examples I've seen that use double sampling seemed to run the same code twice, although I guess this isn't the case.

If I get what your saying then this code is oversampled?

streamin in; streamin amount; streamout out; float x,oldx;

oldx = x;

x = in/(((in*in)*amount)+1);

out = out+(x-oldx);

out = out +(in-out)*0.2;

There definetly less aliasing with that version, although that could just be down to the filter, I'm not sure.

===Edit=== scrap that code I'm just a noob, all it's doing is filtering the signal theres no saturation going on.

cheers 😉

Exo

infuzion ·

Andrew J wrote: Now having said all that, your clipper is second order, so I think the aliases should fall above Nyquist anyway. On the other hand, the one I posted looks like its cubic so would need 2x oversampling and then decimating.

How do you figure all that out please? I'm not well skilled on actual audio math stuff.

exonerate ·

But anyway disregarding the last out line, (the filter) is the out interpolating between samples? is that how it's done, or is it not that simple?

Cheers 😉

Exo

Andrew J ·

Acrobat wrote: 😕 😕 ..perhaps like in SVF filter, dividing by 0.3333333333 and summing up the results? I don't get very well the whole oversampling affair, maybe it's just over my head... if you have some spare time, why don't you write a wiki tutorial on that argument? 😕

I'm familiar with some of these concepts as a radio engineer, but haven't yet built a decimator and used it with audio. So I'll hold off any wiki advice until I've managed to achieve that!

infuzion ·

urm... how about searching the SM forums for "oversampling"? There are a few good threads, inc OSMs.

Maybe asking on KVR etc?

Andrew J ·

exonerate wrote: Yeah I don't really understand how the double sampling works but the examples I've seen that use double sampling seemed to run the same code twice, although I guess this isn't the case.

Yeah but you need to make use of the two results you calculate and input them into your decimator filter. What would be the point of running the code twice on the same input data? You already know what the answer is going to be. If you want to simply repeat the current value, then you just use what you've already calculated. However, if you interpolate a new input value, then of course you need to run the code a second time so you know what the output for that new in-between sample is.

exonerate wrote: If I get what your saying then this code is oversampled?

streamin in; streamin amount; streamout out; float x,oldx;

oldx = x;

x = in/(((in*in)*amount)+1);

out = out+(x-oldx);

out = out +(in-out)*0.2;

There definetly less aliasing with that version, although that could just be down to the filter, I'm not sure.

===Edit=== scrap that code I'm just a noob, all it's doing is filtering the signal theres no saturation going on.

If you scrap that last line, then what you have is out = out+(x-oldx) which looks like a pretty transparent filter (with no roll-off!).

Andrew J ·

infuzion - yeah I've been reading the forums and found kingston/sambean's effort which is great but has a one sample delay. I'll play with that a bit and with a few other things. If I can make good sense of it all, I might write a tutorial on it and put it all on the wiki...

infuzion ·

Cool Andrew. I'm thinking that you'll need atleast 2 samples to interpolate? I'm also assuming that (esp back then) you'd end the audio path with an env with a very fast attack & perhaps fast release (if not 0 release) to help with key-on clicks, so a 1-sample delay would either circumvent or be reduced by that env.

Andrew J ·

infuzion wrote: Cool Andrew. I'm thinking that you'll need atleast 2 samples to interpolate? I'm also assuming that (esp back then) you'd end the audio path with an env with a very fast attack & perhaps fast release (if not 0 release) to help with key-on clicks, so a 1-sample delay would either circumvent or be reduced by that env.

If you're using this in synths - then yeah I guess that's right. Then again, how much would you worry about a one sample delay in a synth?

bootsy ·

yeah, a small delay shouldn't be the issue. It's harder and more important to achieve a steep and low ripple lowpass at affordable cpu consumption. Minimum phase or even phase linear filter is important too if maximum transparency is needed.

bootsy ·

I'm currently trying to understand these "double sampling" concept (like used in the SVF): What it basically does is to "look a head" one sample (or even more) and averaging current and upcoming samples value. Shouldn't that introduce a LP filtering effect? Will probably test that tonight ...

infuzion ·

bootsy wrote: I'm currently trying to understand these "double sampling" concept (like used in the SVF): What it basically does is to "look a head" one sample (or even more) and averaging current and upcoming samples value. Shouldn't that introduce a LP filtering effect? Will probably test that tonight ...

I thought LP would subtract the difference? You're just simulating a double sampling rate here; eg looking at 88.2/kps of samples at a 44.1/kps rate?

bootsy ·

If averaging occurs then some HF will filtered out as one can easily imagine. Every moving average filter or RMS thingy is in that way a lowpass.

I've just checked the SVF in the analyser but unfortunately that looks really awful and there must be something serious wrong with that module. If you select e.g. highpass thats not an highpass at all, weird. I'll continue ...

Acrobat ·

bootsy wrote: If you select e.g. highpass thats not an highpass at all, weird. I'll continue ...

On SVF: It also happens that the HighPass mode consumes much more CPU than the other modes.. 😕

Andrew J ·

infuzion wrote: Andrew J wrote: Now having said all that, your clipper is second order, so I think the aliases should fall above Nyquist anyway. On the other hand, the one I posted looks like its cubic so would need 2x oversampling and then decimating.

How do you figure all that out please? I'm not well skilled on actual audio math stuff.

Sorry, forgot to answer this yesterday - and just as well because I was a bit wrong!

When you produce aliases with a second order non-linearity (i.e. x^2), you're adding harmonics and extending the bandwidth of your signal by a factor of two. So let's say we're working at 48kHz, then the Nyquist frequency is at 24kHz. If you assume that you use audio bandwidth all the way up to 24kHz, then the non-linearity extends the audio up to 48kHz. As this information is above Nyquist, then we'll get aliasing distortion at the D/A stage.

Now, if we oversample by 2x, then Nyquist is moved to 48kHz and we're all OK. In fact, because we're really only interested in audio up to 24kHz there's room to spare - we could actually accommodate a 3rd order non-linearity. Here's how.

If we had a third-order linearity, then the added harmonics would extend the audio out to 24*3=72kHz. Remembering that our sampling rate at 2x is now 96kHz, we have Nyquist at 48 kHz and the audio now extends beyond that. Normally this is a problem, but in our case we're oversampling and we're still really only interested in our baseband audio which goes up to 24 kHz. So when we downsample, our decimating filter should remove the troublesome aliases between 24kHz and our Nyquist of 48kHz.

As a general rule, you should be able to get away with an oversampling ratio which is equal to (n+1)/2, where n is the order of the non-linearity. The thing to watch here though is that you need a good decimating filter to get away with this (i.e. one where it leaves nothing above your original Nyquist frequency). If you're using a really simple filter, you might need to stick with oversampling at a factor of n.

-Andrew

hansdump ·

I wonder if it is possible to make a real softclip at a certain given value.

I mean all values between -10 and 10 in 16Bit resolution for example.

Not only abs(1) to abs (0.5) or so....

Some kind of shoulder the inputstream at a given input value.

How to do that?

H.

hansdump ·

So gentlemen... here is that patent...

http://www.patentstorm.us/patents/48779 ... ption.html

It is such a pitty that all this is situated in the analog world... 😠

n8!

bootsy ·

what is so special about that?

hansdump ·

I think this could be very useful for circuit simulation.

hansdump ·

And the other thing...I don´t see and hear any effect from this double sampling in exo´s code. I think this is only cpu barbecue.

I thought the foundations of oversampling are:

1. zero stuffing 2. lp filtering 3. nonlinear processing 4. downsampling 5 lp filtering

So where are the lowpass filters here?

exonerate ·

hansdump wrote: And the other thing...I don´t see and hear any effect from this double sampling in exo´s code. I think this is only cpu barbecue.

I thought the foundations of oversampling are:

1. zero stuffing 2. lp filtering 3. nonlinear processing 4. downsampling 5 lp filtering

So where are the lowpass filters here?

No it doesn't make any difference, it only adds to CPU. When I posted this I thought I was oversampling but I didn't actually understand exactly how oversampling worked at the time. I just writ the same code twice, a noob mistake Andrew J pointed it out to me, was so obvious that couldn't possibly work. hehe

Cheers 😉

Exo

hansdump ·

sry 4 that hard words... because of these things we are in this forum here...

🙂

hansdump ·

and softclip at a certain value is such an easy task.... I´m such a fool:

so one just have to do:

output = clipvalue * tanh(input/clipvalue)

Im sure thats sure for ya... 😊

H.

hansdump ·

.. and this is my last post for today here... a very very close approximation of tanh directly on the fly from octave to you... the cheap clip algo presented here is nice and cheap, but not very stable on values over 1.

so check this here:

y3 = (0.1076*x.^3 + 3.029*x ) ./(x.^2 + 3.124 ) is approximately tanh(x)

stabiltiy from -5 to 5 guaranteed!

H.

vokal ·

exonerate wrote: I've developed a soft clip / saturation (not sure what to call it really) Algorithm 🙂

This is the code.....

streamin in; streamin amount; streamout out;

float F1=1;

movaps xmm1,in; movaps xmm2,xmm1; mulps xmm1,xmm1; mulps xmm1,amount; addps xmm1,F1; divps xmm2,xmm1; movaps out,xmm2;

And yes theres one divide but It's trivial in such a small piece of code 🙂

The algo is that simple its probably already known by everyone but me. 🙂

I've up loaded an OSM here.....http://www.box.net/shared/hzlkc1bwck , I've double sampled the code in the OSM, made quite a difference actually.

Cheers 😉

Exo

Excuse my ignorace (haha) but how would I implement this code?

DigitalWhiteByte ·

Example for code is into osm linked. Opend osm, see into module Soft Clip -> Fast Saturation

Wrote something here? To have a post removed or your name hidden, write to [email protected].

Before your first post

A few rules keep this a friendly place. You agree to them once.

Shown next to what you post, here and in the app. It doesn’t have to be your real name: 3–24 lower-case letters, digits or _ (capitals become lower case, spaces become _).

    Then your post goes up straight away.

    Delete this reply?

    Open it in SynthMaker?

    It goes on the track you’re editing there, in place of that track’s sound, and into My sounds. Your other tracks stay as they are.

    Want to keep that track’s sound? Start a new song in SynthMaker first (Song › New song), then open this.

    Report this reply?

    Only the developer reads reports. The person isn’t told who reported them.

    What’s wrong with it?

    Block this person?

    You won’t see their posts and replies here any more. They aren’t told, and you can unblock them at any time.

    People you’ve blocked

    Their posts and replies are hidden from you. Unblock someone to see them again.

    The community rules

    A few rules keep this a friendly place. Everyone agrees to them once, before their first post.