From: Matteo Bruni mbruni@codeweavers.com
It's just a normal session, there's nothing special about it. It also means that it can be shared among audio clients, just like any other session. --- dlls/mmdevapi/client.c | 2 ++ dlls/mmdevapi/mmdevapi_private.h | 4 ++-- dlls/mmdevapi/session.c | 13 ++++--------- dlls/mmdevapi/tests/render.c | 27 +++++++++++++++++++++++++-- 4 files changed, 33 insertions(+), 13 deletions(-)
diff --git a/dlls/mmdevapi/client.c b/dlls/mmdevapi/client.c index 94d831370ab..4538eca9e1c 100644 --- a/dlls/mmdevapi/client.c +++ b/dlls/mmdevapi/client.c @@ -515,6 +515,8 @@ static HRESULT stream_init(struct audio_client *client, const BOOLEAN force_def_ FIXME("Unknown flags: %08lx\n", flags); return E_INVALIDARG; } + if (flags & AUDCLNT_STREAMFLAGS_CROSSPROCESS) + FIXME("Cross-process sessions not supported\n");
hr = validate_wfx(fmt, mode);
diff --git a/dlls/mmdevapi/mmdevapi_private.h b/dlls/mmdevapi/mmdevapi_private.h index 8dff5aa0805..672d901bf6d 100644 --- a/dlls/mmdevapi/mmdevapi_private.h +++ b/dlls/mmdevapi/mmdevapi_private.h @@ -27,7 +27,7 @@
#include "unixlib.h"
-typedef struct audio_session { +struct audio_session { GUID guid; struct list clients;
@@ -43,7 +43,7 @@ typedef struct audio_session { GUID grouping_param;
struct list entry; -} AudioSession; +};
typedef struct audio_session_wrapper { IAudioSessionControl2 IAudioSessionControl2_iface; diff --git a/dlls/mmdevapi/session.c b/dlls/mmdevapi/session.c index 9b97cef9df8..8e638251ba2 100644 --- a/dlls/mmdevapi/session.c +++ b/dlls/mmdevapi/session.c @@ -676,6 +676,8 @@ static struct audio_session *session_create(const GUID *guid, IMMDevice *device, if (!ret) return NULL;
+ if (!guid) + guid = &GUID_NULL; memcpy(&ret->guid, guid, sizeof(GUID));
ret->device = device; @@ -725,17 +727,10 @@ HRESULT get_audio_session(const GUID *guid, IMMDevice *device, UINT channels,
TRACE("(%s, %p, %u, %p)\n", debugstr_guid(guid), device, channels, out);
- if (!guid || IsEqualGUID(guid, &GUID_NULL)) { - *out = session_create(&GUID_NULL, device, channels); - if (!*out) - return E_OUTOFMEMORY; - - return S_OK; - } - *out = NULL; LIST_FOR_EACH_ENTRY(session, &sessions, struct audio_session, entry) { - if (session->device == device && IsEqualGUID(guid, &session->guid)) { + if (session->device == device && ((!guid && IsEqualGUID(&session->guid, &GUID_NULL)) || + (guid && IsEqualGUID(guid, &session->guid)))) { session_init_vols(session, channels); *out = session; break; diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index 6c9eb9199ac..afefe363ef5 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -2369,7 +2369,7 @@ static void test_session_creation(void) hr = IAudioSessionManager2_GetSessionEnumerator((void *)sesm2, &sess_enum); ok(hr == S_OK, "got %#lx.\n", hr);
- /* create another session after getting the first enumerarot. */ + /* create another session after getting the first enumerator. */ CoCreateGuid(&session_guid2); hr = IAudioSessionManager_GetAudioSessionControl(sesm, &session_guid2, 0, &ctl); ok(hr == S_OK, "got %#lx.\n", hr); @@ -2392,7 +2392,10 @@ static void test_session_creation(void) hr = IAudioSessionControl_GetDisplayName(ctl, &name); ok(hr == S_OK, "got %#lx.\n", hr); if (!wcscmp(name, L"test_session1")) + { found_first = TRUE; + check_session_ids(dev, &session_guid, ctl); + } if (!wcscmp(name, L"test_session2")) found_second = TRUE; CoTaskMemFree(name); @@ -2431,9 +2434,29 @@ static void test_session_creation(void) ok(found_first && found_second, "got %d, %d.\n", found_first, found_second); IAudioSessionEnumerator_Release(sess_enum); IAudioSessionEnumerator_Release(sess_enum2); + ISimpleAudioVolume_Release(sav);
- /* Release completely to show session persistence */ + /* NULL and GUID_NULL both refer to the default session. There is nothing + * special about it */ + hr = IAudioSessionManager_GetSimpleAudioVolume(sesm, NULL, FALSE, &sav); + ok(hr == S_OK, "GetSimpleAudioVolume failed: %08lx\n", hr); + hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol); + ok(hr == S_OK, "GetMasterVolume failed: %08lx\n", hr); + ok(vol == 1.0f, "Unexpected vol %.8e\n", vol); + hr = ISimpleAudioVolume_SetMasterVolume(sav, 0.5f, NULL); + ok(hr == S_OK, "SetMasterVolume failed: %08lx\n", hr); ISimpleAudioVolume_Release(sav); + + hr = IAudioSessionManager_GetSimpleAudioVolume(sesm, &GUID_NULL, FALSE, &sav); + ok(hr == S_OK, "GetSimpleAudioVolume failed: %08lx\n", hr); + hr = ISimpleAudioVolume_GetMasterVolume(sav, &vol); + ok(hr == S_OK, "GetMasterVolume failed: %08lx\n", hr); + ok(vol == 0.5f, "Unexpected vol %.8e\n", vol); + hr = ISimpleAudioVolume_SetMasterVolume(sav, 1.0f, NULL); + ok(hr == S_OK, "SetMasterVolume failed: %08lx\n", hr); + ISimpleAudioVolume_Release(sav); + + /* Release completely to show session persistence */ IAudioSessionManager_Release(sesm); IAudioSessionManager2_Release(sesm2);