IAudioSessionNotification, anyone have working cod

2019-01-28 02:37发布

问题:

I'm picking up some experimental code I was messing with in the Windows 7 Beta now that I've installed the RC.

Basically, I'm trying to get IAudioSessionManager2 & IAudioSessionNotification working together to inform my little app of every new audio session created.

Punchline code in AudioListener (public IAudioSessionNotification):

//This is mostly lifted from MSDN
HRESULT STDMETHODCALLTYPE AudioListener::QueryInterface(REFIID riid, void** ppvObject)
{
    if(riid == __uuidof(IUnknown))
    {
        *ppvObject = (IUnknown*)this;
        return S_OK;
    }

    if(riid == __uuidof(IAudioSessionNotification))
    {
        *ppvObject = (IAudioSessionNotification*)this;
        return S_OK;
    }

    *ppvObject = NULL;

    return E_NOINTERFACE;
}

//m_hwnd, and WM_SESSION_CREATED are set to good values
//WM_SESSION_CREATEd via RegisterWindowMessage(...)
HRESULT STDMETHODCALLTYPE AudioListener::OnSessionCreated(IAudioSessionControl *pSession)
{
    PostMessage(m_hwnd, WM_SESSION_CREATED, (WPARAM)pSession, 0);

    return S_OK;
}

Code registering my listener:

BOOL RegisterMonitor(HWND target)
{
    BOOL success = false;

    HRESULT res;
    IMMDevice* pDevice;
    IMMDeviceEnumerator* pEnumerator;

    SESSION_LISTENER = NULL;
    SESSION = NULL;

    res = CoInitialize(NULL);

    if(res != S_OK && res != S_FALSE)
        return false;

    SESSION_LISTENER = new AudioListener(target);

    res = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pEnumerator);
    if(res != S_OK)  goto Exit;

    res = pEnumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &pDevice);
    if(res != S_OK)  goto Exit;

    res = pDevice->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL, (void**)&SESSION);
    if(res != S_OK)  goto Exit;

    res = SESSION->RegisterSessionNotification(SESSION_LISTENER);
    if(res != S_OK)  goto Exit;

    success = true;

Exit:
    SAFE_RELEASE(pEnumerator);
    SAFE_RELEASE(pDevice);
    if(!success)
    {
        SAFE_RELEASE(SESSION_LISTENER);
        SAFE_RELEASE(SESSION);
    }

    return success;
}

RegisterMonitor(...) returns true, but no notifications are ever received. I've been testing by launching little apps with minor sound effects and triggering them (Soltaire, Minesweeper, etc.), confirming that they show up in SndVol when I'm expecting to see a notification.

Basically, does anyone see what I'm doing wrong?

回答1:

You released the session manager in your RegisterMonitor function. Once you release the last reference to the session manager it is freed and you'll no longer receive session notifications.

Keep the session manager object alive and it should work just fine.



回答2:

I've experienced the same issue and the solution for me was to add a call to GetSessionEnumerator() after calling RegisterSessionNotification()