-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Add Compressor effect to LMMS #5458
Conversation
🤖 Hey, I'm @LmmsBot from github.com/lmms/bot and I made downloads for this pull request, click me to make them magically appear! 🎩
Windows
Linux
🤖{"platform_name_to_artifacts": {"Windows": [{"artifact": {"title": {"title": "32-bit", "platform_name": "Windows"}, "link": {"link": "https://12913-15778896-gh.circle-artifacts.com/0/lmms-1.3.0-alpha.1.107%2Bg449528be8-mingw-win32.exe"}}, "build_link": "https://circleci.com/gh/LMMS/lmms/12913?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link"}, {"artifact": {"title": {"title": "64-bit", "platform_name": "Windows"}, "link": {"link": "https://12915-15778896-gh.circle-artifacts.com/0/lmms-1.3.0-alpha.1.107%2Bg449528be8-mingw-win64.exe"}}, "build_link": "https://circleci.com/gh/LMMS/lmms/12915?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link"}, {"artifact": {"title": {"title": "32-bit", "platform_name": "Windows"}, "link": {"link": "https://ci.appveyor.com/api/buildjobs/oxnom44236p0qg1k/artifacts/build/lmms-1.3.0-alpha-msvc2017-win32.exe"}}, "build_link": "https://ci.appveyor.com/project/Lukas-W/lmms/builds/38162586"}, {"artifact": {"title": {"title": "64-bit", "platform_name": "Windows"}, "link": {"link": "https://ci.appveyor.com/api/buildjobs/9no642di5thvhpx1/artifacts/build/lmms-1.3.0-alpha-msvc2017-win64.exe"}}, "build_link": "https://ci.appveyor.com/project/Lukas-W/lmms/builds/38162586"}], "Linux": [{"artifact": {"title": {"title": "(AppImage)", "platform_name": "Linux"}, "link": {"link": "https://12912-15778896-gh.circle-artifacts.com/0/lmms-1.3.0-alpha.1.107%2Bg449528b-linux-x86_64.AppImage"}}, "build_link": "https://circleci.com/gh/LMMS/lmms/12912?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link"}]}, "commit_sha": "b78ddbcee1cf2f278603f553ef83286961b4fbcd"} |
At this moment compressor work really nice. No crashes, no bugs at this moment. |
Why is the unit of RMS size 1/44100 second? Isn't it more natural to use something like milliseconds? |
m_maxLookaheadTimer[i] = std::distance(std::begin(m_lookaheadBuf[i]), | ||
std::max_element(std::begin(m_lookaheadBuf[i]), std::begin(m_lookaheadBuf[i]) + m_lookaheadLength)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note, it's possible to optimize finding the maximum value in a ring buffer using a double-ended queue. I can provide the detail if you want.
BTW, why do you want to use the maximum value in the lookahead buffer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like this doesn't consume CPU much, so I think the existing comment is enough which says about the possibility of further optimization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note, it's possible to optimize finding the maximum value in a ring buffer using a double-ended queue. I can provide the detail if you want.
Would that be faster than O(n)? 😮
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's amortized O(1) for fixed lookahead value, and additional O(log(n)) if it's automated.
Rather than using true RMS, I'm now instead using a buffer-free approximation which sounds better in a compression context. I also made it so RMS is in units of milliseconds rather than samples. On top of that, I fixed a bug with auto gain which made it act... incorrectly... as well as a bug making it so the input fader displayed the output volume.
|
Everything is ready now as far as I know. Probably needs some more testing though, to be sure. |
I tested this branch by compiling from source in Debian Buster using clang compiler. It seems all work fine. P.S. Nice interface, but I would like some check box to hide controls |& background. [I am new in testing ...] |
…ds rather than samples, fix autogain bugs, show correct volume on input volume fader
Oh gosh. I guess I was so focused on fixing input gain bugs for the Autogain and Lookahead and such that I didn't realize I broke it for literally everything else. Fixed in the latest commit, it should work properly now.
If you scroll on the background, it will change its scale so you can see more. Also, I made the Compressor fully resizable, so you can resize the Compressor window to open up more room for you to see the visualizer.
I agree that that would be a great feature to have, but I am waiting for LMMS to support multiple audio inputs to effects so that I can allow the user to directly send their audio into the compressor's sidechain signal, rather than using a knob and peak controller as messy workaround that we'll have to worry about backwards compatibility for later.
I put a lot of information in the knob tooltips that you can check out, but yes, maybe an in-plugin manual is called for here since many of the features may seem a bit hidden (e.g. scrolling to resize the visualizer)... |
Great! It work ok now! |
Ok, so, i don't wanna be the stop-merging guy, but here's what i think about it. The default size of the plugin is a bit big for HD screens, but the plugin is resizable, so this is not a big problem. Now let's talk about what i still think it's the real issue in this plugin. The autogain feature. For how it works at the moment it makes the sound incredibly clips, and this obviously forces you to do a manual decrease in volume after activating it. But this feels nosense. What's the point in having an autogain button that forces you to do a manual adjusting in gain after? You could just do a manual increase in gain from the start, in 1 move instead of 2. And this is actually how most compressor works out there, they just have a postgain knob, just to make an example i could mention the LADSPA version of Calf Compressor which is native in LMMS. It's way more rare to find compressor with an auto gain function, because it's probably difficult to code i guess. But according to my experience, the autogain button should do something like detecting the peak of the sound after the compression and bring it up to 0db. To make an example, i had my hands on the WA Production SphereComp as i bought the whole Sphere bundle on sale. This compressor has an autogain function, which isn't always able to bringup the sound to 0db, but for sure doesn't make the sound clip so much, if most of the times not at all. To mention another plugin, the MCompressor by Melda Production have an autogain function even if it's not called this way, "Maximize to 0db"; the name itself it's pretty explicit, even if haven't tried the vst myself. I feel like bringing this up because if it won't be fixed now, in my opinion it will come up multiple times as an issue in the future, too. With the little differences that it won't be fixable without breaking retrocompatibility. The plugin is great, LMMS needs it, and every other feature seems fine to me, but i'd rather have a working auto gain button. As i said i'm not a coder, neither a dsp expert, but this is what i feel from my user experience. |
I think your concerns are due to confusion around what the auto gain function is actually for. The auto gain function is not meant to choose a decent output volume for you; that depends on the context and is up to the musician. The auto gain function is used to maximize the compression shape to 0 dbFs, so a 0 dbFs input will result in a 0 dbFs target output. This allows the musician to change the compression amount with minimal loudness change, so they can better hear what the compression is doing to the sound. The clipping you're encountering is not an inherent issue. Again, this function is not intended to choose an output volume for you (and isn't a mastering tool either), so you should fix the clipping that results due to your settings by adjusting the output gain.
This isn't possible with realtime audio. And if we were to make use of the lookahead to try to make it possible, it would result in unwanted upward compression when the Auto Gain isn't supposed to change over time at all.
You mentioned the "Maximize to 0 db" function in Melda Audio's MCompressor. The Auto Gain button in this compressor is actually identical to that, they do exactly the same thing. In fact, Fabfilter's Pro-C 2 also does the same thing (except they also lower the volume depending on the attack time, which I decided to not bother with). The feature is working exactly as intended. |
Ok, thanks again for the clarifying, i was misunderstanding something. |
Fabfilter Pro-C 2 does that because increasing the attack time results in an overall increase in volume (and therefore perceived loudness as well), but when I analyzed the scale at which attack time became auto gain volume reduction... it was really added in a fairly lazy way from what I could see, basically just turning the attack knob into a linear volume knob without really taking the scale of the attack time into account (...from what I can remember from over a year ago when I tested this). I decided to not bother with that aspect, it seemed rather unnecessary anyway. |
Oh got it, well the volume increase would be only at the start of the sound tho, so |
No, it's for the attack time, as in the value that the attack knob is set to. |
Nono, i was just saying that increase the value of the attack knob increase the volume only of the start of the sound, as the compressor follows it to compress the sound. Just stating that the increase wouldn't be on the whole sound, nothing more. |
The volume change would be on the entire sound though. |
Just wanna state that any misunderstanding has been cleared here and on discord. |
Everything's finished here for now. Ready for merge as long as there aren't other issues with it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a comprehensive review by any means, but I saw you intended to merge soon, so I wrote up some notes I made when I started looking at this a while ago.
Merged. Here's a demo video I made: |
* Add Compressor effect
* Add Compressor effect
* Add Compressor effect
(Simple video demo: https://www.youtube.com/watch?v=j-i0gY_KmVk)
This took a few months to make, the visualizer in the back taking the bulk of the development time. I wanted to make this the best audio compressor in the world... and while it's entirely subjective which compressor is the best, I'm very satisfied with how this turned out.
This is a purely digital compressor, completely void of any coloring of any kind so you can focus on exactly what a compressor is meant for, being compression. Even with 2572985782 db of input gain, unless your parameter settings are asking for it, you'll hear absolutely no distortion whatsoever.
It comes with some fairly unique features, like the toggleable Feedback mode, the Hold control (which is usually only for Gates), the blending between stereo linking modes, the mid/side compression, and the 100% adjustable automatic compression and release, which is significantly more complex than automatic attack/release in most compressors.
The automatic attack/release in this compressor analyzes the crest factor (peak divided by RMS) and adjusts those parameters automatically depending on that value. The knobs control how much this has an impact on those parameters, giving you ultimate flexibility which I've never seen in any other compressor.
It also features fully-automatable lookahead, which applies a constant 20 ms of latency when enabled regardless of the lookahead time. Along with L/R or M/S balancing for either the sidechain input or the audio itself, a sidechain tilt filter which can transform into a highpass, lowpass, or a hybrid between the two, adjustable RMS sizes that can go all the way up to 21.5 ms, a Mix knob which takes lookahead delay into account, and an audition button that can be used to listen to the delta signal of the compressor to know exactly how the compressor is changing your sound, this is by far LMMS's most complex audio effect and I'm very proud to be the author of it.
And well, nobody likes a compressor without a fancy visualizer to assist you. Or maybe they do. But those people are weird. The visualizer has a flowing, moving graph showing the input volume, output volume, and gain reduction. It also contains a visualizer of the compressor's dynamics curve, so you can see exactly how your dynamics are being impacted at any time depending on your compressor settings.
The compressor window is fully resizeable. You can just drag the corner of the window, and the contents will scale to fit the new size. Also, the visualizer supports zooming in all the way to 3 db or all the way out to 96 db, so you can see what the compressor is doing to your audio with whatever amount of detail best suits your needs. All in all, a very cool plugin. :)
This'll definitely need a code/style review. I abandoned this project three times or so, so the code may be kind of a mess. I tried to clean it up the best I could.
(Special thank you to H4CKTON3 (aka RoxasKH on Github) for helping me immensely with the artwork!)