IAudioSessionNotification, у кого-нибудь есть рабочий код? - PullRequest
5 голосов
/ 13 мая 2009

Я собираю какой-то экспериментальный код, с которым я связывался в бета-версии Windows 7, когда я установил RC.

По сути, я пытаюсь заставить IAudioSessionManager2 & IAudioSessionNotification работать вместе, чтобы информировать мое маленькое приложение о каждой новой создаваемой аудио сессии.

Punchline код в AudioListener (общедоступный 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;
}

Код регистрации моего слушателя:

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(...) возвращает true, но никаких уведомлений не поступало. Я тестировал, запуская небольшие приложения с незначительными звуковыми эффектами и вызывая их (Soltaire, Minesweeper и т. Д.), Подтверждая, что они появляются в SndVol, когда я ожидаю увидеть уведомление.

В принципе, кто-нибудь видит, что я делаю не так?

Ответы [ 2 ]

1 голос
/ 14 мая 2009

Вы освободили менеджер сеансов в своей функции RegisterMonitor. После освобождения последней ссылки на менеджер сеансов она освобождается, и вы больше не будете получать уведомления о сеансе.

Поддерживайте объект диспетчера сеансов, и он должен нормально работать.

0 голосов
/ 30 июня 2017

У меня возникла та же проблема, и решение для меня было добавить вызов GetSessionEnumerator () после вызова RegisterSessionNotification ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...