[GH-ISSUE #257] Normalisation not consistent #157

Closed
opened 2026-02-28 14:25:53 +03:00 by kerem · 7 comments
Owner

Originally created by @tagdara on GitHub (Nov 16, 2025).
Original GitHub issue: https://github.com/devgianlu/go-librespot/issues/257

For the last 2-3 versions we see periodic breaks where normalisation does not lift up older tracks.

There are no errors in the log or anything that indicates a problem. Not sure if other folks are seeing this as well.

My config (which has not changed recently and predates the issue is as follows)

device_name: xx-go
device_id: xx
devide_type: avr
log_level: info
zeroconf_enabled: true
credentials:
  type: interactive
  interactive:
    callback_port: 36751

server:
  enabled: true
  port: 3678
  allow_origin: xx.xx.tech
  address: 0.0.0.0

audio_device: default
volume_steps: 100
initial_volume: 100
external_volume: true
disable_autoplay: true 
normalisation_disabled: false
Originally created by @tagdara on GitHub (Nov 16, 2025). Original GitHub issue: https://github.com/devgianlu/go-librespot/issues/257 For the last 2-3 versions we see periodic breaks where normalisation does not lift up older tracks. There are no errors in the log or anything that indicates a problem. Not sure if other folks are seeing this as well. My config (which has not changed recently and predates the issue is as follows) ``` device_name: xx-go device_id: xx devide_type: avr log_level: info zeroconf_enabled: true credentials: type: interactive interactive: callback_port: 36751 server: enabled: true port: 3678 allow_origin: xx.xx.tech address: 0.0.0.0 audio_device: default volume_steps: 100 initial_volume: 100 external_volume: true disable_autoplay: true normalisation_disabled: false ```
kerem 2026-02-28 14:25:53 +03:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@olta commented on GitHub (Nov 18, 2025):

I can at least second that volume behavior has changed recently.

In our case, we have recently noticed that the maximum volume of our devices has dropped a bit. Our devices are using hifiberry miniamps, which only have a maximum output of 2x3W, I guess that's why we've noticed.

I'm not sure this is related to normalization or not, but it would make sense, as otherwise I don't think anything has changed recently regarding volume management, has it? When I checked just now, Spotify's app told me that volume normalization isn't available for our devices - I've never noticed this before, so maybe something has changed on Spotify's side to that regard?

<!-- gh-comment-id:3547232082 --> @olta commented on GitHub (Nov 18, 2025): I can at least second that volume behavior has changed recently. In our case, we have recently noticed that the maximum volume of our devices has dropped a bit. Our devices are using hifiberry miniamps, which only have a maximum output of 2x3W, I guess that's why we've noticed. I'm not sure this is related to normalization or not, but it would make sense, as otherwise I don't think anything has changed recently regarding volume management, has it? When I checked just now, Spotify's app told me that volume normalization isn't available for our devices - I've never noticed this before, so maybe something has changed on Spotify's side to that regard?
Author
Owner

@tagdara commented on GitHub (Nov 25, 2025):

This week I’m at my vacation place where I have a completely different librespot instance running and it is suffering the same problem.

It was untouched since September with no volume challenges, but restarting the librespot-go container updated to latest and I have identical volume problems.

No other changes were made. Most older songs are very quiet. If you turn it up the next song that plays with 2000+ master date typically blows your ears out.

<!-- gh-comment-id:3573809589 --> @tagdara commented on GitHub (Nov 25, 2025): This week I’m at my vacation place where I have a completely different librespot instance running and it is suffering the same problem. It was untouched since September with no volume challenges, but restarting the librespot-go container updated to latest and I have identical volume problems. No other changes were made. Most older songs are very quiet. If you turn it up the next song that plays with 2000+ master date typically blows your ears out.
Author
Owner

@tagdara commented on GitHub (Nov 26, 2025):

Going back through the code, I noticed that the commit for FLAC normalization github.com/devgianlu/go-librespot@db0414a619 made a TON of changes to the way normalisation is handled even outside of FLAC and is the most likely point where it broke. I've spun up a custom version with a bunch of logging to see what I can find out.

Update: At a minimum, it's backwards. Adding normalisationFactor = 1 - normalisationFactor creates a result that is too loud across the board but is far more consistent between tracks with big differences in volume (pre-1990s vs 2010+)

For example:
Prince - Kiss (a quiet track) has a loudness of -15.213523 and gets normalized with 0.17350973
K+Lab - Muuve (a loud track) has a loudness of -5.92256 and gets normalized with 0.5056756

Reversing this with normalisationFactor = 1 - normalisationFactor makes them both play at closer to the same level.

func calculateNormalisationFactor(params *audiofilespb.NormalizationParams, pregain float32) float32 {
	normalisationFactor := float32(math.Pow(10, float64((params.LoudnessDb+pregain)/20)))
	if normalisationFactor*params.TruePeakDb > 1 {
		normalisationFactor = 1 / params.TruePeakDb
	} 
	normalisationFactor = 1 - normalisationFactor
	return normalisationFactor
}
<!-- gh-comment-id:3583213976 --> @tagdara commented on GitHub (Nov 26, 2025): Going back through the code, I noticed that the commit for FLAC normalization https://github.com/devgianlu/go-librespot/commit/db0414a6196f224659cd4cbac84110fd557848db made a TON of changes to the way normalisation is handled even outside of FLAC and is the most likely point where it broke. I've spun up a custom version with a bunch of logging to see what I can find out. Update: At a minimum, it's backwards. Adding normalisationFactor = 1 - normalisationFactor creates a result that is too loud across the board but is far more consistent between tracks with big differences in volume (pre-1990s vs 2010+) For example: Prince - Kiss (a quiet track) has a loudness of -15.213523 and gets normalized with 0.17350973 K+Lab - Muuve (a loud track) has a loudness of -5.92256 and gets normalized with 0.5056756 Reversing this with normalisationFactor = 1 - normalisationFactor makes them both play at closer to the same level. ``` func calculateNormalisationFactor(params *audiofilespb.NormalizationParams, pregain float32) float32 { normalisationFactor := float32(math.Pow(10, float64((params.LoudnessDb+pregain)/20))) if normalisationFactor*params.TruePeakDb > 1 { normalisationFactor = 1 / params.TruePeakDb } normalisationFactor = 1 - normalisationFactor return normalisationFactor } ```
Author
Owner

@devgianlu commented on GitHub (Nov 27, 2025):

That particular logic is still the same it was before, so I think that it's just a coincidence that it sounds better.

What I think might have happened is that the normalisation values parsed from the Vorbis metadata are not the same format as the ones coming from the extended metadata API.

If that's the case, it should be an easy fix. Perhaps just a matter of a dB conversion.

<!-- gh-comment-id:3586878702 --> @devgianlu commented on GitHub (Nov 27, 2025): That particular logic is still the same it was before, so I think that it's just a coincidence that it sounds better. What I think might have happened is that the normalisation values parsed from the Vorbis metadata are not the same format as the ones coming from the extended metadata API. If that's the case, it should be an easy fix. Perhaps just a matter of a dB conversion.
Author
Owner

@tagdara commented on GitHub (Nov 27, 2025):

To your point, I plugged back in the actual old logic that just pulls it directly from the metadata:

Prince - Kiss (quiet mastered): new: 0.173510 / old: 0.574778 / 1-new: 0.826490
K+Lab - Muuve (loud mastered): new: 0.505676 / old: 0.279337 / 1-new: 0.494324

You can see that while my "1-nf" guess is not the same as the old stored value, it at least normalizes in the right direction and is absolutely not just coincidence or perception (nor is it 'the same as it was before'). It should be higher for the first and lower for the second, full stop.

<!-- gh-comment-id:3587030391 --> @tagdara commented on GitHub (Nov 27, 2025): To your point, I plugged back in the actual old logic that just pulls it directly from the metadata: Prince - Kiss (quiet mastered): new: 0.173510 / old: 0.574778 / 1-new: 0.826490 K+Lab - Muuve (loud mastered): new: 0.505676 / old: 0.279337 / 1-new: 0.494324 You can see that while my "1-nf" guess is not the same as the old stored value, it at least normalizes in the right direction and is absolutely not just coincidence or perception (nor is it 'the same as it was before'). It should be higher for the first and lower for the second, full stop.
Author
Owner

@devgianlu commented on GitHub (Nov 30, 2025):

There were multiple issues with the new normalization code, my bad for pushing it. Feel free to reopen this if you still have issues.

It should know be fixed, I tested the tracks @tagdara mentioned and they seemed pretty balanced to my untrained ear.

<!-- gh-comment-id:3592456748 --> @devgianlu commented on GitHub (Nov 30, 2025): There were multiple issues with the new normalization code, my bad for pushing it. Feel free to reopen this if you still have issues. It should know be fixed, I tested the tracks @tagdara mentioned and they seemed pretty balanced to my untrained ear.
Author
Owner

@tagdara commented on GitHub (Nov 30, 2025):

Thanks! I've compiled the latest, deployed it, and we plan on listening to music all day. So far it seems to work great.

<!-- gh-comment-id:3593285499 --> @tagdara commented on GitHub (Nov 30, 2025): Thanks! I've compiled the latest, deployed it, and we plan on listening to music all day. So far it seems to work great.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/go-librespot#157
No description provided.