Author Topic: Loudness war!  (Read 1372 times)

Offline bass

  • Active artist
  • *
  • Posts: 14
Loudness war!
« on: June 01, 2019, 00:02:04 »
Sorry for the clickbaiting title. After a few years, I started programming on my tracker player again. I have noticed, that OpenMPT plays XM files louder than my player. I´m mixing everything in floats and finally converting the float data into 16 bit output. For this, I have to divide the data somehow depending on the channel count. There are many therories what this divider should be. What are your experiences with this? I get clipping, when my divider is too low. But OpenMPT doesn´t clip and is still louder. Am I doing something wrong here?
Thanks!

Offline Saga Musix

  • OpenMPT Developers
  • *****
  • Posts: 6,768
  • aka Jojo
    • Download music, samples, VST plugins: Saga Musix Website
  • Operating System: Windows 10 x64
Re: Loudness war!
« Reply #1 on: June 03, 2019, 08:12:12 »
XM doesn't have a well-defined global volume, you could even change it in  FT2 and this value wouldn't be saved in XM files even, so you can only guess what the correct amplification factor is. OpenMPT's default amplification is that one full-volume voice is played at around -15dB in the mix which has proven to be a rather good average value for lots of different modules. However, for some files it's too quiet and for others it's too loud so it's not a silver bullet.
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.

Offline bass

  • Active artist
  • *
  • Posts: 14
Re: Loudness war!
« Reply #2 on: June 03, 2019, 14:14:11 »
Thank you! So, this means, you divide each sample value on a channel by (1 / 0.177828)?
And does it make a difference for the sound scaling the sample values on each channel while mixing or scaling the final sample value after mixing?

Offline Saga Musix

  • OpenMPT Developers
  • *****
  • Posts: 6,768
  • aka Jojo
    • Download music, samples, VST plugins: Saga Musix Website
  • Operating System: Windows 10 x64
Re: Loudness war!
« Reply #3 on: June 03, 2019, 14:31:50 »
Thank you! So, this means, you divide each sample value on a channel by (1 / 0.177828)?
No, you are taking my approximate a description a bit too literally. :) The sample pre-amp is just one out of many factors leading to the final total amplification amount of every channel, and it's user-configurable. In XM by default it's 48 (found on the General Tab) but it can be changed. The pre-amp is stored as an OpenMPT extension in XM files so other players will ignore it completely and just use whatever pre-amp they want. XMPlay normalizes modules for example, so the pre-amp is calculated while the file is loading. For a tracker this is not a viable approach, though, it makes only sense for players.

Quote
And does it make a difference for the sound scaling the sample values on each channel while mixing or scaling the final sample value after mixing?
It depends. If you literally want to add a separate amplification for the scaling to each channel, then latter is less computationally expensive and introduces less floating-point requantization errors than doing it individually for each sample (every multiplication adds more errors to the final result, so you want to keep the number of operations that require requantization down). However, you can of course just use the same "trick" (really shouldn't be called a trick as it's a trivial optimization that you will find in any good mixer) as OpenMPT and have a single amplification factor that is applied to each mixed sample that itself is a multiplication of actual note volume, panning and the final scaling. This would end up with a single multiplication per audio channel per sample.
So if your mixer currently looks like this:
Code: [Select]
// Mixer
v = sample_value;
v *= note_volume;
v *= panning_left;
v *= global_scaling_factor;
out_left = v;
// same repeated for right channel
Then it would make more sense to optimize it to this:
Code: [Select]
// Somewhere outside of the mixer where the volume of each channel is calculated
volume_factor_left = note_volume * panning_left * global_scaling_factor;
volume_factor_right = note_volume * panning_right * global_scaling_factor;

...

// Mixer
out_left = sample_value * volume_factor_left;
out_right = sample_value * volume_factor_right;
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.

Offline bass

  • Active artist
  • *
  • Posts: 14
Re: Loudness war!
« Reply #4 on: June 03, 2019, 14:55:58 »
Thanks for clarification :-)
I already use the "trick" for the volume factor values (without global scaling factor, because I calculate this at the end when I convert the floating samples [-1, 1] to 16 bit samples).
I just wondered why OpenMPT is much louder playing XM or MOD files than my player, even if my global scaling factor is i.e. 0.25 for 16 channel XM file. Is there a compressor or soft clipping in OpenMPT?

Offline Saga Musix

  • OpenMPT Developers
  • *****
  • Posts: 6,768
  • aka Jojo
    • Download music, samples, VST plugins: Saga Musix Website
  • Operating System: Windows 10 x64
Re: Loudness war!
« Reply #5 on: June 03, 2019, 15:22:06 »
my global scaling factor is i.e. 0.25 for 16 channel XM file.
Please don't adjust the global volume based on the number of channels. ModPlug used to do this and it's a terrible idea.
I cannot tell you what exact factor OpenMPT would be using because there are several possible answers - it depends on many things, including the user-chosen mix mode. In particular the FT2 Pan law is louder in the centre than linear pan law, and whether OpenMPT uses a mix mode with FT2 pan law depends on which tracker was used to create that XM file. With linear pan law, the factor would be 48/256 (assuming a sample pre-amp of 48), with FT2 pan law it's higher.
However, what I can say is that there is certainly no compression or soft clipping going on - you can easily verify by comparing the original waveform and OpenMPT's output.
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.

Offline bass

  • Active artist
  • *
  • Posts: 14
Re: Loudness war!
« Reply #6 on: June 03, 2019, 15:53:34 »
OK, I didn´t expect, that this would be so confusing. But somehow the global volume has to be based ALSO on the number of channels. It´s a big difference if I play 4 or 32 channels. And I don´t want clipping. Of course, I can let the user control the volume or compute the global volume while loading but this seems to be too complicated to me. I thought, there would be an "easy" answer to this. I wonder how other players handle this, it seems, that there is no correct way?!
I also heard about dividing by sqrt(num of channels) or just dividing by number of channels, but this is unnecessary, I think.

Offline Saga Musix

  • OpenMPT Developers
  • *****
  • Posts: 6,768
  • aka Jojo
    • Download music, samples, VST plugins: Saga Musix Website
  • Operating System: Windows 10 x64
Re: Loudness war!
« Reply #7 on: June 03, 2019, 16:02:34 »
Imagine a piano player on stage playing for a concert. Now a flute player enters the stage to accompany the piano. Will the piano automatically become more quiet? Of course not! Maybe the piano player will adjust their play style but that is their decision.
The same goes for volume in a tracker: It is up to the user to decide on a volume level:
1. What if they only use quiet samples that are not normalized? If you decided to change the volume just because they used those samples on a lot of channels, their song will be too quiet.
2. What if they mostly use 8 out of chose 32 channels, but the remaining 24 channels are only used very occasionally? Again, the song will be too quiet.
3. On the other hand, if they decide to put lots of simultaneous notes at full volume on all of those channels, they already have the opportunity to lower the global volume of their song to prevent it from clipping. But it's not up to you to do that decision for them.

It's okay to have a global amplification factor that is not stored individually for each song (like the sample pre-amp in S3M or IT files), but it should treat all songs equally, no matter how many channels they have.
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.