views:

133

answers:

1

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? Failing that, if anyone has known good and tested code; sharing it would be much appreciated.

A: 

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.

Larry Osterman
Where exactly am I freeing the session manager?Also, even if I comment out all the ->Release()/SAFE_RELEASE() code (leaking COM objects like a sieve) I still do not receive notifications.
Kevin Montrose
Sorry, I misread the Exit portion - I didn't realize that the session manager was only released on the failure case.
Larry Osterman
+1 that a programmer on the Windows Audio stack wrote an answer.
Jeff Moser
Unfortunately, the problem persists. Mad props to Larry for helping random flailing coders though.
Kevin Montrose