다음을 통해 공유


IAudioEffectsManager 인터페이스(audioclient.h)

애플리케이션이 현재 효과 목록을 얻고, 효과 상태를 설정하고, 효과 또는 효과 상태 목록이 변경될 때 알림을 등록할 수 있도록 연결된 오디오 스트림에 대한 오디오 효과 파이프라인에 대한 관리 기능을 제공합니다.

상속

IAudioEffectsManager 인터페이스는 IUnknown 인터페이스에서 상속됩니다.

메서드

IAudioEffectsManager 인터페이스에는 이러한 메서드가 있습니다.

 
IAudioEffectsManager::GetAudioEffects

연결된 오디오 스트림에 대한 오디오 효과의 현재 목록을 가져옵니다.
IAudioEffectsManager::RegisterAudioEffectsChangedNotificationCallback

AudioEffectsChangedNotificationClient 인터페이스를 등록합니다.
IAudioEffectsManager::SetAudioEffectState

IAudioEffectsManager::SetAudioEffectState 메서드(audioclient.h)는 지정된 오디오 효과의 상태를 설정합니다.
IAudioEffectsManager::UnregisterAudioEffectsChangedNotificationCallback

IAudioEffectsChangedNotificationClient 인터페이스의 등록을 취소합니다.

설명

IAudioEffectsManager 인터페이스의 인터페이스 포인터를 전달하는 IAudioClient::GetService를 호출하여 이 인터페이스의 instance 가져옵니다.

wil::com_ptr_nothrow<IAudioEffectsManager> audioEffectsManager;
RETURN_IF_FAILED(client->GetService(IID_PPV_ARGS(&audioEffectsManager)));

예제

다음 예제에서는 지정된 오디오 스트림에 AUDIO_EFFECT_TYPE_DEEP_NOISE_SUPPRESSION 효과가 있는지 여부를 감지하는 IAudioEffectsManager.GetAudioEffects를 보여 줍니다.

HRESULT IsPlatformDeepNoiseSuppressionPresent(_In_ IAudioClient *client, _Out_ bool *isPresent)
{
    *isPresent = false;
    wil::com_ptr_nothrow<IAudioEffectsManager> audioEffectsManager;
    RETURN_IF_FAILED(client->GetService(IID_PPV_ARGS(&audioEffectsManager)));
    wil::unique_cotaskmem_array_ptr<AUDIO_EFFECT> effects;
    UINT32 numEffects;
    RETURN_IF_FAILED(audioEffectsManager->GetAudioEffects(&effects, &numEffects));

    for (UINT32 i = 0; i < numEffects; i++)
    {
        // Check if noise suppression is part of the current effects
        if (effects[i].id == AUDIO_EFFECT_TYPE_DEEP_NOISE_SUPPRESSION)
        {
            *isPresent = true;
            return S_OK;
        }
    }

    return S_OK;
}

다음 예제에서는 IAudioEffectsManager.SetAudioEffectState 를 사용하여 AUDIO_EFFECT_TYPE_DEEP_NOISE_SUPPRESSION 효과를 사용하지 않도록 설정하는 방법을 보여 줍니다.

HRESULT TryDisablePlatformDeepNoiseSuppression(_In_ IAudioClient *client)
{
    wil::com_ptr_nothrow<IAudioEffectsManager> audioEffectsManager;
    RETURN_IF_FAILED(client->GetService(IID_PPV_ARGS(&audioEffectsManager)));
    wil::unique_cotaskmem_array_ptr<AudioEffect> effects;
    UINT32 numEffects;
    RETURN_IF_FAILED(audioEffectsManager->GetAudioEffects(&effects, &numEffects));

    for (UINT32 i = 0; i < numEffects; i++)
    {
        if (effects[i].id == AUDIO_EFFECT_TYPE_DEEP_NOISE_SUPPRESSION)
        {
            // Check if deep noise suppression can be set and if it is currently on
            if (effects[i].canSetState && effects[i].state == AUDIO_EFFECT_STATE_ON)
            {
                HRESULT hr = audioEffectsManager->SetAudioEffectState(effects[i].id, AUDIO_EFFECT_STATE_OFF);

                // If canSetState changed to false, or the effect was removed, SetAudioEffectState
                // can fail with one of the following error codes.
                if (hr != AUDCLNT_E_EFFECT_NOT_AVAILABLE && hr != AUDCLNT_E_EFFECT_STATE_READ_ONLY)
                {
                    return hr;
                }
            }

            return S_OK;
        }
    }

    return S_OK;
}

다음 예제에서는 IAudioEffectsManager.SetAudioEffectState 를 사용하여 AUDIO_EFFECT_TYPE_DEEP_NOISE_SUPPRESSION 효과를 사용하도록 설정하는 방법을 보여 줍니다.

HRESULT TryEnablePlatformDeepNoiseSuppression(_In_ IAudioClient *client)
{
    wil::com_ptr_nothrow<IAudioEffectsManager> audioEffectsManager;
    RETURN_IF_FAILED(client->GetService(IID_PPV_ARGS(&audioEffectsManager)));
    wil::unique_cotaskmem_array_ptr<AUDIO_EFFECT> effects;
    UINT32 numEffects;
    RETURN_IF_FAILED(audioEffectsManager->GetAudioEffects(&effects, &numEffects));

    for (UINT32 i = 0; i < numEffects; i++)
    {
        if (effects[i].id == AUDIO_EFFECT_TYPE_DEEP_NOISE_SUPPRESSION)
        {
            // Check if deep noise suppression can be set and if it is currently off
            if (effects[i].canSetState && effects[i].state == AUDIO_EFFECT_STATE_OFF)
            {
                HRESULT hr = audioEffectsManager->SetAudioEffectState(effects[i].id, AUDIO_EFFECT_STATE_ON);

                // If canSetState changed to false, or the effect was removed, SetAudioEffectState
                // can fail with one of the following error codes.
                if (hr != AUDCLNT_E_EFFECT_NOT_AVAILABLE && hr != AUDCLNT_E_EFFECT_STATE_READ_ONLY)
                {
                    return hr;
                }
            }

            return S_OK;
        }
        }

        return S_OK;
}

다음 코드 예제에서는 오디오 효과 목록이 변경되거나 효과 변경을 사용하도록 설정하는 데 필요한 리소스가 변경될 때 알림을 수신하도록 IAudioEffectsChangedNotificationClient 를 구현하는 클래스를 보여 줍니다. OnAudioStreamEffectsChanged 콜백에서 이 예제에서는 GetAudioEffects를 호출하여 현재 효과 목록을 가져옵니다.

class AudioEffectsChangedHandler :
    public winrt::implements<AudioEffectsChangedHandler, IAudioEffectsChangedNotificationClient>
{

    public:
    AudioEffectsChangedHandler(_In_ IAudioClient *client) : m_client(client){}
    STDMETHOD(OnAudioEffectsChanged)()
    {
        OnAudioStreamEffectsChanged(m_client.get());
        return S_OK;
    }
    private:
    wil::com_ptr_nothrow<IAudioClient> m_client;

};

wil::com_ptr_nothrow<IAudioEffectsChangedNotificationClient> g_effectsChangedHandler;

HRESULT RegisterAudioStreamEffectsChangedEvent(_In_ IAudioClient *client)
{
    if (!g_effectsChangedHandler)
    {
        wil::com_ptr_nothrow<IAudioEffectsManager> audioEffectsManager;
        RETURN_IF_FAILED(client->GetService(IID_PPV_ARGS(&audioEffectsManager)));

        // Register for the audio effects changed notification
        g_effectsChangedHandler = winrt::make<AudioEffectsChangedHandler>(client).get();
        RETURN_IF_NULL_ALLOC(g_effectsChangedHandler);

        return audioEffectsManager->RegisterAudioEffectsChangedNotificationCallback(
            g_effectsChangedHandler.get());
    }
    return S_OK;
}

HRESULT UnregisterAudioStreamEffectsChangedEvent(_In_ IAudioClient *client)
{
    if (g_effectsChangedHandler != nullptr)
    {
        wil::com_ptr_nothrow<IAudioEffectsManager> audioEffectsManager;
        RETURN_IF_FAILED(client->GetService(IID_PPV_ARGS(&audioEffectsManager)));

        // Unregister from the audio effects changed notification 
        return audioEffectsManager->UnregisterAudioEffectsChangedNotificationCallback(
            g_effectsChangedHandler.get());
        }

        return S_OK;
}

HRESULT OnAudioStreamEffectsChanged(_In_ IAudioClient *client)
{
    // Re-query the list of effects since there was some change
    wil::com_ptr_nothrow<IAudioEffectsManager> audioEffectsManager;
    RETURN_IF_FAILED(client->GetService(IID_PPV_ARGS(&audioEffectsManager)));
    wil::unique_cotaskmem_array_ptr<AUDIO_EFFECT> effects;
    UINT32 numEffects;
    RETURN_IF_FAILED(audioEffectsManager->GetAudioEffects(&effects, &numEffects));

    for (UINT32 i = 0; i < numEffects; i++)
    {

        // Here the app can check which effects are still enabled, and check if there are new
        // effects that now can be enabled.
        // As an example, the following code enables any effect that can be enabled, if it is not
        // already enabled.
        if (effects[i].canSetState && effects[i].state == AUDIO_EFFECT_STATE_OFF)
        {
            HRESULT hr = audioEffectsManager->SetAudioEffectState(effects[i].id, AUDIO_EFFECT_STATE_ON));
            if (hr == AUDCLNT_E_EFFECT_NOT_AVAILABLE || hr == AUDCLNT_E_EFFECT_STATE_READ_ONLY)
            {
                hr = S_OK;
            }
            RETURN_IF_FAILED(hr);

        }
    }

    return S_OK;
}

요구 사항

요구 사항
지원되는 최소 클라이언트 Windows 빌드 22000
머리글 audioclient.h