trummerschlunk / master_me

automatic mastering plugin for live streaming, podcasts and internet radio.
GNU General Public License v3.0
548 stars 22 forks source link

Tracking plugin version progress #24

Closed falkTX closed 2 years ago

falkTX commented 2 years ago

I am making a DPF-based plugin version for soundsgood, with faustpp for the templating stuff, which nicely gets us a C++ class with some filled in values based on a template. Check the dpf branch for current progress, there are builds via github actions too.

Also see #23 for the GUI sketches, where discussion on the layout and other high level concepts should happen. This ticket is only about the implementation, and mostly so others can easily follow current progress. We can assume I will do all these things, anything that requires intervention I will open as separate tickets.

Current TODO for plugin/dsp side:

Current TODO for UI appearance:

Current TODO for UI widgets:

Current TODO for UI layout:

Current TODO for UI features:

Can be left for later or v1.1:

Unclear at the moment:

falkTX commented 2 years ago

Status as of 2022-08-17

image

image

Still with lots of things in progress, not quite in a usable state yet.

magnetophon commented 2 years ago

Looks great!

falkTX commented 2 years ago

Status as of 2022-08-18

image

Just put in place auto-layout code, so things get nicely packed together without having to define position for every single parameter. Parameter groups can also automatically be sized, useful if we need to change these strings dynamically at some point (translations?) The small groups get cut-off because they do not have defined content yet.

I didnt bother to do all the parameters because they are not final anyway, so would be a bit wasteful. Will move to other custom widgets next, we need one for "gain reduction" (grouped with the sliders) and try to find a way to do the lufs meters + target in a way that looks nice and doesnt take too much space..

x42 commented 2 years ago

Wow. things are really coming together nicely!

Perhaps a bit too early. common loudness targets are -12, -14, -18 and -23 (23 is in the EBU-R spec). So meter-deflection should expand those areas. Perhaps even make the slider snap to those points if that is possible (scale points)?

trummerschlunk commented 2 years ago

referring to

do we want slider double-click for text input of parameter values? (tricky to do, but possible)

yes, please :)

falkTX commented 2 years ago

status as of 2022-08-19

image

it is actually not much, I had to deal with a few other blocking issues somewhere else. but I did map the rest of the parameters (after updating to latest dsp) and also added in place a few things that will purposefully fail the build if something is unexpected (would lead to UI crash if ignored).

falkTX commented 2 years ago

status as of 2022-08-20

image

I was assuming the parameters were final and went to map them all, but there are more to come still now πŸ˜…

anyway, reduction meters are in place. needed to sort out some common code to make it easier to adapt to changes, so the input and output groups sorta have a layout behind the scenes now too. I am in the process of reworking the level meters, will place a label with the current meter value on top again soon. have some ideas on things to try, will try them out next time.

there are some oddities still with the layout positioning, with some contents being cutoff or not given the right amount of space. will fix that later.

did also some other cleanup and reorganization, not visible in the screenshot. just a few things to help have an overview of the faust-to-plugin conversion (to be exact, placing most of static data in the header file and use that in the C++ code instead of templating around the C++ code)

btw, I did 2 things on the faust dsp file, wont bring as PR because it is being modified at the moment too. but these changes are:

diff --git a/soundsgood.dsp b/soundsgood.dsp
index 90e1723..729e209 100644
--- a/soundsgood.dsp
+++ b/soundsgood.dsp
@@ -187,7 +187,7 @@ with {
     leveler_gate_thresh = vslider("v:soundsgood/t:expert/h:[3]leveler/[5]leveler gate threshold[unit:dB][symbol:leveler_gate_threshold]", init_leveler_gatethreshold,-90,0,1);
     limit_pos = vslider("v:soundsgood/t:expert/h:[3]leveler/[7]leveler max +[symbol:leveler_max_plus]", init_leveler_maxboost, 0, 60, 1);
     limit_neg = vslider("v:soundsgood/t:expert/h:[3]leveler/[8]leveler max -[symbol:leveler_max_minus]", init_leveler_maxcut, 0, 60, 1) : ma.neg;
-    fffb = vslider ("v:soundsgood/t:expert/h:[3]leveler/[9][symbol:leveler_fffb]kneecomp ff-fb",0,0,1,0.1);
+    fffb = vslider ("v:soundsgood/t:expert/h:[3]leveler/[9][symbol:leveler_fffb]leveler ff-fb",0,0,1,0.1);
     lp1p(cf) = si.smooth(ba.tau2pole(1/(2*ma.PI*cf)));

     feedforward_feedback = B,(B<:B,B) : par(i,2,_*fffb), par(i,2,_* (1-fffb)),B : (_,_,_,_:>_,_),_,_;
@@ -370,7 +370,7 @@ limiter_rms = co.RMS_FBFFcompressor_N_chan(strength,thresh,att,rel,knee,0,1,fffb
     rel = vslider("v:soundsgood/t:expert/h:[7]limiter/[5][symbol:limiter_release]limiter release",40,1,400,1)*0.001;
     knee = vslider("v:soundsgood/t:expert/h:[7]limiter/[6][symbol:limiter_knee][unit:dB]limiter knee",8,0,12,1);

-    fffb = vslider ("v:soundsgood/t:expert/h:[7]limiter/[6][symbol:limiter_fffb]limiter fffb",0.5,0,1,0.1);
+    fffb = vslider ("v:soundsgood/t:expert/h:[7]limiter/[6][symbol:limiter_fffb]limiter ff-fb",0.5,0,1,0.1);
     // post_gain
     post_gain = par(i,Nch,_ * limiter_postgain) with {
magnetophon commented 2 years ago

Looks great!

Can we put the parameters of the compressor, multiband and limiter in the same order?

Maybe put the parameters they have in common at the top, so they line up horizontally?

Can the brickwall get a bypass and/or a higher maximum ceiling, for people that want to use an external limiter?

Will the compressor get a gain reduction meter?

trummerschlunk commented 2 years ago

yes, dynamics parameters should be in the same order - thank you!

Also mscomp's 'thresh' needs to be labeled 'tar-thresh' as it depends on 'target'

@falkTX can I do the reordering and renaming of one label in the dsp file without destoying the GUI? No symbol names will change.

@magnetophon I intentionally made the brickwall non-bypassable, so no overloads can occur on the output (-> safety for 'simple' users). If one wants to use a 3rd party limiter afterwards, they most likely are in a dynamic range where the limiter does not kick in.

trummerschlunk commented 2 years ago

and mscomp's 'output gain' needs to be relabeled 'makeup' for consistency.

falkTX commented 2 years ago

status as of 2022-08-21

image

image

All the parameters and meters are mapped, some better than others. Metering still needs attention from my side. I started some high-dpi related things, but still WIP. It is starting to be usable, so we should merge it to the master branch. I will try to sort out the details to create a PR now.

sletz commented 2 years ago

Great ! I understand that the GUI layout in mainly manually coded, using DPF framework right? Could Faust grouping information (hgroup/vgroup/tgroup) be used and displayed in a generic way? Or do you @falkTX consider this as not flexible enough?

falkTX commented 2 years ago

in theory grouping information could lead things half way, but IMO that is not enough for a proper plugin GUI. we need ways to declare metadata which is completely on ui side (such as theming, sizes, alignment and separators)

for the gui here I am making it follow very strict theme parameters, see https://github.com/DISTRHO/DPF-Widgets/blob/main/opengl/Quantum.hpp#L28, which can be easily tweaked. soon enough I will add this info to the inspector window so we can tweak theme values at runtime too. so it could be made possible to have a gui auto-generated using these widgets, though it never looks as good as something handcrafted.

for soundsgood there is not a whole lot of time to be specifying faust properties and implementation, so a custom UI it is then.

falkTX commented 2 years ago

Status as of 2022-08-22

image

image

it is metering time! the input, output and lufs meters should be correct now. still need to handle the slider, placing its current value somewhere (likely on the bottom, besides the lufs label) I moved away the leveler gain as it did not fit too well in there, will try to put it on the title/top side next.

also the widgets are smaller now, things were getting a bit too big so I reduced font size, border size and padding. it is not possible to change this dynamically, but will be soon.

falkTX commented 2 years ago

Status as of 2022-08-23

image

image

Finally some work on the mixer-slider, for which opinions are wanted/welcome. The slider goes from 0 to -50dB, which is less than the meters (which go to -70). I am guessing it is intentional. I made the slider mimic how a real one would work, kinda, with half of its height going "out of bounds" of the rail. This is because it is the center position of the slider that is important, restricting the slider handle to where line/rail is drawn would make the scaling no longer match. Is this ok? should it work differently?

Still regarding this slider, I need some help figuring out how to map mouse movement to dB positions. The meters work fine, @x42 was nice to let me borrow a little code to do the conversion, but now I need the reverse. I have a % and need to convert it to dB. Seems to require some log/exp math, which is not my forte. The intention is to have mouse press/move match 1:1 to the dB the mouse is under.

I placed the leveler gain meter on top, but is a bit weird. @trummerschlunk already indicated it doesn't belong there :P Was worth a try.

Turned the enabled button into a switch, as it could be confused with easy/expert buttons which act as radio buttons. Moving leveler gain from the top, makes more sense to put the switch near the plugin name, will try that next.

Lastly, there is a little text on the easy page showing some plugin and build info. It is just place holder for testing for now.

btw, I didnt mention this before but dpf-based widgets have these properties (which applies to this plugin too):

magnetophon commented 2 years ago

@falkTX Wonderful! Thanks for lining up the parameters!

magnetophon commented 2 years ago

Any idea why the limiter knee is swapped with the ff-fb? In the faust code the order is correct.

x42 commented 2 years ago

Why does a limiter have a control knob for feedback compression in the first place?

magnetophon commented 2 years ago

Because it's more of a compressor than a limiter. :)

trummerschlunk commented 2 years ago

True that. Imagine an 1178er or TG1 or thelike...

magnetophon commented 2 years ago

In my latest PR, this parameter makes even more sense, because it allows you to share the load with the brickwall: image

x42 commented 2 years ago

Feedback compression is pretty much useless for limiters. A feedback compressor analyzes the signal after compression and uses that to control the gain stage. For a limiter this is too late. A loud signal will already have been let though before the compression stage can respond.

Feedback compression is mainly used by compressors that color the signal. A common example is old Neve. It strikes me as odd to use it here, especially with a lot of controls (also unusual for feedback or hybrid comps). Just saying.

x42 commented 2 years ago

Finally some work on the mixer-slider, for which opinions are wanted/welcome.

It currently directly jumps to the target value when clicked. I think it would be preferable if it operated like a Fader (relative movement). Also, unmodified mouse-movement is not currently 1:1 linear. The Fader moves faster than the mouse Y-axis travel.

magnetophon commented 2 years ago

@x42

Feedback compression is pretty much useless for limiters.

That is true, but it's not a limiter, it's a compressor. @trummerschlunk put it there, chose an RMS compressor, and added a strength parameter (aka ratio), so no, it's not a limiter.

I already proposed to rename it.

x42 commented 2 years ago

I already proposed to rename it.

May I in turn propose to change "Brickwall" to "Limiter", after that?

magnetophon commented 2 years ago

That's also part of my proposal:

knee-comp -> pre compressor ms-multiband-compressor -> multiband compressors limiter -> post compressor brickwall -> limiter

x42 commented 2 years ago

IMHO, naming each compressor according to their semantic use, as @trummerschlunk explained it, would be preferable. "Pre/Post" is meaningless and obvious.

falkTX commented 2 years ago

Finally some work on the mixer-slider, for which opinions are wanted/welcome.

It currently directly jumps to the target value when clicked. I think it would be preferable if it operated like a Fader (relative movement).

So on click it would jump a bit closer to target but not fully matching the area clicked? Easy to do.

Also, unmodified mouse-movement is not currently 1:1 linear. The Fader moves faster than the mouse Y-axis travel.

It is linear, but the drawing is not (including the slider position). In order to make the slider position pixel-perfect-aligned with the meters, the same dB scaling that happens with the meters is applied to the position of the slider when drawing.

This is what makes the 1:1 mouse tracking more complicated. we need the inverse of the dB scale function.

falkTX commented 2 years ago

Any idea why the limiter knee is swapped with the ff-fb? In the faust code the order is correct.

a little mishap, will correct.

falkTX commented 2 years ago

Status of 2022-08-24

image

image

The leveler gain was moved back into the left side, with metering style similar to the one for lufs. the gain value is displayed on the bottom, similar to how the mixer-slider is.

Near the top of the input group/frame, there are now labels for "target" and "Lvl Gain". With smaller font than usual because otherwise wouldnt fit.

You can now see some arrows in between the parameter groups, though I still have to place the limiter->brickwall one and eq->kneecomp.

The value-sliders can now be dragged both horizontally and vertically. Hold ctrl for precise movement. Do Shift+click to reset to default value.

Enable button was moved to the right, near the name.

Also some minor cleanup and tweaking where things were not exactly pixel perfect.

And finally, the popup window that appeared when clicking on a empty area was transformed to a built-in dialog window, so it is less annoying to use. Oh not triggered by clicking anywhere now, you need to click on the plugin name for the dialog to appear. It is just a debug dialog that helps in development. I will remove this on the final build. Will try to have the same but for theming soon, so you can set colors and sizes. We can even save those as part of plugin state, because why not. But it is not a required feature, so will leave it as extra for later.

image

falkTX commented 2 years ago

early update, as current sizes and colors do not have to be final. clicking on the plugin name will now open the debug dialog, but it will have theming options instead of widget details. these are not saved at the moment, so changes are lost when you reload the UI. but tinkering with it is quite fun.

we can activate pink mode πŸŽ‰ πŸ™ˆ

image

(obviously this is not the official color scheme! but still fun)

so now you can easily test color changes, just let me know what to change and we can make it the default.

falkTX commented 2 years ago

related to previous point. you can bump all number values by 2 to generate a faux high-dpi mode. which helps in testing too.

image

falkTX commented 2 years ago

Status as of 2022-08-25

image

image

we got arrows now 🏹 the leveler -> kneecomp is not final, will make it shorter and cut it near the start, for next time.

tweaked the easy mode layout a bit, trying to find things to put in there. I had the idea of having a histogram of lufs and metering, but faust doing processing per audio block makes it a bit complex to handle consistently. there are other more important things at hand for now.

the target slider now behaves like a knob in its mouse movement, no longer click to make it go to that place (which didnt work anyhow). but there is some oddity with it where going up is faster than down.. to fix soon.

% sliders now show and act as integers.

started to put some labels/markers for mscomp, still WIP

and quite some more cleanup and alignment issues, found by messing with the layout and resetting (using the theme editor dialog).

tbh I am not sure what to place on the easy mode that does not take some substantial amount of time, and we are reaching the target limit here. seems best to just use the space for the presets. if they have more than 1 sentence for description, that already fills up the space quite nicely.

once I am done with the tweaks and fixes I will go for the double-click value text input. probably can (ab)use imgui for that since it is already in place for the debugging and theme editor. instead of rolling a custom text input interface, just using a custom imgui widget matching current style should do the trick nicely..

trummerschlunk commented 2 years ago

Beautiful! Feels very complete already :)

Just to head into the right direction with 'easy' mode... Nothing should confuse the user. The 'tutorial text' and easy to understand preset buttons are most important.

Preset Buttons don't even need descriptions, I guess.

Some nice optics like a histogram would be cool, but I would limit it to the 'leveler-gain' parameter. No other parameters or meters on 'easy' page.

I will try and come up with a logo as background wallpaper maybe...

falkTX commented 2 years ago

Status as of 2022-08-27

image

image

I did not write an update yesterday as there was not much to report on, as I got busy with a few MOD related things. Now back with some goodies 🍬 🍬 🍬

We have a histogram now! πŸš€ Tracking LUFS in and out for the last 30s. Requires UI to be open, as data is kept on UI side. Kinda rough at the moment, pushed so we can test/try it and see how good or bad it works.

The histogram is based on https://github.com/epezent/implot which as the name implies uses imgui. It seems to consume a bit of cpu, so will try to optimize things for it later. The implot API is also quite extensive, allowing zoom, reposition of labels and axis and a bunch of other stuff. I just made it static for now as that is the easiest to control. Now with it in place, we can try to tweak it a bit.

Preset buttons were moved into a better place, big buttons because yes, and it is easy mode too.

There is a logo too! For now it renders using the PNG image as source (both 1x and 2x scaling available), later on we can setup things to use an SVG, but DPF can't render those yet.

And finally some UI related fixups, some meters were not setup properly. A few UI bugs still remain though, all to be fixed soon.

falkTX commented 2 years ago

oh btw, the plot/histogram stuff likely doesnt work on the lv2 version at the moment. I need to update the pregenerated ttl files to enable a few things. will do that next time. I tested it with VST2, that one should work.

falkTX commented 2 years ago

Status as of 2022-08-28

image

Only very minor UI changes this time Added zoom levels in the theme editor, so it is easier to test things in different scale options. Logo is right-most aligned. Target slider is capped at -2dB max now. And little tweaks following dsp side.

Most was bugfixes this time. LV2 version is now back on par with the other formats. VST3 UI now has correct initial size. Handling of integer-step sliders is better now, but seems not fully working right just yet.

Getting to the final stages though.

falkTX commented 2 years ago

plugin is ready!

readme has extensive info about it, including updated screenshots. 2 things remain to do, both for reducing cpu usage but they are not release blockers.

I fixed up a few final vst3 implementation details, dealing with host quirks regarding parameter handling.

From my POV, plugin is ready for release. Let's give it some final testing and then tag v1.0.0 if no release blockers appear.

Closing this one, has been great, pushing a new plugin and in parallel improving DPF too! :tada: