[vlc-devel] [PATCH 5/7] mmdevice: add mmdevice-audio-device preference

Thomas Guillem thomas at gllm.fr
Tue Feb 27 11:41:09 CET 2018


Like for other Windows aouts, this preference can be used to save the preferred
audio device that will be used across several instances of VLC.

If the saved device is unplugged when loading the aout, it will fallback to the
"Default" virtual device.
---
 modules/audio_output/mmdevice.c | 101 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 100 insertions(+), 1 deletion(-)

diff --git a/modules/audio_output/mmdevice.c b/modules/audio_output/mmdevice.c
index 9561b8701d..b0a465331e 100644
--- a/modules/audio_output/mmdevice.c
+++ b/modules/audio_output/mmdevice.c
@@ -1284,7 +1284,6 @@ static int Open(vlc_object_t *obj)
     atomic_init(&sys->request_default_device, false);
 
     sys->gain = 1.f;
-    sys->requested_device = default_device;
     sys->requested_volume = -1.f;
     sys->requested_mute = -1;
     sys->acquired_device = NULL;
@@ -1294,6 +1293,21 @@ static int Open(vlc_object_t *obj)
 
     aout_HotplugReport(aout, default_device_b, _("Default"));
 
+    char *saved_device_b = var_InheritString(aout, "mmdevice-audio-device");
+    if (saved_device_b != NULL && strcmp(saved_device_b, default_device_b) != 0)
+    {
+        sys->requested_device = ToWide(saved_device_b);
+        free(saved_device_b);
+
+        if (unlikely(sys->requested_device == NULL))
+            goto error;
+    }
+    else
+    {
+        free(saved_device_b);
+        sys->requested_device = default_device;
+    }
+
     /* Initialize MMDevice API */
     if (TryEnterMTA(aout))
         goto error;
@@ -1357,6 +1371,86 @@ static void Close(vlc_object_t *obj)
     free(sys);
 }
 
+struct mm_list
+{
+    size_t count;
+    char **ids;
+    char **names;
+};
+
+static void Reload_DevicesEnum_Added(vlc_object_t *this, void *data,
+                                     LPCWSTR wid, IMMDevice *dev)
+{
+    (void) this;
+    struct mm_list *list = data;
+
+    size_t new_count = list->count + 1;
+    list->ids = realloc_or_free(list->ids, new_count * sizeof(char *));
+    list->names = realloc_or_free(list->names, new_count * sizeof(char *));
+    if (!list->ids || !list->names)
+    {
+        free(list->ids);
+        return;
+    }
+
+    char *id, *name;
+    if (DeviceGetFriendlyName(wid, dev, &id, &name) != VLC_SUCCESS)
+        return;
+    list->ids[list->count] = id;
+    list->names[list->count] = name;
+
+    list->count = new_count;
+}
+
+static int ReloadAudioDevices(vlc_object_t *this, char const *name,
+                              char ***values, char ***descs)
+{
+    (void) name;
+
+    bool in_mta = TryEnterMTA(this) == 0;
+
+    struct mm_list list = { .count = 0 };
+    void *it;
+    HRESULT hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
+                                  &IID_IMMDeviceEnumerator, &it);
+    if (FAILED(hr))
+        goto error;
+
+    list.ids = malloc(sizeof (char *));
+    list.names = malloc(sizeof (char *));
+    if (!list.ids || !list.names)
+    {
+        free(list.ids);
+        goto error;
+    }
+
+    list.ids[0] = strdup("");
+    list.names[0] = strdup(_("Default"));
+    if (!list.ids[0] || !list.names[0])
+    {
+        free(list.ids[0]);
+        free(list.ids);
+        free(list.names);
+        goto error;
+    }
+    list.count++;
+
+    DevicesEnum(this, it, Reload_DevicesEnum_Added, &list);
+
+error:
+    IMMDeviceEnumerator_Release((IMMDeviceEnumerator *)it);
+    if (in_mta)
+        LeaveMTA();
+
+    if (list.count > 0)
+    {
+        *values = list.ids;
+        *descs = list.names;
+    }
+
+    return list.count;
+}
+
 #define MM_PASSTHROUGH_TEXT N_( \
     "HDMI/SPDIF audio passthrough")
 #define MM_PASSTHROUGH_LONGTEXT N_( \
@@ -1372,6 +1466,9 @@ static const char *const ppsz_mmdevice_passthrough_texts[] = {
     N_("Enabled"),
 };
 
+#define DEVICE_TEXT N_("Output device")
+#define DEVICE_LONGTEXT N_("Select your audio output device")
+
 vlc_module_begin()
     set_shortname("MMDevice")
     set_description(N_("Windows Multimedia Device output"))
@@ -1386,4 +1483,6 @@ vlc_module_begin()
                  MM_PASSTHROUGH_TEXT, MM_PASSTHROUGH_LONGTEXT, false )
         change_integer_list( pi_mmdevice_passthrough_values,
                              ppsz_mmdevice_passthrough_texts )
+    add_string("mmdevice-audio-device", NULL, DEVICE_TEXT, DEVICE_LONGTEXT, false)
+        change_string_cb(ReloadAudioDevices)
 vlc_module_end()
-- 
2.11.0



More information about the vlc-devel mailing list