Commit b6d22a96 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

wasapi: add run-time device selection

parent 7dc7f613
...@@ -208,6 +208,17 @@ static int SimpleMuteSet(audio_output_t *aout, bool mute) ...@@ -208,6 +208,17 @@ static int SimpleMuteSet(audio_output_t *aout, bool mute)
return FAILED(hr) ? -1 : 0; return FAILED(hr) ? -1 : 0;
} }
static int DeviceChanged(vlc_object_t *obj, const char *varname,
vlc_value_t prev, vlc_value_t cur, void *data)
{
aout_ChannelsRestart(obj, varname, prev, cur, data);
if (!var_Type (obj, "wasapi-audio-device"))
var_Create (obj, "wasapi-audio-device", VLC_VAR_STRING);
var_SetString (obj, "wasapi-audio-device", cur.psz_string);
return VLC_SUCCESS;
}
static void vlc_ToWave(WAVEFORMATEXTENSIBLE *restrict wf, static void vlc_ToWave(WAVEFORMATEXTENSIBLE *restrict wf,
audio_sample_format_t *restrict audio) audio_sample_format_t *restrict audio)
{ {
...@@ -389,6 +400,8 @@ static int Open(vlc_object_t *obj) ...@@ -389,6 +400,8 @@ static int Open(vlc_object_t *obj)
} }
/* Get audio device according to policy */ /* Get audio device according to policy */
var_Create (aout, "audio-device", VLC_VAR_STRING);
IMMDeviceEnumerator *devs; IMMDeviceEnumerator *devs;
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
&IID_IMMDeviceEnumerator, (void **)&devs); &IID_IMMDeviceEnumerator, (void **)&devs);
...@@ -398,9 +411,26 @@ static int Open(vlc_object_t *obj) ...@@ -398,9 +411,26 @@ static int Open(vlc_object_t *obj)
goto error; goto error;
} }
IMMDevice *dev; // Without configuration item, the variable must be created explicitly.
var_Create (aout, "wasapi-audio-device", VLC_VAR_STRING);
LPWSTR devid = var_InheritWide (aout, "wasapi-audio-device");
var_Destroy (aout, "wasapi-audio-device");
IMMDevice *dev = NULL;
if (devid != NULL)
{
msg_Dbg (aout, "using selected device %ls", devid);
hr = IMMDeviceEnumerator_GetDevice (devs, devid, &dev);
if (FAILED(hr))
msg_Warn(aout, "cannot get audio endpoint (error 0x%lx)", hr);
free (devid);
}
if (dev == NULL)
{
msg_Dbg (aout, "using default device");
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devs, eRender, hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devs, eRender,
eConsole, &dev); eConsole, &dev);
}
IMMDeviceEnumerator_Release(devs); IMMDeviceEnumerator_Release(devs);
if (FAILED(hr)) if (FAILED(hr))
{ {
...@@ -408,12 +438,12 @@ static int Open(vlc_object_t *obj) ...@@ -408,12 +438,12 @@ static int Open(vlc_object_t *obj)
goto error; goto error;
} }
LPWSTR str; hr = IMMDevice_GetId(dev, &devid);
hr = IMMDevice_GetId(dev, &str);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
msg_Dbg(aout, "using device %ls", str); msg_Dbg(aout, "using device %ls", devid);
CoTaskMemFree(str); var_SetWide (aout, "audio-device", devid);
CoTaskMemFree(devid);
} }
hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_ALL, NULL, hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_ALL, NULL,
...@@ -482,6 +512,8 @@ static int Open(vlc_object_t *obj) ...@@ -482,6 +512,8 @@ static int Open(vlc_object_t *obj)
if (sys->render == NULL) if (sys->render == NULL)
goto error; goto error;
Leave();
aout->format = format; aout->format = format;
aout->pf_play = Play; aout->pf_play = Play;
aout->pf_pause = Pause; aout->pf_pause = Pause;
...@@ -491,7 +523,8 @@ static int Open(vlc_object_t *obj) ...@@ -491,7 +523,8 @@ static int Open(vlc_object_t *obj)
aout->volume_set = SimpleVolumeSet; aout->volume_set = SimpleVolumeSet;
aout->mute_set = SimpleMuteSet; aout->mute_set = SimpleMuteSet;
} }
Leave(); var_AddCallback (aout, "audio-device", DeviceChanged, NULL);
return VLC_SUCCESS; return VLC_SUCCESS;
error: error:
if (sys->done != NULL) if (sys->done != NULL)
...@@ -501,6 +534,7 @@ error: ...@@ -501,6 +534,7 @@ error:
if (sys->client != NULL) if (sys->client != NULL)
IAudioClient_Release(sys->client); IAudioClient_Release(sys->client);
Leave(); Leave();
var_Destroy (aout, "audio-device");
free(sys); free(sys);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -517,6 +551,9 @@ static void Close (vlc_object_t *obj) ...@@ -517,6 +551,9 @@ static void Close (vlc_object_t *obj)
IAudioClient_Release(sys->client); IAudioClient_Release(sys->client);
Leave(); Leave();
var_DelCallback (aout, "audio-device", DeviceChanged, NULL);
var_Destroy (aout, "audio-device");
CloseHandle(sys->done); CloseHandle(sys->done);
CloseHandle(sys->ready); CloseHandle(sys->ready);
free(sys); free(sys);
......
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