-
Notifications
You must be signed in to change notification settings - Fork 425
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 decibel scaling for volume control #6490
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can make this direction work.
Audio.Volume.Scale(); | ||
Audio.VolumeSample.Scale(); | ||
Audio.VolumeTrack.Scale(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be required. It will happen on BindWith
.
osu.Framework/Audio/VolumeScaler.cs
Outdated
|
||
namespace osu.Framework.Audio | ||
{ | ||
public class VolumeScaler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be renamed to BindableVolume
or similar. VolumeScaler
reads really bad as a class name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also please xmldoc this whole class. Every public property and the class itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also probably seal it. I don't think a framework consumer should be attempting to make a custom implementation of this ever.
osu.Framework/Audio/VolumeScaler.cs
Outdated
private const double ln_ten = 2.302585092994045684017991454684364208; | ||
private const double k = ln_ten / 20; | ||
|
||
public readonly BindableNumber<double> Real; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe call these Linear
and Logarithmic
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this "real" one looks like it should not be externally mutable. should either be IBindableNumber<double>
, or if you're gonna keep it mutable, it should be synced both ways (changing "real" should also change "scaled")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this "real" one looks like it should not be externally mutable
I was hoping it would remain mutable so that we aren't deciding on a developers' behalf which they choose to use. Both may have valid use cases, depending on how you're audio engineeringing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, as long as it's not possible to break the instances of this into complete nonsense by setting both to random values and putting it in a completely invalid state
osu.Framework/Audio/VolumeScaler.cs
Outdated
private const double ln_ten = 2.302585092994045684017991454684364208; | ||
private const double k = ln_ten / 20; | ||
|
||
public readonly BindableNumber<double> Real; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this "real" one looks like it should not be externally mutable. should either be IBindableNumber<double>
, or if you're gonna keep it mutable, it should be synced both ways (changing "real" should also change "scaled")
Co-authored-by: Bartłomiej Dach <[email protected]>
`ln_ten` was really just there to clarify what the numeric literal represented.
osu.Framework/Audio/VolumeScaler.cs
Outdated
@@ -11,8 +11,7 @@ public class VolumeScaler | |||
public const double MIN = -60; | |||
public const double STEP = 0.5; | |||
|
|||
private static readonly double ln_ten = Math.Log(10); | |||
private const double k = ln_ten / 20; | |||
private const double k = Math.Log(10) / 20; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constant declarations must use compile-time constants on the rhs of the assignment. this can't work with const
, it must be static readonly
. are you even compiling this code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kinda still want k
to be const
. I guess that's why I went with the numeric literal to begin with.
const
will get embedded into the IL code wherever it's used, whereas static readonly
requires a memory lookup each time it's accessed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please actually profile this and get back to me. i am 99% confident this will not be measurable. i prefer non-obfuscated code over pedantically marginal performance 'gains'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you like, I can change the name of the variable from ln_ten
to something that's more readable.
But if the code is decently readable either way, why use the slower version, regardless of how pedantically marginal the difference may be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is no solution with the const that i would consider more readable than just writing out what the number is
but i also have no time nor patience to continue this discussion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make is static readonly
or close the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Certainly. I apologize if I came across as confrontational. I'm just trying to have a discussion about your coding philosophies and the reasons behind them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's pretty simple: storing one value to memory that is going to take up 8 bytes is not a concern and shouldn't lead to discussion. By using it we don't have to figure out what a random constant decimal number is and check whether it's correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I see what you're saying. I figured if I just gave the variable a good enough name, describing what it's supposed to represent, then everything would be fine, but at the end of the day, there's still this big ugly numeric literal sitting in the middle of the code and it's a bit unsightly.
`ln_ten` needs to also be const in order to be assigned to `k`
public double Value | ||
{ | ||
get => Real.Value; | ||
set => Scaled.Value = realToScaled(value); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in what world is it sane to have a property return values on a different scale than the one used to set the value
it should not be the case that after you set a property's value, you read it back and get a completely different number. that is nonsensical
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should probably be able to get rid of that. I think at first, I wasn't as explicit about whether I was using the real value or the scaled value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, so it does sorta make sense. We don't want to assign directly to Real
. Instead, we want to assign to Scaled
only, and whenever we do, that triggers a BindValueChanged
function, and that's where Real
gets assigned. So assigning to Scaled
effectively assigns to both of them.
Real
doesn't have an equivalent BindValueChanged
function as that would result in an infinite loop.
Also, instead of assigning directly to Scaled
, sometimes we want to assign a linear value, but it has to go through Scaled
first, so the setter's job is to first translate the linear value into a logarithmic value.
I'll probably still get rid of the getter, as that is a bit confusing, and I think it's just there for convenience sake, but it's better to be explicit.
Getter can be replaced with explicit calls to Real Setter should instead be a function with a clearer name.
Any reason this was closed? I'd genuinely hope you aren't that opposed to the |
Addresses ppy/osu#26731
Meant to work alongside ppy/osu#31493