Aliasing in zero-crossing compressor?
-
- KVRist
- 80 posts since 13 Mar, 2005
I was wondering if one built a compressor that looks at a half-cycle of a waveform and reduces its amplitude, does it still produce aliasing artifacts like conventional compressors?
-
- KVRAF
- 8389 posts since 11 Apr, 2003 from back on the hillside again - but now with a garden!
you would then have a dynamic asymmetric distortion, giving nice even harmonics, and you would have a variable DC component.
I actually quite like the sound of that, I might even go one step further and add a second unit for doing the other half of the signal.
As for reducing aliasing, I feel it would increase it, rather than decrease!
DSP
I actually quite like the sound of that, I might even go one step further and add a second unit for doing the other half of the signal.
As for reducing aliasing, I feel it would increase it, rather than decrease!
DSP
- KVRAF
- 9590 posts since 17 Sep, 2002 from Gothenburg Sweden
Why would a compressor produce aliasing ? It's just volume adjustments. Obviously you'd probably use some non-linearities in there but the compressor initself does'nt produce aliasing,does it ?
-
- KVRian
- 626 posts since 29 Jul, 2003 from Paris - France
well a compressor multiplies its input signal by a variable gain:
it's a special case of Amplitude Modulation.
Amplitude Modulation will shift the spectrum depending on the gain signal. and if some harmonics are shifted above the nyquist frequency (half the sampling rate) there will be aliasing.
The frequency content of the gain signal is usually mainly low frequencies becaus of the enveloppe follower and the attack and release time filters -> the frequency shift is usually not that big.
However with very fast attack time (0.1ms) and depending on the enveloppe follower, you might have noticeable aliasing unless the compressor is oversampled.
the theory tells you that you need the nyquist frequency to be above the sum of the bandwdth of your 2 signals.
it's a special case of Amplitude Modulation.
Amplitude Modulation will shift the spectrum depending on the gain signal. and if some harmonics are shifted above the nyquist frequency (half the sampling rate) there will be aliasing.
The frequency content of the gain signal is usually mainly low frequencies becaus of the enveloppe follower and the attack and release time filters -> the frequency shift is usually not that big.
However with very fast attack time (0.1ms) and depending on the enveloppe follower, you might have noticeable aliasing unless the compressor is oversampled.
the theory tells you that you need the nyquist frequency to be above the sum of the bandwdth of your 2 signals.
- KVRAF
- 9590 posts since 17 Sep, 2002 from Gothenburg Sweden
I knew this.mdsp wrote:it's a special case of Amplitude Modulation.
Amplitude Modulation will shift the spectrum depending on the gain signal. and if some harmonics are shifted above the nyquist frequency (half the sampling rate) there will be aliasing.
I knew this.mdsp wrote:The frequency content of the gain signal is usually mainly low frequencies becaus of the enveloppe follower and the attack and release time filters -> the frequency shift is usually not that big
However did'nt put 2 and 2 together and thought of this.mdsp wrote:However with very fast attack time (0.1ms) and depending on the enveloppe follower, you might have noticeable aliasing unless the compressor is oversampled.
Thanks.
-
- KVRAF
- 8389 posts since 11 Apr, 2003 from back on the hillside again - but now with a garden!
- KVRAF
- 4030 posts since 7 Sep, 2002
Before you get to oversampling issue you should at first make sure your gain signal is produced correctly. A simple if(a>1)a=1; is such a complex function it immediately produces a lot of aliasing: just try to create a polynomial for that function and you'll get what I mean: you'll have to use a polynomial with a large number of elements, and that translates to "x" under a high power: and that may extend the spectrum very far.
So, before doing anything you should be sure function you use does not alias.
For example, fabs(x) is a highly-aliased function and I think it's one of the reasons 'digital' compressors does not sound the way they could. To make it less aliased you have to build two anti-aliased polynomials that clamp positive and negative values separately, and then subtract their results (that will be analogous to diode rectification). Of course, in most cases it's simpler to oversample in the first place.
After you've got your 'super clean' fabs(x) you can apply an inverse waveshaping function (which should be also anti-aliased by means of polynomial) to derive a multiplier signal you may use for compressing the input signal.
If you are using an "attack/release" controls inside the waveshaping function you may separate attack and release by applying release fall-off constantly (like a discharge) and engaging attack only when necessary (that will be charging). As was shown, it's better to replace all "if" constructs with continuous polynomials (they will be acting like diodes). So, instead of "if(a>env)env += ( a - env ) * attack_coeff" it's better to express it that way: env += clamp( a ) * attack_coeff, followed by release stage:
env *= release_coeff (well, this one can be made more complex, just do not forget about anti-aliasing.
Well, I've shown all my secrets now.
Actually, all this is not secret as analog schematics have no aliasing happening inside them: hence they have a better potential to sound cleaner. But after doing DSP compression the way I've described no way an analog compressor will sound better. 
Of course, on the last stage of multiplying input signal by gain signal you have to be at 2x oversampling since you will be getting aliasing without this (only multiplication by a constant value does not produce aliasing).
So, before doing anything you should be sure function you use does not alias.
For example, fabs(x) is a highly-aliased function and I think it's one of the reasons 'digital' compressors does not sound the way they could. To make it less aliased you have to build two anti-aliased polynomials that clamp positive and negative values separately, and then subtract their results (that will be analogous to diode rectification). Of course, in most cases it's simpler to oversample in the first place.
After you've got your 'super clean' fabs(x) you can apply an inverse waveshaping function (which should be also anti-aliased by means of polynomial) to derive a multiplier signal you may use for compressing the input signal.
If you are using an "attack/release" controls inside the waveshaping function you may separate attack and release by applying release fall-off constantly (like a discharge) and engaging attack only when necessary (that will be charging). As was shown, it's better to replace all "if" constructs with continuous polynomials (they will be acting like diodes). So, instead of "if(a>env)env += ( a - env ) * attack_coeff" it's better to express it that way: env += clamp( a ) * attack_coeff, followed by release stage:
env *= release_coeff (well, this one can be made more complex, just do not forget about anti-aliasing.
Well, I've shown all my secrets now.
Of course, on the last stage of multiplying input signal by gain signal you have to be at 2x oversampling since you will be getting aliasing without this (only multiplication by a constant value does not produce aliasing).
- KVRAF
- 3426 posts since 15 Nov, 2006 from Pacific NW
Changing at the zero crossing will still result in an instantaneous change in waveform slope, which will cause a lot of harmonic energy to be generated, which can alias.
In addition, the zero crossing is not really a "safe" place where changes can be hid. Imagine that you add a DC offset to a waveform, in a linear system with lots of heardroom, such that all signals are >0. The signal will sound the same (remember, linear system, lots of heardroom).
I should point out that the post above mine is much more interesting, and has the information that should survive this thread.
Sean Costello
In addition, the zero crossing is not really a "safe" place where changes can be hid. Imagine that you add a DC offset to a waveform, in a linear system with lots of heardroom, such that all signals are >0. The signal will sound the same (remember, linear system, lots of heardroom).
I should point out that the post above mine is much more interesting, and has the information that should survive this thread.
Sean Costello
-
- KVRian
- 646 posts since 18 Feb, 2006 from California
Aleksey- would you explain "anti-aliased by means of polynomial"? I presume this entails finding a polynomial approximation of the function that otherwise produces aliasing, but how is this approximated version made to not alias?
- KVRAF
- 4030 posts since 7 Sep, 2002
I've described the approach in another thread, but I'll re-decribe it here: first of all, you have to run everything at 2x oversampling initially. Since polynomial consists of x^N elements, you may calculate it sequentially. At first you need to calculate "x*x", after that you need to apply a low-pass filter to it (with Bessel-type group delay), Nyquist/2. Then you can use this low-passed x^2 result to calculate x^3 as "x^2 * x". And again, you need to apply a low-pass filter. The process goes on to the x'th power you need. On the last step you just need to combine results in a way polynomial is composed: you will have an anti-aliased polynomial result. (x^4 term can be created by multiplying x^2 by x^2 - this way you can get rid of additional group delay in comparison to "x^3 * x").asomers wrote:Aleksey- would you explain "anti-aliased by means of polynomial"? I presume this entails finding a polynomial approximation of the function that otherwise produces aliasing, but how is this approximated version made to not alias?
I'm still thinking which low-pass function to use, but this can be four 1st order low-pass filters in sequence (-24dB/oct slope). Or you can create a min-phase filter after creating a linear-phase "brickwall" filter windowed by Kaiser window with appropriate Beta parameter to yield a "good enough" response. 4-8 taps should be enough for this purpose.
Of course, it's a bit complex approach, but it allows to have some really heavy saturation without using any system-wide oversampling. On the other hand, if you are planning to use no more than x^3 terms you may just use system-wide 2x oversampling. 4x oversampling usually covers all polynomial needs, but is quite CPU-consuming to use in system-wide fashion.
- KVRAF
- 3426 posts since 15 Nov, 2006 from Pacific NW
Quick question: could you lowpass filter the original input signal with the Bessel lowpass filter (at 1/2 Nyquist) before the x*x operation, and skip the oversampling entirely? There would be some aliasing, granted, but there will be some aliasing in the 2x oversampled system when you multiply the lowpass filtered x*x times x.
- KVRAF
- 4030 posts since 7 Sep, 2002
No, you can't or you will just end up with half of the spectrum removed. "x*x" will not recreate filtered out spectrum: it will only create "harmonics".valhallasound wrote:Quick question: could you lowpass filter the original input signal with the Bessel lowpass filter (at 1/2 Nyquist) before the x*x operation, and skip the oversampling entirely?
- KVRAF
- 4030 posts since 7 Sep, 2002
No, this is incorrect. As I've noted, you have to filter the result after doing x*x. So, you will be multiplying bandlimited x*x by x and that will produce no aliasing. Of course, I'm talking about 'no aliasing' from theoretical side of things: you'll have to use a high-order filter to have 'no aliasing' result. In practical situation you'll have to find a compromise.valhallasound wrote:There would be some aliasing, granted, but there will be some aliasing in the 2x oversampled system when you multiply the lowpass filtered x*x times x.
- KVRAF
- 8476 posts since 12 Feb, 2006 from Helsinki, Finland
Now the filter necessary will depend on the polynomial, because not all polynomials will produce equally strong harmonics (even hard-clip falls 6dB/Oct) but for general purpose oversampling (say ring-mods and such) my experience suggests that 8-12 taps would be the minimum to consider for almost any sort of windowed sinc, unless you're willing to design for some high-frequency attenuation. Anyway, if you design for exactly half-band, and keep it linear-phase, you'll get half the taps exactly zero, which means you can run twice the number of taps for almost exactly the same cost. If the pre-ringing bothers you, it's always possible to get rid of it later with a suitable all-pass or whatever, thought I don't believe it's much of an issue with such short filters.Aleksey Vaneev wrote: I'm still thinking which low-pass function to use, but this can be four 1st order low-pass filters in sequence (-24dB/oct slope). Or you can create a min-phase filter after creating a linear-phase "brickwall" filter windowed by Kaiser window with appropriate Beta parameter to yield a "good enough" response. 4-8 taps should be enough for this purpose.
I also don't think cascaded one-poles are such a great idea. If you put the cutoff at original Nyquist, then you'd get 4*3dB=12dB attenuation there (and I'm pretending digital poles behave like analogs 'cos I'm too lazy to calculate actual values right now), yet only 12+24dB attenuation at twice the original Nyquist (which would be the new Nyquist for 2x upsampling). It's possible to insert zeroes to get more attenuation, but that'll also cause more high-frequency loss, and without feedback the poles stay real so compensation would have to be done separately... and you don't even get linear-phase.
There's the issue that if you filter "x*x" with a non-zero-phase filter, then you should also filter "x" in paraller if you want to keep the phases coherent for the subsequent multiplication. For linear-phase that's a question of some delay which means you don't end up needlessly degrading x.
Anyway, I've never bothered with such progressive polynomial evaluation, and for normal oversampling I've been using the popular polyphase all-pass half-band filters (mostly the 4th order version with coeffs shamelessly ripped from the music-dsp archives) or windowed-sincs if I happened to need linear-phase for whatever reason.
- KVRAF
- 4030 posts since 7 Sep, 2002
Sure, linear-phase is the way to go, but it requires a bit of delay compensation which also takes CPU time while a min-phase filter with an equal response is smaller by a factor of 2, and has a Bessel group delay. Also you do not have to put the cutoff point exactly on Nyquist/2 - you may put it a bit higher so that pass-band is unaffected. A bit of aliasing near Nyquist won't hurt at all if we are talking about quick CPU calculations.mystran wrote: Anyway, I've never bothered with such progressive polynomial evaluation, and for normal oversampling I've been using the popular polyphase all-pass half-band filters (mostly the 4th order version with coeffs shamelessly ripped from the music-dsp archives) or windowed-sincs if I happened to need linear-phase for whatever reason.

