Wow, that was quick! It can be so simple. So you intialize the value to -DBL_MAX now? It think it should rather be zero, though. The power computation starts with the maximum of the mean squared sample values and only at the end is converted to decibel scale with values ≤ 0 (only rounding errors triggering values > 0). See lines 219-220:
/* scale the pow value to be in the range 0.0 -- 1.0 */ ds.maxpow = ds.maxpow / (samplemin * (double)samplemin); I suspect samplemin is 32768 for 16 bit data here … ah, yes, it's -32768. Probably starting with a negative value is fine, but I do wonder what happens with an empty MP3 file: $ echo -n | out123 -w nothing.wav $ lame nothing.wav LAME 3.100 64bits (http://lame.sf.net) Using polyphase lowpass filter, transition band: 16538 Hz - 17071 Hz Encoding nothing.wav to nothing.mp3 Encoding as 44.1 kHz j-stereo MPEG-1 Layer III (11x) 128 kbps qval=3 Frame | CPU time/estim | REAL time/estim | play/CPU | ETA 1/1 (100%)| 0:00/ 0:00| 0:00/ 0:00| 109.30x| 0:00 --------------------------------------------------------------------------------------------------------------------------------------------------------------------- kbps MS % long % 128.0 100.0 100.0 Writing LAME Tag...done ReplayGain: 0.0dB Arguably, 0 dB is the correct gain for nothing, without getting philosophical. Now, just for fun, what does the faulty normalize-audio do? $ LANG=C normalize-audio -n nothing.mp3 Computing levels... level peak gain normalize-audio: error reading nothing.mp3: Numerical argument out of domain $ LANG=C normalize-audio -n nothing.mp3 Computing levels... level peak gain 618.7626dBFS -infdBFS -630.7626dB nothing.mp3 $ LANG=C normalize-audio -n nothing.mp3 Computing levels... level peak gain 920.3700dBFS -infdBFS -932.3700dB nothing.mp3 $ LANG=C normalize-audio -n nothing.mp3 Computing levels... level peak gain normalize-audio: error reading nothing.mp3: Numerical argument out of domain $ LANG=C normalize-audio -n nothing.mp3 Computing levels... level peak gain File nothing.mp3 has zero power, ignoring... Ah, at last! This test case very clearly shows the differing intialization values, even sometimes evaluating to zero. The error about failed read of nothing.mp3 probably comes from the callback structure of the libmad API … (still weird) Anyhow, when I set ds.maxpow = -DBL_MAX: $ LANG=C src/normalize -n nothing.mp3 Computing levels... level peak gain normalize: error reading nothing.mp3: Numerical argument out of domain:00) This is not a good result. With ds.maxpow = 0: $ LANG=C src/normalize -n nothing.mp3 Computing levels... level peak gain File nothing.mp3 has zero power, ignoring... This is what should happen. It also makes a lot more sense for the memory usually being intialized to zero for most builds. This obvious error wouldn't have gone unnoticed for _decades_ otherwise. So, what does the Debian build do to make the ds struct _not_ zeroed at the beginning? It's interesting that 'luck' worked since the early 2000s to have that uninitialized initial power value be zero by chance, and only recently this got broken, and that also only on my machine, not yours. Maybe you can better reproduce it with the empty mp3 file? I guess some hardening, memory randomization is to blame. Maybe that's only active for Ubuntu and not stock Debian libc/kernel … but it does trigger with Debian's binary. So, the proper fix should be intializing ds.maxpow = 0 so that the correct/expected result is computed also for empty input. Alrighty then, Thomas PS: Is upstream clearly dead? Chis Vaill is still listed as 'active' on https://savannah.nongnu.org/project/memberlist.php?group=normalize Would be nice to get an official version 0.7.8.