Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use 0.f->1.f for volume instead of decibels #1460

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

LeftofZen
Copy link
Contributor

Expressing in-game volumes in terms of decibels is messy, error-prone, and non-intuitive. Representing volumes internally as a floating-point number between 0-1 inclusive simplifies the code, makes it easy to understand that '0.5f' means half volume, and follows modern standards for how games, game engines, and audio libraries represent volume.

Incidentally, this PR will make it much easier to implement additional volume sliders for the other audio channels in future (I know this because I started implementing volume sliders first before realising this change was necessary).

@LeftofZen LeftofZen added the enhancement Changing an existing feature slightly label Apr 14, 2022
@LeftofZen LeftofZen added this to In Progress in Sound Engine/Mixer via automation Apr 14, 2022
@LeftofZen
Copy link
Contributor Author

This PR also also adds a 'volume' value printed on the options screen, and slightly extends the visual range the slider can move on the track:
image

@LeftofZen
Copy link
Contributor Author

LeftofZen commented Apr 14, 2022

This PR also 'reinterprets' the 4 bytes used in the vanilla config for volume. Originally they were an int32_t, they are now a float.

@@ -88,7 +88,7 @@ namespace OpenLoco::Config
ObjectHeader preferredCurrency; // 0x7C
uint8_t enabledMusic[29]; // 0x50AF40, 0x8C
uint8_t pad_A9[0xCC - 0xA9]; // 0xA9
int32_t volume; // 0x50AF80, 0xCC
float volume; // 0x50AF80, 0xCC // originally int32_t
Copy link
Contributor Author

@LeftofZen LeftofZen Apr 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unsure if this kind of abuse is allowed...if it isn't I'll just deprecate it and add a float volume in NewConfig

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's switch over to NewConfig instead, yeah.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Roger that, I think NewConfig is better anyways since all the settings for other channel volume sliders will live there too, so it unified those settings when I make that PR

@duncanspumpkin
Copy link
Contributor

I disagree that this should be changed. Decibels is the easier to understand units and we have to keep in decibels for interop reasons.

@AaronVanGeffen
Copy link
Member

OpenRCT2 uses percentages for its volume configs, so it's not without precedent. I think there's merit in both, but admittedly the negative decibels had me puzzled for a bit as well, until I read up on it.

@duncanspumpkin
Copy link
Contributor

OpenRCT2 uses percentages for its volume configs, so it's not without precedent. I think there's merit in both, but admittedly the negative decibels had me puzzled for a bit as well, until I read up on it.

Sure master volumes in terms of percentage but i don't want to change the actual maths under the hood. Or if you do then it needs very careful thought as everything has been structured around integer maths.

@LeftofZen
Copy link
Contributor Author

I didn't realise this was such a contentious topic! I disagree that decibels are beneficial to having in a game audio engine, even in a r/e project such as OpenLoco:

  1. dB is not intuitive. How much louder or quieter is -3000dB compared to -600dB? What is 'half volume' in dB? What is the minimum volume? In dB there will always be a value for the minimum, but it makes more sense to set 0 to the minimum and that means silence. The problem is really that the human brain doesn't 'natively' understand logarithmic scales, we first need to convert them to a linear scale. Then, the fact that a calculation is always required for a human to understand the meaning of a dB value means that reading code in dB values is extremely difficult, unintuitive and error-prone.
  2. There is no reason to keep integer maths around for sound mixing. For graphics/pixel placement, scenario simulation, train speeds, etc, yes we need to use integer arithmetic to match the original game, but sound mixing is different. Even if there is a numerical difference in values, no human can perceive the difference from converting to floating-point arithmetic and the sound being slightly louder or quieter by 0.0001%.
  3. The game sounds the same with my rework (ignoring the few small bugs I'm yet to fix). The music, vehicle sounds, etc, all sound properly mixed and the same as last release (to my ears). Nothing was really changed internally with the mixing, just that they are now mixed in floating-point domain and not dB domain.
  4. Interop is the one reason I agree with here, and I will potentially need to postpone this PR until we don't need to deal with any audio interop. There is one small bug in my branch where the game appears to read the volume from the original config still, in a piece of un-reverse-engineered code. I haven't looked too deeply into a possible fix on my end yet so it may not really be a problem, but yeah the interop is the one reason to potentially defer (but not cancel) this PR.

I have a few small fixes to make to this branch still, then you can review it both in code and with your ears :)

@LeftofZen
Copy link
Contributor Author

LeftofZen commented Aug 24, 2022

I won't be working on this specific branch any more since it's outdated and I wanted to restart the implementation, but in my new branch I've thought this over again and how about this middle ground - we leave the core audio mixing/engine in dB as duncan would like, and we continue to call this volume. Then we add the volume sliders for ambient, title, bgm, vehicle, sfx channels in the music options gui, and in the config we call them gain, and in the code, at the instant we call the OpenAL functions to play the sound (ie around here), we mix whatever the channel volume is with the 'gain' from the audio slider setting. This leaves the dB in the engine, and lets the config look nice by being [0f...1f] instead of [-∞...0].

@AaronVanGeffen AaronVanGeffen removed this from In Progress in Sound Engine/Mixer Jun 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Changing an existing feature slightly pending improvement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants