[vlc-devel] [PATCH 1/2] wasapi: implement the stream volume callback

Rémi Denis-Courmont remi at remlab.net
Sun Mar 22 13:35:06 CET 2015


---
 modules/audio_output/wasapi.c | 45 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/modules/audio_output/wasapi.c b/modules/audio_output/wasapi.c
index c9c490c..3b9d5f3 100644
--- a/modules/audio_output/wasapi.c
+++ b/modules/audio_output/wasapi.c
@@ -26,6 +26,7 @@
 #define COBJMACROS
 #define CONST_VTABLE
 
+#include <math.h>
 #include <stdlib.h>
 #include <assert.h>
 #include <audioclient.h>
@@ -222,6 +223,42 @@ static HRESULT Flush(aout_stream_t *s)
     return hr;
 }
 
+static HRESULT VolumeSet(aout_stream_t *s, float vol)
+{
+    aout_stream_sys_t *sys = s->sys;
+    void *pv;
+    UINT32 count;
+    HRESULT hr;
+
+    assert(isfinite(vol) && vol >= 0.f && vol <= 1.f);
+
+    hr = IAudioClient_GetService(sys->client, &IID_IAudioStreamVolume, &pv);
+    if (FAILED(hr))
+    {
+        msg_Err(s, "cannot get clock (error 0x%lx)", hr);
+        return hr;
+    }
+
+    IAudioStreamVolume *svol = pv;
+
+    hr = IAudioStreamVolume_GetChannelCount(svol, &count);
+    if (SUCCEEDED(hr))
+    {
+        float volumes[count];
+
+        for (unsigned i = 0; i < count; i++)
+            volumes[i] = vol;
+
+        hr = IAudioStreamVolume_SetAllVolumes(svol, count, volumes);
+    }
+
+    IAudioStreamVolume_Release(svol);
+
+    if (FAILED(hr))
+        msg_Err(s, "cannot set stream volume (error 0x%lx)", hr);
+    return hr;
+}
+
 
 /*** Initialization / deinitialization **/
 static const uint32_t chans_out[] = {
@@ -436,7 +473,13 @@ static HRESULT Start(aout_stream_t *s, audio_sample_format_t *restrict fmt,
     s->play = Play;
     s->pause = Pause;
     s->flush = Flush;
-    s->set_volume = NULL;
+    /* The VolumeSet() is not intrinsically limited to floating point. However
+     * VLC gain does not work with integers due to clipping, and does not work
+     * at all with non-linear formats. */
+    if (sys->format == VLC_CODEC_FL32 || sys->format == VLC_CODEC_FL64)
+        s->set_volume = VolumeSet;
+    else
+        s->set_volume = NULL;
     return S_OK;
 error:
     if (sys->client != NULL)
-- 
2.1.4




More information about the vlc-devel mailing list