Aliasing in zero-crossing compressor?

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

Aleksey Vaneev wrote:One tip for you about min-phase transform: it calculates cepstrum and so it loses half of the spectral information. Hope this gives you an idea why kernel length halves after this transform.
Um, wft?

I have coded the Mathematica equivalent to Julius Orion Smith III code at CCRMA and there was no halving of anything for general linear phase fir. Here is the link http://ccrma-www.stanford.edu/~jos/fp/C ... ex2html177 , the mathematica notebook version in available from footnote 12.4.

Here is an example linear phase fir and it's minimum phase equivalent where you can definitely not drop half the coefficients:

Image

Also here is some simple code that won't alias and you are multiplying by something that isn't constant:
scale += 0.0001f;
output[t] = scale * input[t];

I'll leave it there for now as mystran I think has covered most other points, but, when I have more time, I would like to make some more comments on some of the points touched on here.

Andrew Simper
The Glue, The Drop, The Scream - www.cytomic.com

Post

"a compressor just modifies volume, how could it introduce aliasing?"

the definition of "non-linearity" is that the amplitude changes, for example 1.0 becomes 0.7 and 1.5 becomes 0.9.

in order for your compressor not to introduce aliasing or harmonics, the fraction it scales the signal by must remain constant, like 0.5, for example.

you can avoid aliasing by applying a few filters and using 2x oversample. if you keep the modulation frequency below nyquist, the maximum sum/difference is equal to 2nyquist. it's possible to use a soft abs() transform that maintains all content at below 2x nyquist - that would then be filtered to remove any element above nyquist. it could then be applied and the modulated/compressed signal filtered again to remove components above nyquist before decimation.

(the smooth abs() can be achieved by slew-limiting and shaping via a cosine function)

Post

andy_cytomic wrote:
Aleksey Vaneev wrote:One tip for you about min-phase transform: it calculates cepstrum and so it loses half of the spectral information. Hope this gives you an idea why kernel length halves after this transform.
Um, wft?

I have coded the Mathematica equivalent to Julius Orion Smith III code at CCRMA and there was no halving of anything for general linear phase fir.
You have a wrong implementation, or partial knowledge. Min-phase transform requires kernel that's twice long (zero padded) than the original kernel. You are getting aliasing it seems.

Please do not argue - I have min-phase transforms working for ages, and it's 2 times shorter than the lin-phase. Check out CurveEQ, for example (L-P vs M-P modes). It has some very minor skew in the lower freq range when you switch from L-P to M-P. If you leave lower frequencies straight, higher frequencies demonstrate 2x length shrinking quite well.
Image

Post

Maybe I'm wrong after all. (sorry about that)

My routine gives this results for your input sequence - quite different to yours:
0.2890053638
0.2971736544
0.2763932023
0.1028263456
0.0346014339

I've calculated it with 64 sample FFT block - 12.8 times more than original kernel size.

16 sample FFT block gives these min-phase results:
0.2889961984
0.2971573622
0.2764270665
0.1028316512
0.0344997284

and a lot of values
0.0001669003
0.0000860281
-0.0007381943
-0.0009029607
0.0000346621
0.0006785256
0.0005412182
0.0002155070
0.0000052040
-0.0000000934
0.0000011961
(instead of zeros as in the case of 64-sample FFT).

I was probably stuck to long filters where higher order kernel elements do not make much of a difference.

For example, input sequence: 0.025, 0.05, 0.1, 0.2, 0.4, 0.2, 0.1, 0.05, 0.025

gives this min-phase transform:

0.2993468527
0.2998699642
0.2250330407
0.1500545899
0.1063181640
0.0438154576
0.0172140636
0.0062599883
0.0020878790

Latter 2 elements can be discarded. If you take a really long kernel, you may discard even a whole half.

But as it stands, it's not a rule, and depends on the "optimality" of the filter kernel (filter kernels can be minimized in length given the maximal allowed frequency/phase response deviation). Again, I'm sorry about trying to spread a half-valid knowledge.
Image

Post

Aleksey Vaneev wrote:...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).
The last section of this statement that is in brackets is also, afaik, incorrect. Check the code snippet I posted previously.

Appology accepted on your previous post. I don't think I have updated the code available from vellocet for a while, in my current code, and in the example above, I do right zero pad the fir prior to running the minimum phase transform.

There is a big difference between a proof that something is so, and seeing a pattern in certain situations. I have not researched the subject of minimum phase transforms very thoroughly, I consider myself a hack in the area and as such will refrain from making sweeping statements of conjecture.

Andrew Simper
The Glue, The Drop, The Scream - www.cytomic.com

Post

A couple more little quick notes to add to what has been said here before I actually start taking some time to talk about compression:

1) For memory you don't need an & mask, if you can use a temporary buffer slightly longer slightly longer than the longest block and use memcpy to preserve the state. For any reasonably intensive compressor model this will not add much to the total cpu, and will most probably be more efficient than using and & per sample. You can also have non power of 2 delay / look-ahead / fir memory this way.
2) Minimum phase filters cause delay, but the delay varies with frequency
3) If you want a minimum phase filter, rather than transforming an existing fir to minimum phase and lopping off the tail coefficients you can get a more "optimal" solution by using filter design optimisation techniques with constraints being that of a minimum phase filter (an all zero filter with zero positions magnitude >= 1), and fixing the number of taps to whatever you can afford cpu wise.
4) Half wave rectifiers don't generate harmonics at -6 dB / Oct. Each nth derivative of the signal having a discontinuity will generate harmonics (n+1) * (-6 dB / Oct), so the rolloff of a change in first derivative caused by a half wave rectification, or absolute value for that matter, will be -12 dB / Oct, and the size of the initial harmonic is determined by the difference in derivative at that point with the constant function 0, or 2 times the magnitude of the first derivative in the case of the abs function.

I want to look more into the area of filter optimisation, I have the gut feeling that there is a good compromise with having a low amount of delay, and a near monotonic step response but still with decent attenuation. Working at 44100 really sux as you have zero room to move without either introducing ringing in the time domain, or aliasing in the frequency domain or some amount of both.

Andrew Simper
The Glue, The Drop, The Scream - www.cytomic.com

Post Reply

Return to “DSP and Plugin Development”