現在、古い優れたMixer APIを使用していますが、XP互換モードではなく、通常のWindows Vista&7では期待どおりに機能しません。現在のアプリのサウンドのみをミュートしますが、グローバル(ハードウェア)ミュートが必要です。目標を再設定する方法は?純粋なC/C ++で、COMインターフェイスと奇妙な呼び出しなしでこれをコーディングする方法はありますか?
2785 次
2 に答える
4
オーディオ スタックは、Vista 用に大幅に書き直されました。アプリケーションごとの音量とミュート コントロールは、確かに新機能の 1 つです。IAudioEndpointVolume インターフェイスを使用するには、奇妙な呼び出しが必要になります。
于 2010-02-27T15:04:05.703 に答える
0
私は最近、この同じ問題に対処しました。アラームにサウンド システムを使用する Windows アプリケーションがあります。ユーザーが誤ってサウンドシステムをミュートすることは許されません。上記で提案したインターフェースを使用してこの問題に対処する方法は次のとおりです。
初期化中に、IAudioEndpointVolume 型のメンバーを初期化する関数を追加しました。少しトリッキーで、ヘルプはそれほど役に立ちませんでした。方法は次のとおりです。
/****************************************************************************
** Initialize the Audio Endpoint (Only for post XP systems)
****************************************************************************/
void CMuteWatchdog::InitAudioEndPoint(void)
{
HRESULT hr;
IMMDeviceEnumerator * pDevEnum;
IMMDevice * pDev;
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL,
CLSCTX_ALL, IID_IMMDeviceEnumerator,
(void**)&pDevEnum);
m_pIaudEndPt = NULL;
if(hr == S_OK)
{
hr = pDevEnum->GetDefaultAudioEndpoint(eRender, eConsole, &pDev);
if(hr == S_OK)
{
DWORD dwClsCtx;
const IID iidAEV = __uuidof(IAudioEndpointVolume);
dwClsCtx = 0;
hr = pDev->Activate(iidAEV, dwClsCtx, NULL, (void**) &m_pIaudEndPt);
if(hr == S_OK)
{
// Everything is groovy.
}
else
{
m_pIaudEndPt = NULL; // Might mean it's running on XP or something. Don't use.
}
pDev->Release();
}
pDevEnum->Release();
}
}
...
約 1 秒に 1 回、次のような単純な呼び出しを追加しました。
////////////////////////////////////////////////////////////////////////
// Watchdog function for mute.
void CMuteWatchdog::GuardMute(void)
{
if(m_pIaudEndPt)
{
BOOL bMute;
HRESULT hr;
bMute = FALSE;
hr = m_pIaudEndPt->GetMute(&bMute);
if(hr == S_OK)
{
if(bMute)
{
m_pIaudEndPt->SetMute(FALSE, NULL);
}
}
}
}
最後に、プログラムが終了するときは、割り当てられたリソースを解放することを忘れないでください。
////////////////////////////////////////////////////////////////////////
// De-initialize the watchdog
void CMuteWatchdog::OnClose(void)
{
if(m_pIaudEndPt)
{
m_pIaudEndPt->Release();
m_pIaudEndPt = NULL;
}
}
于 2014-06-17T17:01:57.500 に答える