A while back I blogged about using IAudioSessionControl and IAudioSessionControl2 to get a list of active sessions, and then using IAudioMeterInformation to see what the amplitude level of the audio being played from each session was.

I decided to go back and push this a little further and see what information there was to dig out. Pseudocode:

CoCreate(IMMDeviceEnumerator)
MMDevice = IMMDeviceEnumerator::GetDefaultAudioEndpoint(...)
AudioSessionManager2 = MMDevice::Activate(...)
AudioSessionEnumerator = AudioSessionManager2::GetSessionEnumerator()

for each session in AudioSessionEnumerator {
    AudioSessionControl = AudioSessionEnumerator::GetSession(...)
    if (AudioSessionStateActive != AudioSessionControl::GetState()) { continue; }

    AudioSessionControl::GetIconPath (usually blank)
    AudioSessionControl::GetDisplayName (usually blank)
    AudioSessionControl::GetGroupingParam

    AudioSessionControl2 = AudioSessionControl::QueryInterface(...)
    AudioSessionControl2::GetSessionIdentifier (treat this as an opaque string)
    AudioSessionControl2::GetSessionInstanceIdentifier (treat this as an opaque string)
    AudioSessionControl2::GetProcessId (some sessions span multiple processes)
    AudioSessionControl2::IsSystemSoundsSession

    AudioMeterInformation = AudioSessionControl::QueryInterface(...)
    AudioMeterInformation::GetPeakValue

    for each top level window in the process pointed to by AudioSessionControl2::GetProcessId {
        Use WM_GETTEXTLENGTH and WM_GETTEXT to get the window text, if any
    }
}

Here's the output of the new version of meters.exe.

>meters.exe
-- Active session #1 --
    Icon path:
    Display name:
    Grouping parameter: {a204c0ad-03c4-4754-8e8f-92843aacb1fa}
    Process ID: 11812 (single-process)
    Session identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|\Device\HarddiskVolume1\Windows\System32\WWAHost.exe%b{00000000-0000-0000-0000-000000000000}
    Session instance identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|\Device\HarddiskVolume1\Windows\System32\WWAHost.exe%b{00000000-0000-0000-0000-000000000000}|1%b11812
    System sounds session: no
    Peak value: 0.2837

-- Active session #2 --
    Icon path:
    Display name:
    Grouping parameter: {a2e2e0f5-81bb-407e-b701-f4f3695f9dac}
    Process ID: 15148 (single-process)
    Session identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|\Device\HarddiskVolume1\Program Files (x86)\Internet Explorer\iexplore.exe%b{00000000-0000-0000-0000-000000000000}
    Session instance identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|\Device\HarddiskVolume1\Program Files (x86)\Internet Explorer\iexplore.exe%b{00000000-0000-0000-0000-000000000000}|1%b15148
    System sounds session: no
    Peak value: 0.428589
    HWND: 0x0000000001330B12
    HWND: 0x0000000000361CA2
    HWND: 0x00000000019A07A8
    HWND: 0x0000000001411BF2
    HWND: 0x0000000000B60706
    HWND: 0x000000000231165A
    HWND: 0x0000000002631472
    HWND: 0x0000000000441D94

-- Active session #3 --
    Icon path:
    Display name:
    Grouping parameter: {e191c91d-dc24-468d-b542-0d5f12ce8c48}
    Process ID: 2324 (multi-process)
    Session identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|#%b{48FF2ED2-2CE8-40FB-AEF7-31FEFDBA7EF2}
    Session instance identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|#%b{48FF2ED2-2CE8-40FB-AEF7-31FEFDBA7EF2}|1%b#
    System sounds session: no
    Peak value: 0.294137
    HWND: 0x0000000002900C86 Windows Media Player

-- Active session #4 --
    Icon path: @%SystemRoot%\System32\AudioSrv.Dll,-203
    Display name: @%SystemRoot%\System32\AudioSrv.Dll,-202
    Grouping parameter: {e7d6e107-ca03-4660-a067-1a1f3dc1619c}
    Process ID: 0 (multi-process)
    Session identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|#%b{A9EF3FD9-4240-455E-A4D5-F2B3301887B2}
    Session instance identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|#%b{A9EF3FD9-4240-455E-A4D5-F2B3301887B2}|1%b#
    System sounds session: yes
    Peak value: 0.0502903

-- Active session #5 --
    Icon path:
    Display name:
    Grouping parameter: {2a3e30fb-2ded-471e-9c2f-cbd8572b2af2}
    Process ID: 15948 (single-process)
    Session identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|\Device\HarddiskVolume1\Program Files (x86)\VideoLAN\VLC\vlc.exe%b{00000000-0000-0000-0000-000000000000}
    Session instance identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|\Device\HarddiskVolume1\Program Files (x86)\VideoLAN\VLC\vlc.exe%b{00000000-0000-0000-0000-000000000000}|1%b15948
    System sounds session: no
    Peak value: 0.287567
    HWND: 0x0000000000C8160C Opening Ceremony - VLC media player

Active sessions: 5

Part of this was logging the grouping parameter, which is a GUID. I've seen a lot of code that converts the GUID to a string and logs it using %s. Another way is to use a couple of macros and let the format string do the conversion for you:

#define GUID_FORMAT L"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"
#define GUID_VALUES(g) \
g.Data1, g.Data2, g.Data3, \
g.Data4[0], g.Data4[1], g.Data4[2], g.Data4[3], \
g.Data4[4], g.Data4[5], g.Data4[6], g.Data4[7]

...

GUID someGuid = ...;

LOG(L"The value of someGuid is " GUID_FORMAT L".", GUID_VALUES(someGuid));

Standard caveats about not using side effects inside a macro apply. For example, this would be a bug:

for (GUID *p = ...) {
    LOG(L"p = " GUID_FORMAT L".", GUID_VALUES(*(p++)); // BUG!
}

 Source, amd64 binaries, and x86 binaries attached.