SynthMaker

Fast Compression

Archive · 2011 28 old posts

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

cyto ·

This is a gain reduction (compressor) module. Feed it something to be compressed, a control signal, and a threshold and ratio value. Does NOT rely on conversion to dBFS and back again to perform the transfer. In fact, using some algebraic wizardry and some voodoo coefficients, I was able to accomplish the same thing using only four (yes, four!) math operations.

The OSM contains the gain reduction module, an interactive graph for comparing the approximation to an "ideal" transfer curve, and a very simple example of a compressor effect using the module.

Any feedback would be much appreciated.

-cyto

infuzion ·

Wow neat idea & great execution! If you change transferCoeffs/shoulder/Float Power/Base Value to about 1.7, seems you can bring the curve in the needed [0..1] range closer to "ideal" when Thresh is -6 to -12db...? If someone can figure out a formula that will correct the ratio of Base Value to the Threshold, then you can make the curve even close to most Thresh changes IMHO.

BTW, I'm sure Trog or someone wanting to hone their ASM skills can cut the "Ideal" ASM down past 50% of CPU I'm sure.... 😉

bootsy ·

There is no reason to convert the audio path to log scale just to calculate the transfer curve. You can do all the db stuff and db2lin in green math and then compute the transfer curve on the stream. The computation is also wrong - have a look in buddhes analyzer at the transfer curve of this thing and see that the curve is bended over threshold. Thats not what we want for a compressor or limiter. A typical softknee goes bended the other way around, just as an example.

What we want a log scale conversion of the whole audio stream for is that the release curve of the envelope follower gets exponential charactaristics. So there might be some misunderstandings here.

Correct me if I'm wrong.

peace, bootsy

cyto ·

bootsy wrote: There is no reason to convert the audio path to log scale just to calculate the transfer curve.

Au Contraire! The typical compression function [((control-thresh)/ratio)+thresh] must be done on the decibel scale. We are dealing with relative volumes.

bootsy wrote: You can do all the db stuff and db2lin in green math and then compute the transfer curve on the stream.

Which is exactly what this approximation does.

bootsy wrote: The computation is also wrong - have a look in buddhes analyzer at the transfer curve of this thing and see that the curve is bended over threshold. Thats not what we want for a compressor or limiter.

Umm... this is exactly what we want for a compressor or limiter. This is definitely a hard-knee style transfer function. I don't think it would be that difficult to wrangle it a bit to make it exhibit "softer" characteristics. If I have time, I'll work on that feature.

You're right about the envelope curves. They do need special attention in the scaling to sound "good". As there are many approaches to this, I opted to completely omit any "envelope" characteristics from this module. This is simply a "number-crunching" tool.

-cyto

bootsy ·

cyto wrote: bootsy wrote: There is no reason to convert the audio path to log scale just to calculate the transfer curve.

Au Contraire! The typical compression function [((control-thresh)/ratio)+thresh] must be done on the decibel scale. We are dealing with relative volumes.

bootsy wrote: You can do all the db stuff and db2lin in green math and then compute the transfer curve on the stream.

Which is exactly what this approximation does.

I have to insist: The transfer curve is a completely static affair and so there is no difference if I compare to threshold of 0dbFS in log scale or to 1 in linear scale just as an example. If threshold is -6dB then I compare to (around) 0.5 in linear scale. The very same applies to the ratio computation which is (in the linear curve case) just a multiplication in either domain. Thats it and there is no log encoding of the audio itself needed just to compute such a transfer curve.

bootsy wrote: The computation is also wrong - have a look in buddhes analyzer at the transfer curve of this thing and see that the curve is bended over threshold. Thats not what we want for a compressor or limiter.

Umm... this is exactly what we want for a compressor or limiter. This is definitely a hard-knee style transfer function. I don't think it would be that difficult to wrangle it a bit to make it exhibit "softer" characteristics. If I have time, I'll work on that feature.

What I did was just to compile the compressor example which was included in your osm and hooked it right into the analyzer. It showed a bended curve above threshold. I will check that again when I'm back home again by tomorrow and report back.

peace, bootsy

bootsy ·

this is what I've meant ...

cyto ·

Bootsy, That graph is a little misleading. Most of the "bend" occurs between +20dB and +40dB - which translates to a normalized value of 10-100! Actually, I'm surprised its not even more off at such extreme settings. The point of this module is to provide an efficient means of calculating an otherwise intensive operation. If you want "clinical" results (esp. from extreme settings like control values 10x - 100x out of the average range), then this isn't for you. You're better off doing it the "right" way.

Having said that, I did a little more work to address some of the issues that infuzion brought up regarding the transfer curve at lower threshold settings. I also added a "soft-knee" option that provides a very gentle response. Also, in the graph tool, I added a transfer graph (like the output of the VST analiser) so you can see the response in real time without having to export a .dll

I may come off as standoffish, but I really do appreciate the criticism. Keep it coming 🙂

-cyto

Andrew J ·

bootsy wrote: I have to insist: The transfer curve is a completely static affair and so there is no difference if I compare to threshold of 0dbFS in log scale or to 1 in linear scale just as an example. If threshold is -6dB then I compare to (around) 0.5 in linear scale. The very same applies to the ratio computation which is (in the linear curve case) just a multiplication in either domain. Thats it and there is no log encoding of the audio itself needed just to compute such a transfer curve.

Bootsy, are you talking about calculating a look up table of the transfer curve (linear units) in green and then interpolating in asm?

infuzion ·

cyto wrote: Having said that, I did a little more work to address some of the issues that infuzion brought up regarding the transfer curve at lower threshold settings.

Oh wow, that came out quite nice, thanks! I really was only worried for the range about -12...-6db, where alot of settings are, but you have the entire range very close to the "ideal". Cheers!

bootsy ·

Andrew J wrote: bootsy wrote: I have to insist: The transfer curve is a completely static affair and so there is no difference if I compare to threshold of 0dbFS in log scale or to 1 in linear scale just as an example. If threshold is -6dB then I compare to (around) 0.5 in linear scale. The very same applies to the ratio computation which is (in the linear curve case) just a multiplication in either domain. Thats it and there is no log encoding of the audio itself needed just to compute such a transfer curve.

Bootsy, are you talking about calculating a look up table of the transfer curve (linear units) in green and then interpolating in asm?

I'm usually doing all in code which in case of this simple transfer curve should be pretty much easy, out of my memory something like

out = in & in<=threshold + (in*inverseratio) & in>threshold;

where in, out and threshold is in linear scale.

I've implemented lots of non-linear curves this way and by piece-wise polynomial computation where one can usually put lots of computations outside into green math to save cpu. Bézier curves are used by others as an alternative as well (there are also examples here somewhere in the forum).

I really don't wanted to bust the party here, I'm in here to learn as well! Let's see to which further insights this great discussion will lead to ...

peace, bootsy

Andrew J ·

bootsy wrote: I'm usually doing all in code which in case of this simple transfer curve should be pretty much easy, out of my memory something like

out = in & in<=threshold + (in*inverseratio) & in>threshold;

where in, out and threshold is in linear scale.

OK you probably meant:

out = in & in<=threshold + ((in-threshold)*inverseratio+threshold) & in>threshold;

That's linear compression. So if you had a 2:1 ratio then for every 2 milliVolts above your threshold, the output rises by 1 milliVolt.

Most compressors work on dB compression - which is what cyto is talking about. In that case for every 2 dB above your threshold, the output rises by 1 dB.

The following charts illustrate the difference between linear & dB compression for a threshold set at -25 dBFS and a ratio of 8:1. The first chart shows the transfer functions in a dB domain, and the second shows them in the linear domain. (Click once on each chart to see the whole graphic.)

trogluddite ·

Thanks to all. 🙂 I've been trying to make a nice smooth 'auto gain control' for one of my plugins - I knew I needed soft-knee, rms, dB scale compression - but then I slammed head on into my 'maths brick wall' and it ended up sounding like a two year-old had got hold of my volume control! Thanks to your discussion (and especially the pictures!), I think I have discovered where I am going wrong.

@cyto - your approximations are a beautiful example of 'algorithm economy' - I think I may have to enlarge the 'credits window' on my plugin!!

Dell ·

I believe this compressor is more suited as a limiter than say the constant rise and fall of a traditional compressor. I’ve created a short video that compares the Continuous Average (RMS) –vs- Peak ratio without the aid of brick wall voltage limiting.

http://v.youku.com/v_show/id_XMzEyODAzNjUy.html

The video is hosted on YOUKU for they are more open to videos globally than youtube.

The module inside is the original version for, I find it calculates better from a dB standpoint than the updated versions. But of course, I am not a Rock person so you may beg to differ. 😉

Cheers!

infuzion ·

Dell wrote: http://v.youku.com/v_show/id_XMzEyODAzNjUy.html The module inside is the original version for, I find it calculates better from a dB standpoint than the updated versions. But of course, I am not a Rock person so you may beg to differ.

Get Funky!! Thanks for the vid; now I'm sick with Disco fever 😉 What settings are you talking about for "better dB" please?

trogluddite ·

Dell wrote: I believe this compressor is more suited as a limiter

But surely that is a limitation (sorry, no pun intended!) of the level detection method and time constants rather than the curve approximation?

One of the great things about cyto's design is that he has kept the various modules separate, so that we can use whatever detection/time constant method is best for the application, yet still make use of his 'CPU lite' transfer curve.

Dell ·

infuzion wrote: Dell wrote: http://v.youku.com/v_show/id_XMzEyODAzNjUy.html The module inside is the original version for, I find it calculates better from a dB standpoint than the updated versions. But of course, I am not a Rock person so you may beg to differ.

Get Funky!! Thanks for the vid; now I'm sick with Disco fever 😉 What settings are you talking about for "better dB" please?

The original version seems to have better control over fast transients. The updated versions appear to let some peaks leak through which offers more overshoot.

To my ears the updated version sounds more dynamic whereas the older version is more squashed.

infuzion ·

Dell wrote: infuzion wrote: Dell wrote: http://v.youku.com/v_show/id_XMzEyODAzNjUy.html The module inside is the original version for, I find it calculates better from a dB standpoint than the updated versions. But of course, I am not a Rock person so you may beg to differ.

What settings are you talking about for "better dB" please?

The original version seems to have better control over fast transients. The updated versions appear to let some peaks leak through which offers more overshoot. To my ears the updated version sounds more dynamic whereas the older version is more squashed.

Well, if more peaks get through, then the "dynamic range" is indeed larger.

Dell ·

trogluddite wrote: Dell wrote: I believe this compressor is more suited as a limiter

But surely that is a limitation (sorry, no pun intended!) of the level detection method and time constants rather than the curve approximation?

Yes. However, the majority of commercial limiters I've tried, will not allow you to achieve -0.3 dB, -0.2 dB and/or -0.1 dB Peaks with a continuous average (RMS) of -6 dB without the means of brick wall limiting. So it is very precise in that respect.

The majority of Commercial Limiters, that do not offer some type of brick wall circuitry, tend to get very sporadic when asked to limit peaks below 0.5 dB.

One of the great things about cyto's design is that he has kept the various modules separate, so that we can use whatever detection/time constant method is best for the application, yet still make use of his 'CPU lite' transfer curve.

Absolutely!

With a creative imagination you can go far with this design.

cyto ·

Dell wrote: I believe this compressor is more suited as a limiter than say the constant rise and fall of a traditional compressor.

There is a very good (but maybe hard to explain) reason that this is true. Essentially, the coefficients are calculated in this order: B (which is the "sharpness" of the curve near the origin), A (which is the vertical offset), then C (which is the horizontal offset). The issue stems from the way in which the A coefficient is calculated. Basically it finds the distance of the "ideal" curve from the x-axis at a certain arbitrary point (I use the value 24) and offsets the approximation to align at that point. Then, the C coefficient is calculated by simply inserting the B and A coefficients into the transfer curve, inserting threshold into the x-value and 1 into the y-value, and solving for C. What ends up happening is that by calculating the C value in such a way, you are effectively destroying the assumptions of the previous calculations (I hear particle physicists have this same problem 🙂 ) The reason the approximation is more accurate at higher ratio settings is that at such high settings the "ideal" and the approximation are converging on the asymptote (x-axis) at more consistent rates so there is very little vertical offset needed (and therefore less assumptions to destroy). If you're with me this far, I applaud you! I'm trying to wrangle this a little more to find a way to calculate the two offsets concurrently. I have a working theory, but it's taking me awhile to work out. Hopefully, I'll have something to report back with later.

trogluddite wrote: ...is that he has kept the various modules separate, so that we can use whatever detection/time constant method is best for the application.

Yes. I'm not going to do all the work 🙂

The original idea for this little guy was to be incorporated into larger effects. For instance, to "duck" a long, repeating delay signal in response to the volume of the dry signal. Or other similar scenarios. I'm glad you guys are finding it useful.

-cyto

Tzarls ·

Any way to have this 2 versions without SM2 primitives? I´m still using 1.1.7 and the schematics won´t load.... 🙁 Unless, of course, those primitives are essential...

infuzion ·

Tzarls wrote: Any way to have this 2 versions without SM2 primitives? I´m still using 1.1.7 and the schematics won´t load.... 🙁 Unless, of course, those primitives are essential...

Is that the free CM version? You can download the free version of SM2.0, & install it in a sandbox. I think the De-zip primitive, some of the array stuff in the graph displays, & "Pergeable" module are the only things new in the OSM. Would help if someone updated the component listing & detail pages for when a primitive was added & updated.

Tzarls ·

CM version? No! 1.1.7 was the last SM1 version released... Interesting thing that Sandboxie app, BTW.

bootsy ·

Cyto, I was wrong of course. Whenever I've worked in linear scale I've got my polynomial (softknee) stuff rendered pretty much easy and wasn't aware of such implications. I'm sorry for the confusion! 😊

cyto ·

bootsy wrote: I'm sorry for the confusion!

Actually, bootsy, you helped more than you know! Our earlier exchange got me critically thinking about concepts that we all kinda take for granted. This led to some new perspectives and ideas that might materialize in future projects. Also, you're analysis did exposed some weaknesses in my work that others should be aware of when they use this thing. That's why I like this forum: as we all work our way through the confusion, some brilliant things happen.

-cyto

Dell ·

cyto wrote: There is a very good (but maybe hard to explain) reason that this is true. Essentially, the coefficients are calculated in this order: B (which is the "sharpness" of the curve near the origin), A (which is the vertical offset), then C (which is the horizontal offset). The issue stems from the way in which the A coefficient is calculated. Basically it finds the distance of the "ideal" curve from the x-axis at a certain arbitrary point (I use the value 24) and offsets the approximation to align at that point. Then, the C coefficient is calculated by simply inserting the B and A coefficients into the transfer curve, inserting threshold into the x-value and 1 into the y-value, and solving for C. What ends up happening is that by calculating the C value in such a way, you are effectively destroying the assumptions of the previous calculations (I hear particle physicists have this same problem 🙂 ) The reason the approximation is more accurate at higher ratio settings is that at such high settings the "ideal" and the approximation are converging on the asymptote (x-axis) at more consistent rates so there is very little vertical offset needed (and therefore less assumptions to destroy). If you're with me this far, I applaud you! I'm trying to wrangle this a little more to find a way to calculate the two offsets concurrently. I have a working theory, but it's taking me awhile to work out. Hopefully, I'll have something to report back with later.

-cyto

Understanding is not a problem. Like others who speak from a digital perspective I merely convert it into analogue analogy. 🙂

Actually, bootsy, you helped more than you know! Our earlier exchange got me critically thinking about concepts that we all kinda take for granted. This led to some new perspectives and ideas that might materialize in future projects. Also, you're analysis did exposed some weaknesses in my work that others should be aware of when they use this thing. That's why I like this forum: as we all work our way through the confusion, some brilliant things happen.

-cyto

I’m quite certain anyone who chooses to use your OSM will modify it for his or her requirements.

Cheers!

McBarGig ·

Wow! Just Wow... Nice work Cyto!

DhyanMikael ·

Thank you Cyto for this example. Just what I need right now!

I have a question. How do I modify the fast compressor to turn it into a fast expander (gate)? I know it's simpe but I have no clue about these things...

Best regards, Mikael

cyto ·

DhyanMikael wrote: Thank you Cyto for this example. Just what I need right now!

I'm glad you like it! If you are a registered user, you may want to look over at [old link] to get some ideas for envelope followers. You can tell from my posts there that I am not a huge fan of the stock EF! 😈

DhyanMikael wrote: I have a question. How do I modify the fast compressor to turn it into a fast expander (gate)? I know it's simpe but I have no clue about these things...l

It may not be as simple as you think. Give me a couple of days to think about it and I'll see if I can come up with a solution. I have a bunch of projects going on right now that I need to finish up, but maybe over the weekend I can look at it.

-cyto

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.