【问题标题】:How to globally mute and unmute sound in Vista and 7, and to get a mute state?如何在Vista和7中全局静音和取消静音,并获得静音状态?
【发布时间】:2011-01-21 17:52:18
【问题描述】:

我现在正在使用旧的好的 Mixer API,但它在 Windows Vista 和 7 上无法正常工作,而不是在 XP 兼容模式下。它只为当前应用程序静音,但我需要一个全局(硬件)静音。如何达到目标?有没有什么方法可以在纯 C/C++ 中编写没有 COM 接口和奇怪调用的代码?

【问题讨论】:

    标签: c++ c audio windows-vista mixer


    【解决方案1】:

    我最近处理了同样的问题。我们有一个使用声音系统进行警报的 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();
       }
    }
    

    ...

    大约每秒一次,我添加了一个对以下内容的简单调用:

    ////////////////////////////////////////////////////////////////////////
    // 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;
       }
    }
    

    【讨论】:

      【解决方案2】:

      为 Vista 重写了音频堆栈。每个应用程序的音量和静音控制确实是新功能之一。陌生电话需要使用IAudioEndpointVolume interface

      【讨论】:

      • 您能否为上述问题提供一个工作示例?有没有什么方法可以弃用 COM,用纯 C 或 C++ 编写代码?
      • 如果您以前从未编写过任何 COM 代码,那么您已经过上了幸福的生活。没有办法解决它。您可以从设计界面的人那里获得代码示例。链接:blogs.msdn.com/larryosterman/archive/2007/03/06/…
      猜你喜欢
      • 2018-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-31
      • 1970-01-01
      • 1970-01-01
      • 2011-12-09
      相关资源
      最近更新 更多