Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LOMM (upward/downward multiband compressor) #6925

Merged
merged 14 commits into from
Nov 10, 2023

Conversation

LostRobotMusic
Copy link
Contributor

@LostRobotMusic LostRobotMusic commented Oct 8, 2023

LOMM.

image

UI background designed by our pal Grimnir (@grimnomancy) on Discord.

Okay cool so what is it

LOMM was originally intended to just be a super quickly-made OTT replacement for LMMS, but as it goes with literally everything I make, it wound up spiraling into a significantly larger project which puts OTT to shame. That's super cool, given OTT might actually be the most-used VST on the planet.

Unlike OTT, LOMM is built to provide absurdly clean and clear compression, with no crossover phase issues, no unwanted distortion or artifacts, and with algorithms even designed with the master bus in mind. However, if the user so pleases, they can completely ruin this and crank this plugin up to comically destructive levels OTT isn't even capable of approaching. The parameters provided are versatile enough to appeal to any use case a musician could possibly want, whether it be applying gorgeously subtle touch-ups to a song that sounds timbrally lacking, to transforming even the weakest of sounds into terrifyingly powerful sonic brick walls.

LOMM is an upward/downward multiband compressor.
"Upward/downward" means it compresses the audio both upward and downward. Most compressors are only downward, meaning if the measured volume of the audio goes above a certain threshold, the volume is proportionally decreased to decrease its dynamic range. However, LOMM is also capable of upward compression, meaning if the volume goes below a certain threshold, its volume will be proportionally increased. This can bring out many of the quieter and subtler textures and timbres within a sound.
"Multiband" means the audio is split into separate frequency bands, before one copy of the effect is applied to each band individually. This is an incredibly valuable attribute for a compressor, since the behavior of one frequency range won't interfere with the compression needed for another frequency range.

Stuff

List of stuff:

  • DEPTH controls the compression amount of all bands simultaneously. This works similarly to a dry/wet control (but impacts only the gain reduction, not other parameters like band gain settings), and is designed to be automated to cleanly and easily adjust the current amount of compression throughout your song.
    • The Depth Link next to it controls whether the Output Volume knob's value is scaled along with the Depth value, allowing for more convenient adjustment and automation.
  • TIME controls the attack and release of all bands simultaneously. Larger values cause the gain reduction to move much more slowly over time, resulting in a very clean and gentle sound. Smaller values cause the gain reduction to move much faster, reacting to transients quickly and increasing the overall intensity of the compression.
  • AUTO TIME uses some unique algorithms to adjust the compression speed in realtime depending on the incoming audio. When this knob is turned up, LOMM will analyze the level of incoming transients and decrease attack/release times right when transients are at their peak. This allows the compressors to react very well to transients as if your attack/release times are short, but still draw all the benefits of having attack/release times that are a bit longer.
  • BALANCE changes the volume of each channel before it reaches the compressors, allowing you to have more control over how the compression is applied to each channel. This feature becomes massively useful when working in Mid/Side mode, as it will allow the user to directly adjust the width of the sound prior to compression.
  • RANGE controls the maximum possible gain increase that LOMM will allow for each band. This plugin's upward compression excels at bringing out subtle details in sounds, but sometimes it can start bringing things out that were quiet enough to have been better off left alone. This knob can put a hard cap on how crazy LOMM is allowed to go with this.
  • UPWARD and DOWNWARD are similar to Depth, but they adjust the upward and downward compressors individually.
  • IN and OUT adjust the input and output volume for the entire plugin. Note that the Out knob will have its volume scaled relative to the Depth knob value unless Depth Link is disabled.
  • LOOKAHEAD adds a constant 20 milliseconds of latency to the signal when enabled, and uses the set lookahead time to check for sudden peaks in the audio that it otherwise wouldn't have been able to predict. Unlike my LMMS Compressor plugin (oops), this plugin handles lookahead in a very clean and healthy way, by simply taking the maximum between the delayed sidechain signal and non-delayed sidechain signal to be used as the actual sidechain signal. This has an extremely clean sound and prevents any sudden unpredictable volume spikes from creating ugly clicks in the audio. The latency introduced will always be the same regardless of the lookahead time value, which means it is perfectly safe to automate.
  • STEREO LINK ensures the gain reduction applied to both channels will always be the same, allowing you to do whatever you want within LOMM without messing with the stereo information the incoming audio already had.
  • INIT is used to reset LOMM to a clean slate. LOMM's default settings are set up to somewhat mimic the settings OTT has under the hood, but sometimes you'd rather start entirely from scratch, which this button allows. Don't worry, it has a dialogue box to ask for permission first.
  • MID/SIDE mode converts the audio from left/right to mid/side before reaching the compressors. This means the mono and stereo information are compressed separately, which is immensely useful for powerfully enhancing the width of your audio while being capable of keeping it under precise control if needed.
  • FEEDBACK mode is overpowered. I'm pretty sure this is the world's first-ever digital multiband upwards/downwards compressor with toggleable feedback. Most digital compressors are Feedforward by default, where they use their estimate of the input volume to guess at where the output volume should optimally be. Feedback takes out the guesswork and ensures that the compression applied is accurate regardless of the transient information within your audio, resulting in significantly cleaner and more natural compression. Even with the most extreme settings, your audio won't have that ugly "overcompressed" sound typically associated with high levels of compression. Unfortunately, Feedback and Lookahead are incompatible with each other, so this button will vanish when Lookahead is enabled.
  • MIX is another parameter designed for automation, which works properly with Lookahead despite the latency. Unlike the Depth knob, this knob will effectively fade out the changes made to the various band volumes and such, so this is the knob to use when you want to fade all of the plugin's processing rather than just the compression. Note that this changes the mix of all of the bands, not the entire plugin. This prevents phase cancellation issues with the crossover filters.
  • KNEE sets the knee of all three compressors. A small knee has a sharp transition between compressing and not-compressing, while a larger knee causes the compression to gradually fade in around the edges.
  • RMS is another interpolation stage applied before the attack/release. You can turn it all the way down to put LOMM into Peak mode where it'll send the exact input audio into the compressors. Otherwise, it'll smooth out the transients beforehand for a much cleaner sound with minimal distortion.
  • CROSSOVER FREQUENCIES control the cutoff frequencies of the crossover filters, setting the point at which the bands overlap.
  • CROSSOVER SPLIT toggles allow you to bring LOMM down to 2-band or even single-band compression when disabled. It's common to only need to keep the low frequencies separated from the rest of the spectrum so you can compress everything else unhindred, or vice-versa.

Band Stuff

The bands each have their own stuff. IN and OUT control the input and output volume of each band, essentially equivalent to a Crossover EQ on each side. Threshold controls the point at which the compression begins to engage for both higher and lower volumes. Ratio controls the amount of gain change applied relative to how far past the threshold the audio is located. ATK and REL control the attack and release of each band individually. The large "X Band" labels can also be clicked to enable or disable a band entirely (muting its output, unlike the crossover split toggles which merge the audio into another band instead).

Yo wait it's animated

image
Yes, despite Qt, it's animated. And, you can even interact with it.
The red area represents the threshold for the upward compression, and the yellow area represents the threshold for the downward compression. You can drag these left and right to set the threshold, and middle click them to reset them to their default value. You can also drag the empty area between the two areas to adjust both simultaneously.
You'll see two lines move to match with the audio being sent through the plugin. The smaller grey line represents the input volume (after being sent through RMS and attack/release and so on), and the larger white line represents the output volume (after the gain change is applied).

Insert eloquent outro here

plz merge quickly or i will die
amogus

oh yeah lmms development is also literally my only source of income and i can't afford food so
https://www.patreon.com/lostrobot
if you're able
thanks
very grateful

EDIT: Here's a quick and simple demo video to give an idea of a few of its abilities:
https://www.youtube.com/watch?v=AIMQfIdDL6k
Its general usage is quite similar to Ableton's Multiband Dynamics.

@LostRobotMusic LostRobotMusic changed the title LOMM upward/downward multiband compressor LOMM (upward/downward multiband compressor) Oct 8, 2023
@superpaik
Copy link
Contributor

superpaik commented Oct 11, 2023

That it's very good stuff! Thanks for the effort.
I've tested it with EQ Curve Analyzer and doesn't seem to alter the audio, other than expected.

Some thoughts after testing it:

  • What does LOMM stands for?
  • When set to Depth 0, I'd expect the plugin to do nothing. If you crank up the Output knob, nothing happens (correct), but if you do the same with any band's output knob, the output is affected. Is that intended to work like that?
  • I would expect INIT to reset values to initialization state (when you load the plugin) I know you said that it somehow set the plugin controls to "zero", but maybe the message shown should say something about it, because now it says "Are you sure you want to reset all parameters?" To me, resets means "set to initial value" as when you double-click any control that reset it to initial value.
  • At the beginning I though Knee and RMS where related to the crossover filters. But my fault, after watching the video I realized that they are related as how bands are mixed, what makes me think that a very thoroughly manual is needed to use the plugin correctly because it can be daunting for users. I don't know if it would be possible to make two UIs, one simple (basic controls) and one advanced (with the full potential of the plugin).

@LostRobotMusic
Copy link
Contributor Author

LostRobotMusic commented Oct 11, 2023

That it's very good stuff! Thanks for the effort. I've tested it with EQ Curve Analyzer and doesn't seem to alter the audio, other than expected.

Some thoughts after testing it:

What does LOMM stands for?

It doesn't really have to stand for anything, it's mainly a reference to OTT and an ongoing meme in the LMMS Discord server about LoMMuS. Though Punch who thought of the name originally recommended "LMMS's Own Multiband Maximizer", we can go with that.

When set to Depth 0, I'd expect the plugin to do nothing. If you crank up the Output knob, nothing happens (correct), but if you do the same with any band's output knob, the output is affected. Is that intended to work like that?

Yes. The purpose of Depth is to control the compression amount alone. Mix is the knob to use if you want to control the amount of all of the plugin's processing. A Depth of zero causes the compression to do nothing, but the rest of the plugin's processing still applies. The output volume link button to the right of the Depth button controls whether it impacts the output volume, and is there because I found Depth scaling the output volume generally makes the knob far more convenient to automate (due to the Depth value having a large impact on the resulting volume).

I would expect INIT to reset values to initialization state (when you load the plugin) I know you said that it somehow set the plugin controls to "zero", but maybe the message shown should say something about it, because now it says "Are you sure you want to reset all parameters?" To me, resets means "set to initial value" as when you double-click any control that reset it to initial value.

You aren't the first person to say this, it's good feedback. I'll change the message.

At the beginning I though Knee and RMS where related to the crossover filters. But my fault, after watching the video I realized that they are related as how bands are mixed, what makes me think that a very thoroughly manual is needed to use the plugin correctly because it can be daunting for users. I don't know if it would be possible to make two UIs, one simple (basic controls) and one advanced (with the full potential of the plugin).

Knee and RMS are standard controls you'll see in most compressor plugins. These knobs have the same function here as they do in all other compressors. They aren't relevant to how the bands are mixed. Knee controls the knee size of the compression curve, while RMS controls the RMS size of the sidechain reading.

But I did just realize I completely forgot to add tooltips to this plugin (oops), so I'll be sure to do that. My bad.

@LostRobotMusic
Copy link
Contributor Author

The plugin now has the tooltips I somehow forgot, everything should be much easier to navigate.

@LostRobotMusic LostRobotMusic added enhancement needs style review A style review is currently required for this PR needs code review A functional code review is currently required for this PR needs testing This pull request needs more testing labels Oct 14, 2023
Copy link
Contributor

@sakertooth sakertooth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did not test the actual plugin, but in terms of the code:

  • You might want to format the newly added files in their entirety. There seem to be formatting issues in a few places.
  • Might want to take a look at making CodeFactor happy. CodeFactor is complaining about the format and certain methods being too complex. Try and take a look for yourself and see if you can split some of them into functions. I think a good starting point would be with LOMMEffect::processAudioBuffer.
  • I would advise using std::array instead of C-style arrays. std::array knows about its own size in contrast to C-style arrays, which allows us to use for loops with them in an easy way. With C-style arrays, you have to remember what the size of it was or use sizeof, which leaves room for error.

Comment on lines +90 to +92
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < 3; ++j)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend using more descriptive name for loop variables, e.g., ch and band.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally I'd agree, but the large majority of variable usage throughout this function uses i and j as array indices, so changing them to more descriptive labels results in a surprisingly large deficit in the readability of the entire code. I added comments to the loops to make sure the variables' purposes are obvious, let me know if you still think this change should be made.

@RoxasKH
Copy link
Contributor

RoxasKH commented Oct 15, 2023

I did only a really brief testing but it seems to be great.

GUI looks cool too, i only have a small concern

LMMS tends to already have lots of green shades and the numbers in LOMM have yet another one, they clash a little and stand out a lot imo.
I get it might be intentional to make it look more lcdboxy, but i'd rather not add another one.

Hoping it's just a minor change like a color code change, would it be possible to just use the same palette as the rest of the LMMS LCDspinboxes for consistency? I've attached a couple images below to make it clearer what i mean, on the right there's the current green shade, on the left a poor edit reusing the existing one

LOMMCorrectedGreen

Copy link
Contributor

@sakertooth sakertooth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code is fine with me. Haven't done any testing, but many people have and no major complaints seemed to pop up.

@kamkamkamkamkamkamkamkam

please merge thx

Copy link
Member

@zonkmachine zonkmachine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests fine. Cool machine!

@LostRobotMusic LostRobotMusic merged commit 89c98a7 into LMMS:master Nov 10, 2023
@teknopaul
Copy link

Game changer! 👊

@LostRobotMusic LostRobotMusic removed needs style review A style review is currently required for this PR needs code review A functional code review is currently required for this PR needs testing This pull request needs more testing labels Nov 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants