Commit 5e98fc50 authored by Rémi Denis-Courmont's avatar 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.
parent 1433d065
...@@ -117,6 +117,7 @@ struct aout_sys_t ...@@ -117,6 +117,7 @@ struct aout_sys_t
LONG refs; LONG refs;
unsigned ducks; unsigned ducks;
float gain; /**< Current software gain volume */
wchar_t *device; /**< Requested device identifier, NULL if none */ wchar_t *device; /**< Requested device identifier, NULL if none */
float volume; /**< Requested volume, negative if none */ float volume; /**< Requested volume, negative if none */
...@@ -197,9 +198,20 @@ static void Flush(audio_output_t *aout, bool wait) ...@@ -197,9 +198,20 @@ static void Flush(audio_output_t *aout, bool wait)
static int VolumeSet(audio_output_t *aout, float vol) static int VolumeSet(audio_output_t *aout, float vol)
{ {
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
float gain = 1.f;
vol = vol * vol * vol; /* ISimpleAudioVolume is tapered linearly. */ vol = vol * vol * vol; /* ISimpleAudioVolume is tapered linearly. */
if (vol > 1.f)
{
gain = vol;
vol = 1.f;
}
aout_GainRequest(aout, gain);
EnterCriticalSection(&sys->lock); EnterCriticalSection(&sys->lock);
sys->gain = gain;
sys->volume = vol; sys->volume = vol;
WakeConditionVariable(&sys->work); WakeConditionVariable(&sys->work);
LeaveCriticalSection(&sys->lock); LeaveCriticalSection(&sys->lock);
...@@ -923,16 +935,13 @@ static HRESULT MMSession(audio_output_t *aout, IMMDeviceEnumerator *it) ...@@ -923,16 +935,13 @@ static HRESULT MMSession(audio_output_t *aout, IMMDeviceEnumerator *it)
hr = ISimpleAudioVolume_GetMasterVolume(volume, &level); hr = ISimpleAudioVolume_GetMasterVolume(volume, &level);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
aout_VolumeReport(aout, cbrtf(level)); aout_VolumeReport(aout, cbrtf(level * sys->gain));
else else
msg_Err(aout, "cannot get master volume (error 0x%lx)", hr); msg_Err(aout, "cannot get master volume (error 0x%lx)", hr);
level = sys->volume; level = sys->volume;
if (level >= 0.f) if (level >= 0.f)
{ {
if (level > 1.f)
level = 1.f;
hr = ISimpleAudioVolume_SetMasterVolume(volume, level, NULL); hr = ISimpleAudioVolume_SetMasterVolume(volume, level, NULL);
if (FAILED(hr)) if (FAILED(hr))
msg_Err(aout, "cannot set master volume (error 0x%lx)", 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) ...@@ -1091,6 +1100,7 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
assert (sys->stream == NULL); assert (sys->stream == NULL);
sys->stream = s; sys->stream = s;
aout_GainRequest(aout, sys->gain);
return 0; return 0;
} }
...@@ -1128,6 +1138,7 @@ static int Open(vlc_object_t *obj) ...@@ -1128,6 +1138,7 @@ static int Open(vlc_object_t *obj)
sys->ducks = 0; sys->ducks = 0;
sys->device = default_device; sys->device = default_device;
sys->gain = 1.f;
sys->volume = -1.f; sys->volume = -1.f;
sys->mute = -1; sys->mute = -1;
InitializeCriticalSection(&sys->lock); InitializeCriticalSection(&sys->lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment