[vlc-commits] mmdevice: use craptastic software gain
Rémi Denis-Courmont
git at videolan.org
Wed Nov 12 21:12:12 CET 2014
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Nov 12 21:03:13 2014 +0200| [5e98fc504ac9c0569ea4d0e00608db7b8088b2dc] | committer: Rémi Denis-Courmont
mmdevice: use craptastic software gain
The same caveats apply as for Windows legacy (and ALSA) outputs:
- Change latency is high and noticeable.
- Change between less than 100% and more than 100% occurs in two steps.
- Non-linear formats are not supported at all.
- Integer formats are prone to clipping/saturation.
- Floating formats may hit Windows peak protection, sounding awful.
In other words, it does not work properly and it never will. This will
be removed once minimum and maximum volumes are exposed properly.
As meager consolation, there are two advantages over endpoint volume:
- The code is much simpler.
- Other audio sessions are not affected.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=5e98fc504ac9c0569ea4d0e00608db7b8088b2dc
---
modules/audio_output/mmdevice.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/modules/audio_output/mmdevice.c b/modules/audio_output/mmdevice.c
index a7871c5..d9d3573 100644
--- a/modules/audio_output/mmdevice.c
+++ b/modules/audio_output/mmdevice.c
@@ -117,6 +117,7 @@ struct aout_sys_t
LONG refs;
unsigned ducks;
+ float gain; /**< Current software gain volume */
wchar_t *device; /**< Requested device identifier, NULL if none */
float volume; /**< Requested volume, negative if none */
@@ -197,9 +198,20 @@ static void Flush(audio_output_t *aout, bool wait)
static int VolumeSet(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);
+
EnterCriticalSection(&sys->lock);
+ sys->gain = gain;
sys->volume = vol;
WakeConditionVariable(&sys->work);
LeaveCriticalSection(&sys->lock);
@@ -923,16 +935,13 @@ static HRESULT MMSession(audio_output_t *aout, IMMDeviceEnumerator *it)
hr = ISimpleAudioVolume_GetMasterVolume(volume, &level);
if (SUCCEEDED(hr))
- aout_VolumeReport(aout, cbrtf(level));
+ aout_VolumeReport(aout, cbrtf(level * sys->gain));
else
msg_Err(aout, "cannot get master volume (error 0x%lx)", hr);
level = sys->volume;
if (level >= 0.f)
{
- if (level > 1.f)
- level = 1.f;
-
hr = ISimpleAudioVolume_SetMasterVolume(volume, level, NULL);
if (FAILED(hr))
msg_Err(aout, "cannot set master volume (error 0x%lx)",
@@ -1091,6 +1100,7 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
assert (sys->stream == NULL);
sys->stream = s;
+ aout_GainRequest(aout, sys->gain);
return 0;
}
@@ -1128,6 +1138,7 @@ static int Open(vlc_object_t *obj)
sys->ducks = 0;
sys->device = default_device;
+ sys->gain = 1.f;
sys->volume = -1.f;
sys->mute = -1;
InitializeCriticalSection(&sys->lock);
More information about the vlc-commits
mailing list