Lets talk about stereo link modes (compressors)

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

JCJR are you bandlimiting the input into your phase rotation stage?

Post

Hi camsr

Nope, nothing except an optional side-chain highpass filter in front of the allpass networks. It is programmed in JS and I didn't want to clutter the GUI with another 'full size control" just as a switch to enable/disable side-chain highpass. So the way to turn it "off" is to tune the highpass to the minimum 10 Hz setup on the highpass frequency control.

But without the side-chain highpass I think it would work just as good.

When I first tried the "band limited Hilbert" idea wasn't thinking about it correctly and I expected the envelope follower to have a non-flat frequency response (not the same output level for high frequencies versus low frequencies). I expected either the follower would need some kind of corrective EQ, or maybe the "band limited Hilbert" would turn out impractical for the task.

But the nature of squaring the signal for RMS just worked out to not need anything fancy, for which I was pleasantly surprised. Trying to use the band-limited hilbert trick on peak envelopes might be nasty. Or maybe not. Haven't experimented with it.

My "gaussian" main RMS smoother does real good suppressing ripple above 100 Hz with 10 ms time constant, and does real good down to about 20 Hz at >= 25 ms time constant. I wanted to "pretty good" suppress ripple down to 20 Hz even when setting the main RMS smoother to 10 ms time constant. Hence the band limited Hilbert experiment.

In the low frequency region where the hilbert has quadrature outputs, for instance with a +/- 1 amplitude sine wave, adding the two squared outputs makes a low-ripple output of 1.0. At higher frequencies as the outputs drift out of quadrature, the sum of the two squared outputs gets more and more ripple. At some point maybe the rectified sine wave has [1.1, 0.9] ripple peaks. At some higher frequency it would reach [1.2, 0.8] ripple peaks. Until near nyquist it would be nearing [+2, 0] ripple peaks.

But at every frequency, the smoothed average is 1.0. After final smoothing, a nice flat envelope frequency response. The primary "gaussian" RMS smoother has no trouble filtering out ripple except for low bass at short time constants. So the band limited hilbert just lets me get away with shorter time constants in the primary RMS smoother.

Post

Did you route the output of the first network into the second network, or are they from the input?
I was just experimenting with it, I used bandlimiting on the input and output of the quadrature stage. Works great!
Although the hilbert network has some ringing and it's not insignificant, it should be managable.

Post

camsr wrote:Did you route the output of the first network into the second network, or are they from the input?
I was just experimenting with it, I used bandlimiting on the input and output of the quadrature stage. Works great!
Although the hilbert network has some ringing and it's not insignificant, it should be managable.
Great!

What bandlimits, and how many allpass filters?

My routing is like this--

Code: Select all

         |--> 1stOrderAP 8.335807 Hz --> 1stOrderAP 75.031263 Hz --> Hilb Out 1
Input -->|
         |--> 1stOrderAP 30.195915 Hz --> 1stOrderAP 271.763235 Hz --> Hilb Out 2
I also fooled with a limited-band hilbert using chains of 3 first order allpass, which I didn't finish tweaking for "best performance" but could do pretty good quadrature over about 5 octaves rather than about 2.5 octaves, but the latency was bigger and I only need about 2.5 octaves of smoothing help in the bass.

Testing the complete envelope smoother with the landlimited Hilbert front-end-- As best I recall, the actual attack-release in the low bass tended to be about 16 ms even if the following gaussian smoother was set for 10 ms, so it isn't exactly "free lunch". Maybe it was some other number, but I think about 16 ms.

But even if the low-ripple bass smoothing might be a little longer time constant, the mid-bass up thru the highs can get down to about 10 ms Attack/Release. Seemed "close enough for rock'n'roll".

Had posted about the same a few messages back with the js code. Will upload the js rms compressor in a day or two as soon as I can finish the documentation. Am a real slow worker. :)

1st Allpass cascade frequencies = 8.336807 Hz, 75.031263 Hz
2nd Allpass cascade frequencies = 30.195915 Hz, 271.763235 Hz

Code: Select all

  AP0_L = APFilt_0_L.FirstOrdTrapezoidFilter_DoSamp(LeftSample);
  AP0_L = APFilt_1_L.FirstOrdTrapezoidFilter_DoSamp(AP0_L);
  AP1_L = APFilt_2_L.FirstOrdTrapezoidFilter_DoSamp(LeftSample);
  AP1_L = APFilt_3_L.FirstOrdTrapezoidFilter_DoSamp(AP1_L);
  //Square and add the two left channel allpass chains
  MonoEnvVal = AP0_L * AP0_L + AP1_L * AP1_L;
  
  AP0_R = APFilt_0_R.FirstOrdTrapezoidFilter_DoSamp(RightSample);
  AP0_R = APFilt_1_R.FirstOrdTrapezoidFilter_DoSamp(AP0_R);
  AP1_R = APFilt_2_R.FirstOrdTrapezoidFilter_DoSamp(RightSample);
  AP1_R = APFilt_3_R.FirstOrdTrapezoidFilter_DoSamp(AP1_R);
  //Square and add the two right channel allpass chains, resulting in a mono cumulative envelope
  MonoEnvVal += (AP0_R * AP0_R + AP1_R * AP1_R);
  MonoEnvVal *= 0.25; //Scale down the sum of four signals

Post

Not sure yet about what frequency is best... I set it to 271 on a one-pole lowpass. This obviously band-split the result, so I used two lowpass after the allpasses to run the correct network through to the output.

Post

I added a last-minute tweak to my hobby RMS Compressor to select between two stereo link modes--

1) RMS Sum of Left + Right
2) Maximum RMS of Left or Right

Testing with some old stereo song mixes, option 2 does seem to do a slightly better job, but on my songs it is not a "night and day" difference. Perhaps "more radically stereo" music would have more obvious difference. Anyway, it was enough of an improvement to set option 2 as the default.

Post Reply

Return to “DSP and Plugin Development”