Skip to content

Conversation

@yonatan-mitmit
Copy link

Human perception of audio loudness is logarithmic and not linear, but the audio-volume curves in Windows don't sufficiently taper audio.

The result is that the perceived change in volume between 100%-90% is much smaller than 10%-20%. For most people this means that the volume sensitivity doesn't sound right. Motivation is explained here, though the default implementation doesn't sufficiently taper the audio

The patch adds a setting to switch the volume to use a logarithmic curve. Changes primarily in SettingService, AudioDevice, AudioDeviceSession and some Glue code in ViewModels.

@riverar
Copy link
Contributor

riverar commented Jun 24, 2018

Thanks @yonatan-mitmit, we're trying to figure out behind the scenes if we want this in the core app or as an add-on (which means we need to build up an add-on model). Bear with us.

@yonatan-mitmit
Copy link
Author

yonatan-mitmit commented Jun 25, 2018 via email

@riverar riverar added tag: reviewed status: blocked Something is preventing us from continuing on this item labels Jul 6, 2018
@riverar
Copy link
Contributor

riverar commented Jul 6, 2018

Just an update: we reviewed this item and decided against incorporation into the core product. But we do think, as mentioned before, it'd make for a great add-on (as soon as such a framework exists). Will leave this open for now so we have something to refer back to/communicate updates. Will close this for now, as it's an old PR (before we implemented the CLA bot), but it's on our internal backlog.

Thanks!

@riverar riverar closed this Jul 6, 2018
@riverar riverar removed the status: blocked Something is preventing us from continuing on this item label Jul 6, 2018
@mkryuchkov
Copy link

@riverar
Are there any updates or options for logarithmic volume curve?

@riverar riverar reopened this Mar 24, 2023
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@riverar
Copy link
Contributor

riverar commented Mar 24, 2023

Will dust off this PR and get it checked in.

@riverar
Copy link
Contributor

riverar commented Mar 24, 2023

@yonatan-mitmit Hey there! Can we reuse your implementation here?

@yonatan-mitmit
Copy link
Author

Sure.
I switched to Mac a couple of years ago so I haven't kept this patch up to date, but feel free to use it.

@riverar
Copy link
Contributor

riverar commented Mar 24, 2023

@yonatan-mitmit Thanks! Am curious, did you have any similar audio mixer needs on the macOS side? What do you use over there?

@yonatan-mitmit
Copy link
Author

@yonatan-mitmit Thanks! Am curious, did you have any similar audio mixer needs on the macOS side? What do you use over there?

Not really, the need never quite arose again here.

@yonatan-mitmit
Copy link
Author

Btw, if you ever do want to integrate, the formulas can be simplified as
dispToVolume = 1000 ^ (disp -1) // Or put differently 1/(1000 ^ (1-disp))
volToDisplay = math.log(vol) / math.log(1000) + 1 (base 1000 logarithm for the display volume).

By changing the base number (1000) you control how "aggressive" is the log curve.

@rp1231
Copy link

rp1231 commented Mar 28, 2023

@yonatan-mitmit Thanks! Am curious, did you have any similar audio mixer needs on the macOS side? What do you use over there?

There's these two that I know of :
https://www.rogueamoeba.com/soundsource/
https://staticz.com/soundcontrol/

@yonatan-mitmit
Copy link
Author

Looks cool. Thanks!

@riverar

This comment was marked as resolved.

@riverar
Copy link
Contributor

riverar commented Apr 12, 2023

Added via fcb166f, thanks @yonatan-mitmit. If any tweaks are needed, feel free to PR or yell at me.

To EarTrumpet users, this should light up in dev automatically in a few minutes.

@riverar riverar closed this Apr 12, 2023
@mkryuchkov
Copy link

mkryuchkov commented Apr 12, 2023

Hi, @riverar ! Thanks for such a lightning response.
I got dev version and found out logarithmic feature looks working upside down.

According to referred article:

However, perceived loudness varies approximately as the logarithm of the power of the audio signal, as shown on the right side of the preceding diagram. Thus, movement of the slider over an interval near the minimum setting results in a relatively large change in perceived loudness, but slider movement over an interval of the same width near the maximum setting causes a relatively small change in perceived loudness.

Current implementation not fixes the problem but make it even more noticeable: slider make a huge loudness change in 80%-100% range and almost no loudness change in 0%-80% range.
Expected fix is to compensate perception thing and make slider feel linear from perception point.

Maybe we should invert the formulae? Or have a way to change CURVE_FACTOR?

@mkryuchkov
Copy link

mkryuchkov commented Apr 12, 2023

Oh, sorry. I got it all wrong.

By the way should CURVE_FACTOR be an option? I'd like to use a less aggressive curve.

@riverar
Copy link
Contributor

riverar commented Apr 12, 2023

@mkryuchkov Yeah I struggled with the aggressiveness of the curve too, and even thought it was backwards too. So don't feel bad, haha.

I think we're currently using the x4 approximation documented here:
https://www.dr-lex.be/info-stuff/volumecontrols.html#ideal2:~:text=1e%2D3-,6.908,-x4

I experimented with x3 and didn't see a big improvement so figured my brain is ruined by linear sliders and left it alone. Happy to make any recommended community changes here!

private const float CURVE_FACTOR = 6.908f;
public static int ToVolumeInt(this float val)
{
return Convert.ToInt32(Math.Round(val * 100, MidpointRounding.AwayFromZero));
}
public static float Bound(this float val, float min, float max)
{
return Math.Max(min, Math.Min(max, val));
}
public static float ToLogVolume(this float val)
{
return ((float)(Math.Exp(CURVE_FACTOR * val) / Math.Exp(CURVE_FACTOR))).Bound(0, 1f);
}
public static float ToDisplayVolume(this float val)
{
return ((float)(Math.Log(val * Math.Exp(CURVE_FACTOR)) / CURVE_FACTOR)).Bound(0, 1f);
}

@mkryuchkov
Copy link

@riverar
I fooled around with demo player and EarTrumpet and more I played more handy current implementation seems to me.

I assume it depends on how loud my audio device goes. I'm used to "keep neighbors happy" sound level so never go upper 40-50 dB. Formulae presented is for 60 dB range.

90 dB(A) with a background noise level of 30 dB(A) hence a useful dynamic range of 60 dB, is probably a good guess.

Sooo, I guess it would be okay for most of the users. At least I get used to it already.

The only thing I would be happy to have is to set scroll to change by 1 percent, not 2. Two percent make significant change for one step using logarithmic curve.

P.S. Scroll on hover option is awesome!

@riverar
Copy link
Contributor

riverar commented Apr 12, 2023

Maybe we can switch to the 50dB curve and if folks have louder needs, we can add configurability.

@mkryuchkov
Copy link

Worth a try. Configurability sounds like perfect solution.
I'm happy to test as soon as changes come.

// me becomes a fan of your app

@riverar
Copy link
Contributor

riverar commented Apr 12, 2023

@mkryuchkov restart (dev) twice and you should pick up 2.2.2.35

@mkryuchkov
Copy link

@riverar got update, works much smoother now. Feels nice to scroll even scroll step is two percent.

Thank you very much!
This app should be default mixer on Windows. At least to be included into PowerToys.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants