There is an application uses DirectSound to play waves and uses IAudioEndpointVolume to adjust the volume, but there is no effect on the volume adjustment.
From: YeshunYe yeyeshun@uniontech.com
Signed-off-by: YeshunYe yeyeshun@uniontech.com --- dlls/mmdevapi/audiovolume.c | 41 ++++++++++++++++++++++++++++--- dlls/winealsa.drv/mmdevdrv.c | 15 ++++++++--- dlls/winecoreaudio.drv/mmdevdrv.c | 15 ++++++++--- dlls/wineoss.drv/mmdevdrv.c | 15 ++++++++--- dlls/winepulse.drv/mmdevdrv.c | 11 +++++++-- 5 files changed, 79 insertions(+), 18 deletions(-)
diff --git a/dlls/mmdevapi/audiovolume.c b/dlls/mmdevapi/audiovolume.c index bbaba7750b3..b331eaa3155 100644 --- a/dlls/mmdevapi/audiovolume.c +++ b/dlls/mmdevapi/audiovolume.c @@ -44,6 +44,7 @@ typedef struct AEVImpl { LONG ref; float master_vol; BOOL mute; + IMMDevice *parent; } AEVImpl;
static inline AEVImpl *impl_from_IAudioEndpointVolumeEx(IAudioEndpointVolumeEx *iface) @@ -53,6 +54,7 @@ static inline AEVImpl *impl_from_IAudioEndpointVolumeEx(IAudioEndpointVolumeEx *
static void AudioEndpointVolume_Destroy(AEVImpl *This) { + IMMDevice_Release(This->parent); HeapFree(GetProcessHeap(), 0, This); }
@@ -135,9 +137,35 @@ static HRESULT WINAPI AEV_SetMasterVolumeLevel(IAudioEndpointVolumeEx *iface, fl
static HRESULT WINAPI AEV_SetMasterVolumeLevelScalar(IAudioEndpointVolumeEx *iface, float level, const GUID *ctx) { + AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface); + IAudioSessionManager *sesman; + ISimpleAudioVolume *volume; + HRESULT hr; + TRACE("(%p)->(%f,%s)\n", iface, level, debugstr_guid(ctx)); - FIXME("stub\n"); - return E_NOTIMPL; + if(level < 0.f || level > 1.f) + return E_INVALIDARG; + + This->master_vol = level * 100.f - 100.f; + hr = IMMDevice_Activate(This->parent, &IID_IAudioSessionManager, CLSCTX_INPROC_SERVER, 0, (void**)&sesman); + if(FAILED(hr)){ + WARN("Activate failed: %08x\n", hr); + return E_FAIL; + } + hr = IAudioSessionManager_GetSimpleAudioVolume(sesman, 0, FALSE, &volume); + IAudioSessionManager_Release(sesman); + if(FAILED(hr)){ + WARN("GetSimpleAudioVolume failed: %08x\n", hr); + return E_FAIL; + } + hr = ISimpleAudioVolume_SetMasterVolume(volume, level, NULL); + ISimpleAudioVolume_Release(volume); + if(FAILED(hr)){ + WARN("SetMasterVolume failed: %08x\n", hr); + return E_FAIL; + } + + return S_OK; }
static HRESULT WINAPI AEV_GetMasterVolumeLevel(IAudioEndpointVolumeEx *iface, float *leveldb) @@ -156,11 +184,12 @@ static HRESULT WINAPI AEV_GetMasterVolumeLevel(IAudioEndpointVolumeEx *iface, fl
static HRESULT WINAPI AEV_GetMasterVolumeLevelScalar(IAudioEndpointVolumeEx *iface, float *level) { + AEVImpl *This = impl_from_IAudioEndpointVolumeEx(iface); TRACE("(%p)->(%p)\n", iface, level); if (!level) return E_POINTER; - FIXME("stub\n"); - *level = 1.0; + + *level = (This->master_vol + 100.0f) / 100.0f; return S_OK; }
@@ -307,6 +336,7 @@ static const IAudioEndpointVolumeExVtbl AEVImpl_Vtbl = { HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolumeEx **ppv) { AEVImpl *This; + TRACE("%s\n", debugstr_guid(&parent->devguid));
*ppv = NULL; This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This)); @@ -315,6 +345,9 @@ HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolumeEx **pp This->IAudioEndpointVolumeEx_iface.lpVtbl = &AEVImpl_Vtbl; This->ref = 1;
+ This->parent = &parent->IMMDevice_iface; + IMMDevice_AddRef(This->parent); + *ppv = &This->IAudioEndpointVolumeEx_iface; return S_OK; } diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c index 96a0a62d72e..1139c774ac5 100644 --- a/dlls/winealsa.drv/mmdevdrv.c +++ b/dlls/winealsa.drv/mmdevdrv.c @@ -647,15 +647,22 @@ static HRESULT get_audio_session(const GUID *sessionguid, { AudioSession *session;
- if(!sessionguid || IsEqualGUID(sessionguid, &GUID_NULL)){ - *out = create_session(&GUID_NULL, device, channels); - if(!*out) + *out = NULL; + if (!sessionguid || IsEqualGUID(sessionguid, &GUID_NULL)) { + LIST_FOR_EACH_ENTRY(session, &g_sessions, AudioSession, entry) { + if (session->device == device) { + session_init_vols(session, channels); + *out = session; + break; + } + } + if (!*out) *out = create_session(&GUID_NULL, device, channels); + if (!*out) return E_OUTOFMEMORY;
return S_OK; }
- *out = NULL; LIST_FOR_EACH_ENTRY(session, &g_sessions, AudioSession, entry){ if(session->device == device && IsEqualGUID(sessionguid, &session->guid)){ diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c index 8d1d14aa26f..fbce42bd2e0 100644 --- a/dlls/winecoreaudio.drv/mmdevdrv.c +++ b/dlls/winecoreaudio.drv/mmdevdrv.c @@ -637,15 +637,22 @@ static HRESULT get_audio_session(const GUID *sessionguid, { AudioSession *session;
- if(!sessionguid || IsEqualGUID(sessionguid, &GUID_NULL)){ - *out = create_session(&GUID_NULL, device, channels); - if(!*out) + *out = NULL; + if (!sessionguid || IsEqualGUID(sessionguid, &GUID_NULL)) { + LIST_FOR_EACH_ENTRY(session, &g_sessions, AudioSession, entry) { + if (session->device == device) { + session_init_vols(session, channels); + *out = session; + break; + } + } + if (!*out) *out = create_session(&GUID_NULL, device, channels); + if (!*out) return E_OUTOFMEMORY;
return S_OK; }
- *out = NULL; LIST_FOR_EACH_ENTRY(session, &g_sessions, AudioSession, entry){ if(session->device == device && IsEqualGUID(sessionguid, &session->guid)){ diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c index 166f9408416..253999228d7 100644 --- a/dlls/wineoss.drv/mmdevdrv.c +++ b/dlls/wineoss.drv/mmdevdrv.c @@ -619,15 +619,22 @@ static HRESULT get_audio_session(const GUID *sessionguid, { AudioSession *session;
- if(!sessionguid || IsEqualGUID(sessionguid, &GUID_NULL)){ - *out = create_session(&GUID_NULL, device, channels); - if(!*out) + *out = NULL; + if (!sessionguid || IsEqualGUID(sessionguid, &GUID_NULL)) { + LIST_FOR_EACH_ENTRY(session, &g_sessions, AudioSession, entry) { + if (session->device == device) { + session_init_vols(session, channels); + *out = session; + break; + } + } + if (!*out) *out = create_session(&GUID_NULL, device, channels); + if (!*out) return E_OUTOFMEMORY;
return S_OK; }
- *out = NULL; LIST_FOR_EACH_ENTRY(session, &g_sessions, AudioSession, entry){ if(session->device == device && IsEqualGUID(sessionguid, &session->guid)){ diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 0ad17edf2ef..97fba2244e2 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -770,15 +770,22 @@ static HRESULT get_audio_session(const GUID *sessionguid, { AudioSession *session;
+ *out = NULL; if (!sessionguid || IsEqualGUID(sessionguid, &GUID_NULL)) { - *out = create_session(&GUID_NULL, device, channels); + LIST_FOR_EACH_ENTRY(session, &g_sessions, AudioSession, entry) { + if (session->device == device) { + session_init_vols(session, channels); + *out = session; + break; + } + } + if (!*out) *out = create_session(&GUID_NULL, device, channels); if (!*out) return E_OUTOFMEMORY;
return S_OK; }
- *out = NULL; LIST_FOR_EACH_ENTRY(session, &g_sessions, AudioSession, entry) { if (session->device == device && IsEqualGUID(sessionguid, &session->guid)) {