[vlc-devel] [PATCH] winstore: handle volume/mute in the winstore audio output

Steve Lhomme robux4 at videolabs.io
Mon Feb 8 16:48:21 CET 2016


From: Steve Lhomme <robUx4 at gmail.com>

---
 modules/audio_output/mmdevice.h | 12 +++++++++
 modules/audio_output/wasapi.c   | 54 +++++++++++++++++++++++++++++++++++++++++
 modules/audio_output/winstore.c | 37 ++++++++++++++++++++++++++++
 3 files changed, 103 insertions(+)

diff --git a/modules/audio_output/mmdevice.h b/modules/audio_output/mmdevice.h
index 51f5e42..68f506c 100644
--- a/modules/audio_output/mmdevice.h
+++ b/modules/audio_output/mmdevice.h
@@ -35,6 +35,8 @@ struct aout_stream
     HRESULT (*play)(aout_stream_t *, block_t *);
     HRESULT (*pause)(aout_stream_t *, bool);
     HRESULT (*flush)(aout_stream_t *);
+    HRESULT (*set_volume)(aout_stream_t *,float);
+    HRESULT (*mute)(aout_stream_t *,bool);
 
     struct
     {
@@ -86,6 +88,16 @@ static inline HRESULT aout_stream_Flush(aout_stream_t *s, bool wait)
         return (s->flush)(s);
 }
 
+static inline HRESULT aout_stream_SetVolume(aout_stream_t *s, float volume)
+{
+    return s->set_volume ? (s->set_volume)(s, volume) : E_POINTER;
+}
+
+static inline HRESULT aout_stream_Mute(aout_stream_t *s, bool mute)
+{
+    return s->mute ? (s->mute)(s, mute) : E_POINTER;
+}
+
 static inline
 HRESULT aout_stream_Activate(aout_stream_t *s, REFIID iid,
                              PROPVARIANT *actparms, void **pv)
diff --git a/modules/audio_output/wasapi.c b/modules/audio_output/wasapi.c
index bfdfb4e..1ea36ed 100644
--- a/modules/audio_output/wasapi.c
+++ b/modules/audio_output/wasapi.c
@@ -81,6 +81,58 @@ typedef struct aout_stream_sys
 } aout_stream_sys_t;
 
 
+static HRESULT SetVolume(aout_stream_t *s, float vol)
+{
+    aout_stream_sys_t *sys = s->sys;
+    ISimpleAudioVolume *pc_AudioVolume = NULL;
+    HRESULT hr;
+
+    hr = IAudioClient_GetService(sys->client, &IID_ISimpleAudioVolume, &pc_AudioVolume);
+    if (FAILED(hr))
+    {
+        msg_Err(s, "cannot get volume service (error 0x%lx)", hr);
+        goto done;
+    }
+
+    hr = ISimpleAudioVolume_SetMasterVolume(pc_AudioVolume, vol, NULL);
+    if (FAILED(hr))
+    {
+        msg_Err(s, "cannot set volume (error 0x%lx)", hr);
+        goto done;
+    }
+
+done:
+    ISimpleAudioVolume_Release(pc_AudioVolume);
+
+    return hr;
+}
+
+static HRESULT Mute(aout_stream_t *s, bool mute)
+{
+    aout_stream_sys_t *sys = s->sys;
+    ISimpleAudioVolume *pc_AudioVolume = NULL;
+    HRESULT hr;
+
+    hr = IAudioClient_GetService(sys->client, &IID_ISimpleAudioVolume, &pc_AudioVolume);
+    if (FAILED(hr))
+    {
+        msg_Err(s, "cannot get volume service (error 0x%lx)", hr);
+        goto done;
+    }
+
+    hr = ISimpleAudioVolume_SetMute(pc_AudioVolume, mute, NULL);
+    if (FAILED(hr))
+    {
+        msg_Err(s, "cannot set mute (error 0x%lx)", hr);
+        goto done;
+    }
+
+done:
+    ISimpleAudioVolume_Release(pc_AudioVolume);
+
+    return hr;
+}
+
 /*** VLC audio output callbacks ***/
 static HRESULT TimeGet(aout_stream_t *s, mtime_t *restrict delay)
 {
@@ -439,6 +491,8 @@ static HRESULT Start(aout_stream_t *s, audio_sample_format_t *restrict fmt,
     sys->written = 0;
     s->sys = sys;
     s->time_get = TimeGet;
+    s->set_volume = SetVolume;
+    s->mute = Mute;
     s->play = Play;
     s->pause = Pause;
     s->flush = Flush;
diff --git a/modules/audio_output/winstore.c b/modules/audio_output/winstore.c
index b5a9233..5b1ebe9 100644
--- a/modules/audio_output/winstore.c
+++ b/modules/audio_output/winstore.c
@@ -58,6 +58,41 @@ struct aout_sys_t
     IAudioClient *client;
 };
 
+static int VolumeSet(audio_output_t *aout, float vol)
+{
+    aout_sys_t *sys = aout->sys;
+    HRESULT hr;
+    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);
+
+    // TODO EnterMTA();
+    hr = aout_stream_SetVolume(sys->stream, vol);
+    // TODO LeaveMTA();
+
+    return SUCCEEDED(hr) ? 0 : -1;
+}
+
+static int MuteSet(audio_output_t *aout, bool mute)
+{
+    aout_sys_t *sys = aout->sys;
+    HRESULT hr;
+
+    // TODO EnterMTA();
+    hr = aout_stream_Mute(sys->stream, mute);
+    // TODO LeaveMTA();
+
+    return SUCCEEDED(hr) ? 0 : -1;
+}
+
 static int TimeGet(audio_output_t *aout, mtime_t *restrict delay)
 {
     aout_sys_t *sys = aout->sys;
@@ -194,6 +229,8 @@ static int Open(vlc_object_t *obj)
     aout->start = Start;
     aout->stop = Stop;
     aout->time_get = TimeGet;
+    aout->volume_set = VolumeSet;
+    aout->mute_set = MuteSet;
     aout->play = Play;
     aout->pause = Pause;
     aout->flush = Flush;
-- 
2.7.0.windows.1



More information about the vlc-devel mailing list