lordmulder / DynamicAudioNormalizer

Dynamic Audio Normalizer
Other
251 stars 36 forks source link

DynamicAudioNormalizer makes some parts of audio quieter #15

Closed knopp closed 5 years ago

knopp commented 6 years ago

I'm not sure if this is intentional, but it is quite unexpected. I have peek value set to 0.7. In some loud sections of the audio MDynamicAudioNormalizer_PrivateData::getMaxLocalGain returns value less that 1, which results in audio volume actually being lowered compared to original. If I clamp the result to always be >= 1 it works as expected.

All my options: frame-length: 300, filter-size: 11, peek-value: 0.7, max-amplification: 5.0, target-rms: 0, compress-factor: 0, channel-coupling: 1, dc-correction: 0, alt-boundary: 1

lordmulder commented 6 years ago

Hello.

The purpose of the getMaxLocalGain() internal function is to compute the maximum amplification factor that may be applied to a specific frame without causing "clipping" in that frame. And "no clipping" here means that we must not exceed the target peak magnitude - but we can approach it as closely as possible.

More specifically, that function computes the amplification factor that would bring the magnitude of the "loudest" peak within the frame to the selected target peak magnitude. By default, the target peak magnitude is 0.95. If the magnitude of the "loudest" peak in the frame is below the target peak magnitude, then you would get an amplification factor (return value) greater than 1.0. If the magnitude of the "loudest" peak in the frame already is at the target peak magnitude, then you would get an amplification factor (return value) of exactly 1.0. And, if the magnitude of the "loudest" peak in the frame happens to be above the target peak magnitude, then you would get an amplification factor (return value) less than 1.0.


BUT: Be aware that the getMaxLocalGain() only computes the maximum "local" amplification factor that, in theory, could be applied to a particular frame without clipping. That is not the amplification factor that will actually be applied to the frame, though! In order to avoid too much fluctuation of the amplification factors (aka "pumping effect") we apply a minimum filter and a Gaussian smoothing kernel to all the "local" amplification factors. So, in the end, a certain frame can (and of then will!) end up with a smaller "final" amplification factor than what its maximum "local" amplification factor would allow - certainly never greater.

See also: Chart.pdf

Regards, MuldeR

knopp commented 6 years ago

Thanks. getMaxLocalGain was maybe not the right place to look at, however the amplificationFactor in amplifyFrame is still less than 1 in one of the videos I tested. That means the frame volume is lower after normalization than before.

lordmulder commented 6 years ago

however the amplificationFactor in amplifyFrame is still less than 1 in one of the videos I tested. That means the frame volume is lower after normalization than before.

Yes, that's perfectly possible – depending on how you have chosen the target peak magnitude and depending on the "neighboring" frames. What I wrote above should make clear why that is 😏

knopp commented 6 years ago

Thank you for the explanation. I guess I my expectation was wrong. For some reason I assumed that the hitting the target peak magnitude would prevent frame from being amplified, but would not cause the frame actually ending up quieter than before normalisation. I simply treated target-peak magnitude as limit for amplification for quiet passages and did not expect the normalizer to touch loud passages. Maybe in future these limits could be separated?

lordmulder commented 6 years ago

I simply treated target-peak magnitude as limit for amplification for quiet passages

That is pretty much what the maxAmplification parameter does. Isn't it?

Maybe in future these limits could be separated?

I'm not sure what would be the justification for that... :confused:

knopp commented 6 years ago

Well, unlike target-peak magnitude, maxAmplification does not take frame loudness into account. So for some parts max amplification of 5 may be fine, for other it may be too much. So I wanted to use the peak magnitude to limit the amplification in some parts of the audio, but I didn't want this to affect scenes that are originally above my selected target-peak. If this not something that would be generally useful I'll be more than happy to just patch my local build :)

lordmulder commented 6 years ago

Well, the target peak magnitude is the maximum magnitude (limit) that will ever be allowed - anything above that is considered as "clipping". So, if you don't want existing peaks in your input to be attenuated, you must set target peak magnitude sufficiently high. At the same time, the max. amplification factor can be used to prevent "quiet" sections from being amplified too much. This is useful, IMO, because amplifying "quiet" sections by a very large factor can result in the quantization noise to become audible...