3

現在、古い優れたMixer APIを使用していますが、XP互換モードではなく、通常のWindows Vista&7では期待どおりに機能しません。現在のアプリのサウンドのみをミュートしますが、グローバル(ハードウェア)ミュートが必要です。目標を再設定する方法は?純粋なC/C ++で、COMインターフェイスと奇妙な呼び出しなしでこれをコーディングする方法はありますか?

4

2 に答える 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 に答える