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

Allow editing AudioStreamPlayer and audio bus volumes in linear percentages instead of decibels #1884

Open
mindinsomnia opened this issue Nov 24, 2020 · 10 comments

Comments

@mindinsomnia
Copy link

Describe the project you are working on:
It's not really relevant to this general usability improvement suggestion.

Describe the problem or limitation you are having in your project:
It's a usability suggestion so it's not a limitation or a problem, it's just something that will make using Godot more comfortable and enjoyable for users.

Describe the feature / enhancement and how it helps to overcome the problem or limitation:
An option to choose between two different units for volume sliders in Godot. Db (as in Decibels) or Linear Scale, which is a sliding value between 0% and 100%.

I have read the Godot manual and I understand it's point of view expressed that it is a good idea in the long term to learn how to work with Decibels for professional audio work. However in my opinion it would be a usability improvement to offer the user the ability to choose between using Decibels and Linear Scale for the following reasons:

  1. As the manual acknowledges, this is something most users are not going to be familiar with. A Godot user's first experience should be as intuitive as possible, and linear scale is the most intuitive volume control for most people.

  2. In many instances, particularly for first time users of Godot, or indie game developers, or users who are new to game development in general, the benefits of working in Decibels may not apply at all. One of the mentioned benefits of working with Decibels in the manual is "will allow you to communicate better with audio professionals", but for a indie game developer learning Godot for the first time, they would be lucky to even know an audio professional. More than likely, most beginners will be adding simple sound effects to actions in their game, clicks to menu actions, or a 'tada!' success sound effect to winning a level, and a simple volume slider would be more than enough for that task.

  3. Plenty of software offers a choice between units that represent the same thing in different ways. Design software offers the choice between working in pixel measurements or millimeters/inches/etc. In Blender camera field of view can be specified in either angles (something game developers would be more accustomed to) or millimeters (something photographers would be more accustomed to).

vSLXGO0u0A

  1. In Game Design, we often teach players new gameplay mechanics intuitively through level design, introducing things in a way that allows a player to organically learn them. This is one of the benefits of providing a simple switch to toggle between Decibels and Linear Scale. Providing a choice between both would actually help promote and teach decibels to users and not even require them to read a manual to understand them. New users will be able to immediately control the volume of their sounds, and be able to switch between the units to understand how different values in each scale correspond to each other. A simple hover text hint on the dropdown could even make mention that decibels are the recommended way of working. This allows the user to learn about decibels without being confused or needing to read a manual, and use a linear scale slider initially as they are learning.

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
I propose that internally, Godot always uses Decibels, but optionally can present either a Decibel slider, or Linear Scale slider.

The result is a simple cosmetic change on how the option actually looks in the UI:

Before:
godot volume slider

After:
godot-volume-slider2

Internally, when in Linear Scale mode, the slider's value is converted to Decibels and stored in the Decibel property. Hence when the user switches between units, the conversion is automatic.

I think in addition to the UI option, this should be replicated in the API for AudioStreamPlayer.

Right now already AudioStreamPlayer has a 'volume_db' property, all that would need to be added is a 'volume_linear' property or perhaps even just 'volume', and internally when it's set the value could be automatically converted into decibel scale and stored in volume_db.

If this enhancement will not be used often, can it be worked around with a few lines of script?:
N/A

Is there a reason why this should be core and not an add-on in the asset library?:
N/A

@Calinou
Copy link
Member

Calinou commented Nov 24, 2020

I'm not sure if this is worth the additional work. For instance, there are already two ways to edit the gravity of a RigidBody – using the "mass" and "weight" properties. The fact that you can see both properties at the same time introduces more confusion than anything else. This would have to be revised first before we can consider adding support for more properties that can be edited in different ways.

Technically, it could be done by adding a property hint that indicates that a property is to be specified using decibels. Then we can add an editor setting that forces all decibels to be specified using a linear scale instead. (I don't think this should be specified in the node itself, as this is clearly an user preference.)

This way of working would be less confusing, but it'd also require adding a property hint for every property that may be specified in multiple ways – be it mass/weight, FOV in degrees/millimeters, volume in decibels/linear scale…

Also, if we consider this to be a documentation issue, we can amend the class reference to quickly explain how decibel volumes work.

@Calinou Calinou changed the title Usability Improvement: Optional Volume Units, Db/Linear Scale Allow editing AudioStreamPlayer and audio bus volumes in linear percentages instead of decibels Mar 9, 2021
@wareya
Copy link

wareya commented Aug 17, 2021

As someone who's actually familiar with audio programming, and intimately familiar with sound design and music production, not being able to read or modify raw amplitude directly is basically unthinkable. Decibels are not how perceived volume works, they're part of how mixing works, and being forced to go through decibels when doing things like hand-writing background music crossfading is just plain wrong.

For the hand-written background music crossfading example, the two tracks have to meet at -9db, -6db, or -3db, depending on what approach you're doing. In terms of raw amplitude, crossfading like this is a simple linear transition with an exponent thrown on top. And having to write extra code to convert from amplitude to decibels on top of that is bizarre. And don't say "just do the fade in decibels", that would either be straight up wrong or involve a weird mapping curve that approximates doing it in linear amplitude in the first place. Incidentally, the -6db version of this is what you want to do if you're doing that dynamic music mixing thing where you have multiple different copies of the same track with different instrumentation and blend between them based on what's happening in the gameplay. That's an easy example why being able to do this correctly on the game logic side of things (not the engine side, where it would be technical debt) is actually meaningfully useful, not just theoretically useful, and you shouldn't have to go through decibels to do it.

There's a similar problem if you somehow manage to get control of left and right channel volumes independently, and program audio emitter panning and distance attenuation from scratch instead of using the engine's spatialization features (which you very well might want to do if you're doing something like making a competitive FPS where exactly how panning and distance attenuation work are a core part of game balance). There are several different "panning laws" (different functions for converting panning values into per-channel volume), but in code they're all best represented with amplitude curves, not decibel curves, because decibels are for audio mixing and audio analysis, not audio programming. There are likewise also multiple different approaches to distance attenuation, which is less interesting for 3d games (where you're obligated to use inverse square falloff) but very interesting for 2d games (where you can do pretty much anything, and any approach you could think of is valid). I used to work on a competitive 2d shooter called Gang Garrison 2 where the specific distance attenuation curve that offscreen sounds had was integral to how the game's balance worked, and if I hypothetically wanted to remake that game in godot, replicating that attenuation curve would be a valid thing to worry about.

There are a lot of things of this nature that are just far easier and more correct to do in amplitude than decibels. I don't need to be told how decibels work. I already know how they work, what they're for, and where and why they're used. They're just not a drop-in replacement for raw amplitude, you need to get your hands dirty with raw amplitude eventually if you do anything sufficiently interesting with volume values. And doing all of that on top of code that maps to decibels just to map back to amplitude later inside the engine is bizarre.

@jitspoe
Copy link

jitspoe commented Nov 7, 2021

Honestly, I'd just scrap the decibels and use direct linear volume adjustment if we want to have just 1. I'm always using linear2db() to set values, which the engine then converts back to linear to do the math anyway, so it seems like 2 unnecessary steps when almost no devs think in db anyway.

Also, the decibels aren't even quite correct -- I think k the engine is set up so -40db is 0 in linear, when it should be -infinity, so somebody could try to set something to, like, -50db to get 0.00001 and actually be getting 0 (unlikely, but you never know). I feel like, for the vast majority of people, using linear values (ex: I want to fade in something, so I go from 0 to 1) is far more straightforward than using decibels. I'm not even sure how you'd do that in db directly. I always use linear2db, but it took a while for me to find that function initially since it's a global function, not like a setter function on the audio objects themselves.

Also, there is some inconsistency in naming -- some things use unit_db and others use volume_db. I wouldn't change this for 3.x, but it might be worth switching to linear values for 4.x.

@Calinou Calinou added this to the 4.0 milestone Nov 7, 2021
@Calinou
Copy link
Member

Calinou commented Jan 11, 2022

Now that godotengine/godot#50009 has been merged, it should be possible to implement this as an editor helper.

@aaronfranke aaronfranke modified the milestones: 4.0, 4.x Feb 24, 2023
@aXu-AP
Copy link

aXu-AP commented Oct 17, 2023

Now that godotengine/godot#50009 has been merged, it should be possible to implement this as an editor helper.

Aand that didn't age well, in the end rotation_degrees needed to be reintroduced altough I think the case was weaker than this (I mean, radians and degrees are at least linearly related).
I think volume_linear should be exposed as a property, just to be able use it with animations and tweens. I have exactly zero projects which has audio and doesn't have the following script or similiar just for this reason:

@tool
extends AudioStreamPlayer
@export_range(0, 2) var volume_linear : float = 1.0:
	set(value):
		volume_db = linear_to_db(value)
	get:
		return db_to_linear(volume_db)

I mean, it works and it isn't much code, but just the fact that it's required for working with audio through built-in tools is a bit baffling. Or is there some other possibility for fading sound with animationplayer or tween through volume_db? Some specific easing values?

@shak2
Copy link

shak2 commented May 31, 2024

How about making it default to a linear scale (so it works nicely in animations and tweens), and then have a tickbox in the inspector to change it to decibal scale for the audio professionals to use?

@Calinou
Copy link
Member

Calinou commented May 31, 2024

How about making it default to a linear scale (so it works nicely in animations and tweens)

We can't change the default behavior to avoid breaking compatibility with existing projects. All we can do is implement @aXu-AP's suggestion, which adds a new property while preserving the existing one's behavior. The decibel-based property can then be hidden from the inspector as the linear one would replace it (they represent the same underlying value).

@shak2
Copy link

shak2 commented May 31, 2024

Save the change for Godot 5 so it doesn't affect 4 projects.

We should never shy away from a user useful change for fear of breaking projects. Better to make the change sooner rather than later when even more historic projects will exist. It only gets worse until it's fixed.

@Zireael07
Copy link

You know Godot 5 is years away at this point?

@dalexeev
Copy link
Member

We could add an editor setting to switch between dB and Linear % plus an inspector plugin that would replace the field if Linear % is selected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants