jmshrv / finamp

A Jellyfin music client for mobile
Mozilla Public License 2.0
1.67k stars 117 forks source link

0.9.7b - Desktop base gain #765

Open Fale opened 3 weeks ago

Fale commented 3 weeks ago

Hi,

I have 0.9.7b both installed on my phone and on my PC (as a testing flatpak).

I've noticed that in Settings -> Volume Normalization there is "Base gain" option (defaulted to -2.0db) on the desktop one but not on the mobile one.

I think the -2.0 default is problematic since it is not conforming to the user expectation (that would be that by default 100% audio = 100%, not 80%). If I understand correctly from @Chaphasilor comments, bringing the base gain to 0.0 would basically disable the volume normalization due to how usually reply gain is annotated.

I think that some "alternative way" should be found, since the application should behave in an opinion that fulfills the user's expectations (both that volume is 100% and that volume normalization work). Though, I do not understand the full complexity behind it to be able to provide a sensible solution for this. I really wonder how other players work around this issue.

Chaphasilor commented 3 weeks ago

Okay, so here's how replay gain and Jellyfin's volume normalization works:
Each track is analyzed using a special algorithm. That algorithm calculated the "loudness units full-scale" (or "LUFS" for short), an absolute value that tries to describe how loud a piece of audio appears overall.
The Jellyfin server now sets a reference level (of -18 LUFS) that all tracks should be normalized to. So if a track had a LUFS value of -10, it receives a negative "gain" of -8 dB, since -10 LUFS + -8 dB is -18 LUFS.
But there could also be some tracks that are recorded differently, or very quiet by design, and those might have a LUFS value of -24 or even lower. Those would then receive a positive gain of +6 dB.
In the end, all track would be played at -18 LUFS.

The issue now is that except the audio library Finamp uses under the hood does not support applying an actual gain to the played audio (except on Android). It it would, we could apply a negative gain to reduce the volume, and a positive gain to increase/boost the volume by any amount, independent of the actual volume. Think of it as talking to someone on the phone: you can change the volume of your speaker/earpiece, and the other person can move closer or farther away from their microphone. You control the volume, they control the gain. If your phone is at maximum volume, they can still talk louder, simply by moving closer to their microphone.

Since this gain doesn't work on all platform except for Android, the only thing Finamp has left to control is the volume. That is at 100% by default, and can't go higher, only lower.
Now for the tracks that are -10 LUFS and have a negative gain of -8 dB, or anything greater or equal to -18 LUFS, this isn't an issue. We simply decrease the volume when those are played. A track with -8 dB might play at 55% volume, one with -3 dB might be closer to 80%. In the end, they all sound roughly equally loud.

But for the quiet track with a positive gain, we face a problem: We start at 100% volume, and now need to increase the volume further to apply the gain. That doesn't work.
The only way we can do it (as far as I know!) is do reduce the starting volume to something like 80%, and then use the remaining 20% if we need to apply a positive gain. A gain of 2 dB would maybe go to 90% volume, one with 3 dB to 95%, all good. But a gain of 6 dB would only go to 100%, when it would need to go to 110% or so. So the normalization "bottoms out", and the track is only almost as loud as the other tracks. The higher the gain, the greater the difference.

That's why we start with a base gain of -2 dB on all other platforms. Essentially this adds this gain to the track gain, so a track with a gain of -8 dB becomes -10 db, one with 6 dB becomes 4 dB, and one with 2 dB becomes 0 dB. That means we can properly normalize all tracks up to a gain of 2 dB, where we hit 100% volume.
Set the base gain to -6 dB and you can normalize everything up to 6 dB gain. A track with 8 dB gain will be almost equally loud, while a track with a gain of 14 dB will be noticeably quieter.

That's really the whole issue here.

Now one thing to note is that most tracks should have a negative gain. -18 LUFS is relatively quiet, so most track need to be reduced in volume to achieve it. Most, but not all. There are tracks that are way more quiet, I think the highest gain I've see so far was +19 dB. So that's why I allocated a bit of "headroom" for those rare, quiet tracks by reducing the base gain.
Depending on your personal library, this value might be better or worse. If you only have pop music, you can probably safely set the base gain to +8 dB and everything this works, since no track has a higher gain than -8 dB. If you listen to a lot of classical music, it might be the other way around.

The reason why you music is so quiet now is because your tracks apparently have a negative gain, maybe -12 dB, and the -2 dB base gain are added on top. So in total, the volume for a playing track might be reduced by -14 dB, which is ~20% volume. You can experiment with higher base gain values (4, 6, 8) and see if it still works well for your library!

The Jellyfin server currently doesn't easily let us find out what the minimum and maximum gains are, so there's no way to be sure, we literally have to guess.

I hope this explains things a bit better!

Fale commented 3 weeks ago

Thanks a lot for the explanation on the exact details of it.

Documenting this might help, but I still think that this is not the behavior the user expetcts, so there will be many complains about this.

DomiStyle commented 4 days ago

Is there an upstream issue somewhere for applying a gain on desktop?

I currently have the gain set to 8.0, which works decently well but definitely has issues on some tracks. Could probably be alleviated a little bit by having a dedicated volume slider (https://github.com/jmshrv/finamp/issues/500).