IAudioEffectsManager
COM公式ドキュメント
オーディオエフェクトパイプラインの管理機能を提供します
解説(Remarks)
このインターフェイスのインスタンスは、IAudioEffectsManager インターフェイスのインターフェイスポインターを渡して IAudioClient::GetService を呼び出すことで取得します。
wil::com_ptr_nothrow<IAudioEffectsManager> audioEffectsManager;
RETURN_IF_FAILED(client->GetService(IID_PPV_ARGS(&audioEffectsManager)));
例
次の例は、IAudioEffectsManager.GetAudioEffects を使用して、指定したオーディオストリームに AUDIO_EFFECT_TYPE_DEEP_NOISE_SUPPRESSION エフェクトが存在するかどうかを検出する方法を示します。
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;
}
メソッド 4
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
AudioEffectsChangedNotificationClient インターフェイスを登録します。
| client | IAudioEffectsChangedNotificationClient* | in | 登録する IAudioEffectsChangedNotificationClient インターフェイス。 |
戻り値
| 値 | 説明 |
|---|---|
| S_OK | 成功 |
| AUDCLNT_E_DEVICE_INVALIDATED | 関連付けられたオーディオストリームが破棄されました。 |
解説(Remarks)
コールバックインターフェイスの登録を解除するには、UnregisterAudioEffectsChangedNotificationCallback を呼び出します。
例
次のコード例は、オーディオエフェクトの一覧が変化したとき、またはエフェクトを有効にするために必要なリソースが変化したときに通知を受け取るために 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;
}
IAudioEffectsChangedNotificationClient インターフェイスの登録を解除します。
| client | IAudioEffectsChangedNotificationClient* | in | 登録を解除する IAudioEffectsChangedNotificationClient インターフェイス。 |
戻り値
| 値 | 説明 |
|---|---|
| S_OK | 成功 |
| AUDCLNT_E_DEVICE_INVALIDATED | 関連付けられたオーディオストリームが破棄されました。 |
解説(Remarks)
コールバックインターフェイスを登録するには、RegisterAudioEffectsChangedNotificationCallback を呼び出します。
関連付けられたオーディオストリームの現在のオーディオエフェクトの一覧を取得します。
| effects | AUDIO_EFFECT** | out | 現在のオーディオエフェクトの一覧を表す AUDIO_EFFECT 構造体の配列へのポインターを受け取ります。 |
| numEffects | DWORD* | inout | effects で返される AUDIO_EFFECT 構造体の数を受け取ります。 |
戻り値
以下を含む(ただしこれらに限定されない)HRESULT を返します。
| 値 | 説明 |
|---|---|
| S_OK | 成功 |
| AUDCLNT_E_DEVICE_INVALIDATED | 関連付けられたオーディオストリームが破棄されました。 |
解説(Remarks)
配列の解放は呼び出し元が CoTaskMemFree を使用して行う責任があります。
オーディオエフェクトの一覧が変化したときに通知を受け取るには、IAudioEffectsChangedNotificationClient を登録します。
例
次の例は、IAudioEffectsManager.GetAudioEffects を使用して、指定したオーディオストリームに AUDIO_EFFECT_TYPE_DEEP_NOISE_SUPPRESSION エフェクトが存在するかどうかを検出する方法を示します。
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 メソッド (audioclient.h) は、指定したオーディオエフェクトの状態を設定します。
| effectId | GUID | in | 状態を変更するエフェクトの GUID 識別子。オーディオエフェクトの GUID は ksmedia.h で定義されています。 |
| state | AUDIO_EFFECT_STATE | in | 設定する状態を指定する AUDIO_EFFECT_STATE 列挙型の値。 |
戻り値
以下を含む(ただしこれらに限定されない)HRESULT を返します。
| 値 | 説明 |
|---|---|
| S_OK | 成功 |
| AUDCLNT_E_EFFECT_NOT_AVAILABLE | 指定したエフェクトは利用できません |
| AUDCLNT_E_EFFECT_STATE_READ_ONLY | 指定したエフェクトの状態は読み取り専用です |
| AUDCLNT_E_DEVICE_INVALIDATED | 関連付けられたオーディオストリームが破棄されました。 |
解説(Remarks)
関連付けられたオーディオストリームの現在のオーディオエフェクトの一覧を取得するには、GetAudioEffects を呼び出します。
例
次の例は、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;
}
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IAudioEffectsManager "{4460B3AE-4B44-4527-8676-7548A8ACD260}" #usecom global IAudioEffectsManager IID_IAudioEffectsManager "{}" #comfunc global IAudioEffectsManager_RegisterAudioEffectsChangedNotificationCallback 3 sptr #comfunc global IAudioEffectsManager_UnregisterAudioEffectsChangedNotificationCallback 4 sptr #comfunc global IAudioEffectsManager_GetAudioEffects 5 var,var #comfunc global IAudioEffectsManager_SetAudioEffectState 6 int,int ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IAudioEffectsManager "{4460B3AE-4B44-4527-8676-7548A8ACD260}" #usecom global IAudioEffectsManager IID_IAudioEffectsManager "{}" #comfunc global IAudioEffectsManager_RegisterAudioEffectsChangedNotificationCallback 3 sptr #comfunc global IAudioEffectsManager_UnregisterAudioEffectsChangedNotificationCallback 4 sptr #comfunc global IAudioEffectsManager_GetAudioEffects 5 sptr,sptr #comfunc global IAudioEffectsManager_SetAudioEffectState 6 int,int ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。