[vlc-devel] [RFC PATCH 1/2] mmdevice: reflect the state of Sndvol slider
Thomas Guillem
thomas at gllm.fr
Thu Apr 5 11:24:13 CEST 2018
Lot of confusions when reading the MSDN documentation about volume change.
Cf. "Session Volume Controls" [1], "Audio-Tapered Volume Controls" [2] and
"Endpoint Volume Controls" [3].
By reading the following [1]:
> To produce a linear relationship between perceived loudness and slider
> position, the application must define a nonlinear relationship between the
> volume level v and the slider position.
We can conclude that VLC should use the IAudioEndpointVolume API to control the
volume in an audio-tapered way.
But [3]:
> As a general rule, applications should avoid using the IAudioEndpointVolume
> interface to control the volume levels of shared-mode streams.
And [1]:
> As an option, an application window can display a volume slider. The
> application slider should reflect the state of the corresponding Sndvol
> slider at all times.
> To support this behavior, WASAPI implements the ISimpleAudioVolume interface.
> When the user moves the application slider, the application calls the
> ISimpleAudioVolume::SetMasterVolume method to adjust the session volume level
> accordingly.
This means that our application should use the ISimpleAudioVolume API and have
a linear relation between the slider and the volume API (therefore, we should
remove the vol * vol * vol that this patch is doing).
But [2]:
> The following interfaces use linear-tapered curves for their volume settings:
> ISimpleAudioVolume
So ISimpleAudioVolume is linear-tapered and IAudioEndpointVolume is
audio-tapered. For the user, we would prefer a audio-tapered volume.
Then, we have 4 choices:
- a/ Keep the code as it is. I don't like it because it doesn't respect the
Sndvol slider, and the first 60% on the slider doesn't change the loudness
much (very hard to hear an audible difference with low % values).
- b/ Do what this patch is doing. the relation between the slider and the
loudness is still not linear but it respect the Sndvol slider. I tested with
few samples: changing volume feels way more natural (the loudness change a
lot between 0 and 50% and much less after 90%).
- c/ Use IAudioEndpointVolume, but it's not recommended for shared streams as
it changes the volume for every apps using a shared stream.
- d/ Keep using ISimpleAudioVolume but with the volume table added from
Windows XP SP2, cf. [4]. The slider will be linear with the loudness but
won't respect the Sndvol slider.
[1] https://msdn.microsoft.com/fr-fr/library/windows/desktop/dd316769(v=vs.85).aspx
[2] https://msdn.microsoft.com/fr-fr/library/windows/desktop/dd370798(v=vs.85).aspx
[3] https://msdn.microsoft.com/en-us/library/windows/desktop/dd370839(v=vs.85).aspx
[4] https://download.microsoft.com/download/e/b/a/eba1050f-a31d-436b-9281-92cdfeae4b45/voltable.docx
---
modules/audio_output/mmdevice.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/modules/audio_output/mmdevice.c b/modules/audio_output/mmdevice.c
index c2f190f01f..c8b48fde41 100644
--- a/modules/audio_output/mmdevice.c
+++ b/modules/audio_output/mmdevice.c
@@ -178,15 +178,13 @@ static int VolumeSetLocked(audio_output_t *aout, float vol)
aout_sys_t *sys = aout->sys;
float gain = 1.f;
- vol = vol * vol * vol; /* ISimpleAudioVolume is tapered linearly. */
-
if (vol > 1.f)
{
gain = vol;
vol = 1.f;
}
- aout_GainRequest(aout, gain);
+ aout_GainRequest(aout, gain * gain * gain);
sys->gain = gain;
sys->requested_volume = vol;
@@ -982,7 +980,7 @@ static HRESULT MMSession(audio_output_t *aout, IMMDeviceEnumerator *it)
hr = ISimpleAudioVolume_GetMasterVolume(volume, &level);
if (SUCCEEDED(hr))
- aout_VolumeReport(aout, cbrtf(level * sys->gain));
+ aout_VolumeReport(aout, level * sys->gain);
else
msg_Err(aout, "cannot get master volume (error 0x%lx)", hr);
--
2.11.0
More information about the vlc-devel
mailing list