-static int SimpleVolumeSet(audio_output_t *aout, float vol)
-{
- aout_sys_t *sys = aout->sys;
- ISimpleAudioVolume *simple;
- HRESULT hr;
-
- if (TryEnter(aout))
- return -1;
- hr = IAudioClient_GetService(sys->client, &IID_ISimpleAudioVolume,
- (void **)&simple);
- if (SUCCEEDED(hr))
- {
- hr = ISimpleAudioVolume_SetMasterVolume(simple, vol, NULL);
- ISimpleAudioVolume_Release(simple);
- }
- Leave();
-
- if (FAILED(hr))
- {
- msg_Err(aout, "cannot set volume (error 0x%lx)", hr);
- sys->volume_hack = vol;
- return -1;
- }
- sys->volume_hack = -1.f;
- return 0;
-}
-
-static int SimpleMuteSet(audio_output_t *aout, bool mute)
-{
- aout_sys_t *sys = aout->sys;
- ISimpleAudioVolume *simple;
- HRESULT hr;
-
- if (TryEnter(aout))
- return -1;
- hr = IAudioClient_GetService(sys->client, &IID_ISimpleAudioVolume,
- (void **)&simple);
- if (SUCCEEDED(hr))
- {
- hr = ISimpleAudioVolume_SetMute(simple, mute, NULL);
- ISimpleAudioVolume_Release(simple);
- }
- Leave();
-
- if (FAILED(hr))
- {
- msg_Err(aout, "cannot set mute (error 0x%lx)", hr);
- sys->mute_hack = mute;
- return -1;
- }
- sys->mute_hack = -1;
- return 0;
-}
-
-
-/*** Audio devices ***/
-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 GetDevices(vlc_object_t *obj, IMMDeviceEnumerator *it)
-{
- HRESULT hr;
- vlc_value_t val, text;
-
- var_Create (obj, "audio-device", VLC_VAR_STRING | VLC_VAR_HASCHOICE);
- text.psz_string = _("Audio Device");
- var_Change (obj, "audio-device", VLC_VAR_SETTEXT, &text, NULL);
-
- IMMDeviceCollection *devs;
- hr = IMMDeviceEnumerator_EnumAudioEndpoints(it, eRender,
- DEVICE_STATE_ACTIVE, &devs);
- if (FAILED(hr))
- {
- msg_Warn (obj, "cannot enumerate audio endpoints (error 0x%lx)", hr);
- return;
- }
-
- UINT n;
- hr = IMMDeviceCollection_GetCount(devs, &n);
- if (FAILED(hr))
- {
- msg_Warn (obj, "cannot count audio endpoints (error 0x%lx)", hr);
- n = 0;
- }
- else
- msg_Dbg(obj, "Available Windows Audio devices:");
-
- while (n > 0)
- {
- IMMDevice *dev;
-
- hr = IMMDeviceCollection_Item(devs, --n, &dev);
- if (FAILED(hr))
- continue;
-
- /* Unique device ID */
- LPWSTR devid;
- hr = IMMDevice_GetId(dev, &devid);
- if (FAILED(hr))
- {
- IMMDevice_Release(dev);
- continue;
- }
- val.psz_string = FromWide(devid);
- CoTaskMemFree(devid);
- text.psz_string = val.psz_string;
-
- /* User-readable device name */
- IPropertyStore *props;
- hr = IMMDevice_OpenPropertyStore(dev, STGM_READ, &props);
- if (SUCCEEDED(hr))
- {
- PROPVARIANT v;
-
- PropVariantInit(&v);
- hr = IPropertyStore_GetValue(props, &PKEY_Device_FriendlyName, &v);
- if (SUCCEEDED(hr))
- text.psz_string = FromWide(v.pwszVal);
- PropVariantClear(&v);
- IPropertyStore_Release(props);
- }
- IMMDevice_Release(dev);
-
- msg_Dbg(obj, "%s (%s)", val.psz_string, text.psz_string);
- var_Change(obj, "audio-device", VLC_VAR_ADDCHOICE, &val, &text);
- if (likely(text.psz_string != val.psz_string))
- free(text.psz_string);
- free(val.psz_string);
- }
- IMMDeviceCollection_Release(devs);
-}
-
-
-/*** Audio session events ***/
-static inline aout_sys_t *vlc_AudioSessionEvents_sys(IAudioSessionEvents *this)
-{
- return (aout_sys_t *)(((char *)this) - offsetof(aout_sys_t, events));
-}
-
-static STDMETHODIMP
-vlc_AudioSessionEvents_QueryInterface(IAudioSessionEvents *this, REFIID riid,
- void **ppv)
-{
- if (IsEqualIID(riid, &IID_IUnknown)
- || IsEqualIID(riid, &IID_IAudioSessionEvents))
- {
- *ppv = this;
- IUnknown_AddRef(this);
- return S_OK;
- }
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
-}
-
-static STDMETHODIMP_(ULONG)
-vlc_AudioSessionEvents_AddRef(IAudioSessionEvents *this)
-{
- aout_sys_t *sys = vlc_AudioSessionEvents_sys(this);
- return InterlockedIncrement(&sys->refs);
-}
-
-static STDMETHODIMP_(ULONG)
-vlc_AudioSessionEvents_Release(IAudioSessionEvents *this)
-{
- aout_sys_t *sys = vlc_AudioSessionEvents_sys(this);
- return InterlockedDecrement(&sys->refs);
-}
-
-static STDMETHODIMP
-vlc_AudioSessionEvents_OnDisplayNameChanged(IAudioSessionEvents *this,
- LPCWSTR wname, LPCGUID ctx)
-{
- aout_sys_t *sys = vlc_AudioSessionEvents_sys(this);
- audio_output_t *aout = sys->aout;
-
- msg_Dbg(aout, "display name changed: %ls", wname);
- (void) ctx;
- return S_OK;
-}
-
-static STDMETHODIMP
-vlc_AudioSessionEvents_OnIconPathChanged(IAudioSessionEvents *this,
- LPCWSTR wpath, LPCGUID ctx)
-{
- aout_sys_t *sys = vlc_AudioSessionEvents_sys(this);
- audio_output_t *aout = sys->aout;
-
- msg_Dbg(aout, "icon path changed: %ls", wpath);
- (void) ctx;
- return S_OK;
-}
-
-static STDMETHODIMP
-vlc_AudioSessionEvents_OnSimpleVolumeChanged(IAudioSessionEvents *this, float vol,
- WINBOOL mute, LPCGUID ctx)
-{
- aout_sys_t *sys = vlc_AudioSessionEvents_sys(this);
- audio_output_t *aout = sys->aout;
-
- msg_Dbg(aout, "simple volume changed: %f, muting %sabled", vol,
- mute ? "en" : "dis");
- aout_VolumeReport(aout, vol);
- aout_MuteReport(aout, mute == TRUE);
- (void) ctx;
- return S_OK;
-}
-
-static STDMETHODIMP
-vlc_AudioSessionEvents_OnChannelVolumeChanged(IAudioSessionEvents *this,
- DWORD count, float *vols,
- DWORD changed, LPCGUID ctx)
-{
- aout_sys_t *sys = vlc_AudioSessionEvents_sys(this);
- audio_output_t *aout = sys->aout;
-
- msg_Dbg(aout, "channel volume %lu of %lu changed: %f", changed, count,
- vols[changed]);
- (void) ctx;
- return S_OK;
-}
-
-static STDMETHODIMP
-vlc_AudioSessionEvents_OnGroupingParamChanged(IAudioSessionEvents *this,
- LPCGUID param, LPCGUID ctx)
-
-{
- aout_sys_t *sys = vlc_AudioSessionEvents_sys(this);
- audio_output_t *aout = sys->aout;
-
- msg_Dbg(aout, "grouping parameter changed");
- (void) param;
- (void) ctx;
- return S_OK;
-}
-
-static STDMETHODIMP
-vlc_AudioSessionEvents_OnStateChanged(IAudioSessionEvents *this,
- AudioSessionState state)
-{
- aout_sys_t *sys = vlc_AudioSessionEvents_sys(this);
- audio_output_t *aout = sys->aout;
-
- msg_Dbg(aout, "state changed: %d", state);
- return S_OK;
-}
-
-static STDMETHODIMP
-vlc_AudioSessionEvents_OnSessionDisconnected(IAudioSessionEvents *this,
- AudioSessionDisconnectReason reason)
-{
- aout_sys_t *sys = vlc_AudioSessionEvents_sys(this);
- audio_output_t *aout = sys->aout;
-
- msg_Dbg(aout, "session disconnected: reason %d", reason);
- return S_OK;
-}
-
-static const struct IAudioSessionEventsVtbl vlc_AudioSessionEvents =
-{
- vlc_AudioSessionEvents_QueryInterface,
- vlc_AudioSessionEvents_AddRef,
- vlc_AudioSessionEvents_Release,
-
- vlc_AudioSessionEvents_OnDisplayNameChanged,
- vlc_AudioSessionEvents_OnIconPathChanged,
- vlc_AudioSessionEvents_OnSimpleVolumeChanged,
- vlc_AudioSessionEvents_OnChannelVolumeChanged,
- vlc_AudioSessionEvents_OnGroupingParamChanged,
- vlc_AudioSessionEvents_OnStateChanged,
- vlc_AudioSessionEvents_OnSessionDisconnected,
-};
-