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

Require effective media volume range to be logarithmic #5501

Open
LeoWattenberg opened this issue May 1, 2020 · 14 comments
Open

Require effective media volume range to be logarithmic #5501

LeoWattenberg opened this issue May 1, 2020 · 14 comments

Comments

@LeoWattenberg
Copy link

Hello.
Currently, the standard explicitly doesn't specify what scaling should be used for the effective media volume range (ie for volume sliders):

An element's effective media volume is determined as follows:
[...]

  • Return volume, interpreted relative to the range 0.0 to 1.0, with 0.0 being silent, and 1.0 being the loudest setting, values in between increasing in loudness. The range need not be linear. The loudest setting may be lower than the system's loudest possible setting; for example the user could have set a maximum volume.

https://html.spec.whatwg.org/multipage/media.html#effective-media-volume, emphrasis added.
The same explicit non-specification can be found in the HTML5.3 WD.

Even though it's not specified, browsers currently seem to use linear scaling, presumably because it's easier to build. This however leads to a bad UX, as ears are perceiving volume logarithmically. Consider the following example:

Here is a diagram of the volume in dB the video 3FBijeNg_Gs has, at various volume percentages (blue).
As you can see, it peaks at -13.9dB, so for us, 100%=-13.9dB, so far, so good. But look at what moving the slider does:
If I move it just barely, the 9% from 1%→10%, the volume increases by 22dB, increasing the power over 100x, increasing the sound pressure tenfold.
But if I move it all the way from 50% → 100%, it only increases by 6dB, only increasing the power 4x and doubling the sound pressure.

Fig 1: Volume response in dB per volume slider percent

This makes it super frustrating to dial in the proper volume of the sound on websites, as the right half of the volume slider gives you a super granular control where moving it barely does anything, while the left half may crank up the volume by 10dB at a time just by moving the volume slider by a few pixels.

With a logarithmic response, things get a lot more balanced (orange line in the diagram): Here, the 50% mark is some 20dB away from both the 100% and 1% mark, making the volume slider work more like actual mixing consoles. Moving the slider by n pixels now consistently increases or decreases the volume by n * constant_factor dB.

These types of fixes can of course be implemented by the individual websites, browsers or via user extensions, but then the behavior of one of the most basic media controls changes significantly from website to website and browser to browser, which can be a good reason against moving to a logarithmic response. For example, when YouTube transitioned away from Flash (in which they did use a logarithmic response), they decided to keep things consistent with browsers and now are on linear response.

Because of that, I propose specifying this directly in the HTML standard, so that this behavior is consistent across the web while also being more user friendly than it currently is.

@domenic
Copy link
Member

domenic commented May 1, 2020

I don't think this kind of thing, translating UI into auditory levels, is in the scope of the HTML Standard. You'd be best filing this issue on the relevant browser issue trackers.

(For example, the HTML Standard doesn't actually require that audio/video elements produce audio at all.)

@pshaughn
Copy link
Contributor

pshaughn commented May 1, 2020

Requiring browsers to change their existing scale would definitely be a big, breaking change. I hadn't realized this was unspecified and as a page author I've relied on linearity.

@LeoWattenberg
Copy link
Author

Fwiw, I've been using UI here as a shorthand for the actual values between 0 and 1 that those UI sliders represent. And with the standard explicitly saying that it's not specifying the scale, I think the standard can explicitly specify the scale to get consistent browser behavior.

@LeoWattenberg
Copy link
Author

@jernoble
Copy link

jernoble commented May 2, 2020

The HTMLMediaElement.volume property, IMO, is a convenience to allow pages to provide a custom volume control UI. As such, UAs are free to interpret the volume property the same way they would any other volume slider provided by the platform, and the behavior of that page-provided volume slider will therefore match other volume UI provided elsewhere on the same platform, including as @LeoWattenberg said by limiting the maximum effective volume (represented by volume = 1.0), or as @domenic says by ignoring the volume property entirely!

If pages need precise, defined control over media element output (e.g., to match perceived volumes of two separate media elements), they can use the Web Audio API and the GainNode, which is defined as linear.

@carlosrafaelgn
Copy link

I agree with @pshaughn .

I believe it would be better to simply make it clear in the spec that the volume is on a linear scale, as it has been for quite some time now, avoiding breaking existing web apps and, at the same time, guaranteeing to developers that it will never change and that they can create their own UI controls to apply a logarithmic scale as they wish.

Making volume treat the input range of [0, 1] in a logarithmic way, out of the box, could, in fact, be messy...

For example, the decibel range used. If 1 maps to -0 dB, then 0.5 maps to ... The answer is not clear, as it could be mapped to anything, depending on the actual range used by the browser. One could assume 0.5 maps to -10 dB, others could assume it maps to -20 dB and so on.

Forcing the browser to apply a range of, for example, 40 dB, would translate into a mapping more or less like this:

  • 0: -infinity dB
  • 0.0000...0001: -39.99999... dB
  • 1: -0 dB

Now... is a range of 40 dB OK?

For some use cases a range of 40 dB would be OK, indeed, but... What if someone desires a range of only 20 dB, or perhaps a range of 80 dB, 100 dB... How knows?

If the browser used a range of x decibels but the developer needed a range < x decibels, it could be fixed. On the other hand, if the developer needed a range > x decibels, it would be impossible to fix! 😱

The way I see, forcing the volume to be on a logarithmic scale could cause more trouble than what it could solve. 😳

Again, I believe it should only be made clear in the spec that volume is on a linear scale and let developers do their jobs, creating UI controls as they wish so. 😊

Regarding the UI control used by the browser to render plain audio / video tags, perhaps it should be better to leave up to browser developers to apply a logarithmic mapping between the control and the actual volume property (if it's already not being done by now). But that's a different subject... 😅

@pshaughn
Copy link
Contributor

pshaughn commented Aug 1, 2021

I wouldn't say no to also having a convenience getter/setter that translates the real linear gain to and from a decibels value, as long as the existing attribute continues to work the way it's been working.

@carlosrafaelgn
Copy link

Indeed! That is an excellent idea! 😊

Creating a new attribute, something like volumeDB (or anything with a better name), internally linked to volume, so that when we set volumeDB to -3, for example, automatically changes volume to 0.7079457843841379 and vice-versa.

@LeoWattenberg
Copy link
Author

That'd work for me, too! Should I edit the OP of this issue and the title, or start a new issue, or something else?

@LeoWattenberg
Copy link
Author

https://www.dr-lex.be/info-stuff/volumecontrols.html this probably is relevant to this discussion too

@carlosrafaelgn
Copy link

That'd work for me, too! Should I edit the OP of this issue and the title, or start a new issue, or something else?

Sorry for not having replied back then... It's just that I don't know what could be the best thing to do in this case... 😅

@gsuberland
Copy link

Did this ever go anywhere, or is the behaviour still undefined with no way to specify a perceptual attenuation?

@LeoWattenberg
Copy link
Author

I don't believe there's been any movement on this. That said, Discord since has made an implementation of it: https://github.com/discord/perceptual

@carlosrafaelgn
Copy link

I believe the spec is leaving the control in a linear scale on purpose, so, as I mentioned here, developers could choose the desired range in dB that best suits their needs (something the browser could never do for us, because each application has different requirements).

But..... Given that GainIndB = 20 * log10(Amplitude) and Amplitude = 10 ^ (GainIndB/20), it should be fairly simple to implement a proper logarithmic control directly in the UI. In fact, this is exactly what I do in my own web player. 😊

I do not have inside information (W3C, WHATWG and so on...). But this is what I believe, considering this issue has been around for over 3 years now. 😅

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

No branches or pull requests

7 participants