trummerschlunk / master_me

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

limiter: missing latency report #13

Closed x42 closed 2 years ago

x42 commented 2 years ago

The brickwall limiter, when enabled, adds a a latency of 480 samples (@ 48kHz). it's really limiter_lad_lookahead = 0.01; * ma.SR

When bypassing the limiter (or the whole effect), either the latency has to be reset to 0, or ideally a crossfade happens with a signal that is delayed by latency.

falkTX commented 2 years ago

If the latency is constant (time-wise), we can pass this info into the plugin wrapper and let it handle the case of bypass.

I see a few bypass related controls in the faust file, but not sure how that is managed in a deeper level.

From what I understand after talking with other devs, doing "global" (plugin-wide) bypass control in faust code is not a good idea, as the non-bypassed code would always run. And in any case, we can optimize things better in the native C++ portion of the plugin wrapper. We can have a transition between on and off states, and once the off transition completes we stop processing the faust side. Is this doable, or do we have precise-time-dependant faust code at play here? (that would go out of sync if we stop processing)

x42 commented 2 years ago

Yes the latency is constant, only depending on the sample-rate.

From what I understand after talking with other devs, doing "global" (plugin-wide) bypass control in faust code is not a good idea, as the non-bypassed code would always run.

Yes, that is what is required. DSP load should be constant. You don't want to add load in a mastering plugin depending on settings in a live show.

In this case the bypass code is just a delayline. Worst case 2 calls to memcpy(). I use that in pretty much all x42 plugins where x-fade is the correct way to bypass a latent plugin or where a dry/wet control is needed. e.g. zero-convolver that you are familiar with.

The alternative here would be to smoothly ramp the limiter threshold to 0 (which is what x42-dpl does).

falkTX commented 2 years ago

hmm the constant dsp load is a good point. turning off the plugin internally would falsely make it more performant, only because it is actually doing nothing.

but is that a real issue? if a plugin is bypassed, the user could be expecting the plugin to be off/disabled and thus not consume cpu. seems a bit weird to me that a plugin consumes the same cpu when enabled and disabled.

x42 commented 2 years ago

If you enable a hard bypassed plugin, the DSP load increases. Worst case it may be more than the system can handle and you get x-runs. More commonly the CPU load increases, frequency scaling kicks in and you may also get a dropout.

For the case at hand, the mastering plugin always runs after all other processing is complete. It cannot be run in parallel and any DSP load it introduces will directly be added to the overall load.

Then again this is a detail for now. Ideally the final plugin should not even allow to disable the limiter or any internal stages for that matter.

falkTX commented 2 years ago

so you think for this plugin in specific, it is best to always have plugin dsp running, even if bypassed? I am ok with that, makes sense for this one but don't think it applies in general.

in any case, we need to report the latency to the host. is there any faust specific declaration for it, or do we need to define a new one?

trummerschlunk commented 2 years ago

Good morning! (I was an owl too once, don't know when that changed...)

The bypass of limiter and brickwall are obsolete as they are vital part of the mastering chain. I'll eliminate them. This way, latency will be constant and never change (in milliseconds, so samplerate dependent).

For the question of changing cpu load, I am leaning towards never changing it. I am familiar to spikes when plugins do that. I also want the bypassed module to actually process audio, which is why I implemented a custom bypass function bp2.

trummerschlunk commented 2 years ago

I asked @sletz some weeks ago, if there is a way to report latency, but apparently there isn't.

magnetophon commented 2 years ago

I asked @sletz some weeks ago, if there is a way to report latency, but apparently there isn't.

I had the same feature request for faust2lv2 a couple of years ago, and it's implemented now:https://bitbucket.org/agraef/faust-lv2/issues/9/feature-request-latency-compensation-meta.

There is also an issue for faust itself: https://github.com/grame-cncm/faust/issues/614

trummerschlunk commented 2 years ago

Actually, I would really like to get rid of the latency, but I don't think there is a non-lookahead brickwall limiter which is clean and safe. I was even thinking about a clipping stage as last module...

What's your ideas on that?

magnetophon commented 2 years ago

Actually, I would really like to get rid of the latency, but I don't think there is a non-lookahead brickwall limiter which is clean and safe.

A lookahead limiter has much better chances of being clean, but my compressor in the libraries is 100% brickwall, when used with a fixed strength of 1 and with an attack of 0.

No need for a clipper, this will sound cleaner.

If you insisit on 0 latency, your best bet for clean sound is this compressor/limiter. Quoting myself from the docs:

N channel RMS feed back compressor into peak limiter feeding back into the FB compressor.
By combining them this way, they complement each other optimally:
the RMS compressor doesn't have to deal with the peaks,
and the peak limiter get's spared from the steady state signal.
trummerschlunk commented 2 years ago

cool, I will try both options...

magnetophon commented 2 years ago

I made a start with integrating the above limiter. Turns out it was already in there, just with a fixed high-ish threshold and the metering disabled.

x42 commented 2 years ago

I think you will want a lookahead limiter as part of a master-chain. Especially if you target EBU compliance which requires a hard -1 dBTP limit.

magnetophon commented 2 years ago

If I understood the goal of this project correctly, it's to make spoken word content, produced by amateurs, sound better, while not messing up musical content too much. Is that correct @trummerschlunk?

For these reasons, I'm not sure if the latency is worth it. In the end I think it boils down to the subjective choice between cleaner sound and less latency.

For faust in general, I would love better support for latency reporting though!

x42 commented 2 years ago

Sure for live situations reporting the latency makes no difference. Yet if the plugin is also used for later re-encoding (like the VOC team does), it should report it if there is any.

For the case at hand, a latency of just over 1ms should be sufficient (compare to x42-dpl in true-peak mode). That's around 40cm of sound in air and not much of an issue.

I assumed since the rest of the plugin ties into EBU loudness spec this is meant to to target broadcast standards. If that is not the case, it is indeed rather subjective.

trummerschlunk commented 2 years ago

There is no modules using 'looka-head' anymore in the code.

Look-ahead Limiters sound nice, but the latency is a tradeoff in live-streaming situations. The brickwall I am using now does a good job.

Is the plugin really zero-latency then? At least a little time is needed to do the calculations, no?

Can we close this issue then?