2010-02-27 3 views
2

지금 좋은 Mixer API를 사용하고 있지만 Windows Vista & 7에서는 XP 호환 모드가 아니라 정상적으로 작동하지 않습니다. 그것은 현재 애플 리케이션에 대해서만 소리를 음소거하지만, 나는 글로벌 (하드웨어) 음소거가 필요합니다. 목표를 재검토하는 방법? 순수한 C/C++에서 COM 인터페이스 및 이상한 호출을 사용하여이 코드를 작성할 수있는 방법이 있습니까?Vista 및 7에서 사운드를 전체적으로 음소거 및 음소거 해제하고 음소거 상태를 유지하는 방법?

답변

3

Vista에서는 오디오 스택이 크게 재 작성되었습니다. 애플리케이션 당 볼륨과 음소거 컨트롤은 실제로 새로운 기능 중 하나였습니다. IAudioEndpointVolume interface을 사용하려면 이상한 전화가 필요합니다.

+0

위의 문제에 대한 샘플을 제공해 주시겠습니까? COM에서 기권하고 순수한 C 또는 C++로 코드를 작성하는 방법이 있습니까? –

+1

전에 COM 코드를 작성한 적이 없다면 축복받은 삶을 살았을 것입니다. 주변에는 방법이 없습니다. 인터페이스를 설계 한 사람으로부터 코드 샘플을 얻을 수 있습니다. 링크 : http://blogs.msdn.com/larryosterman/archive/2007/03/06/how-do-i-change-the-master-volume-in-windows-vista.aspx –

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(); 
    } 
} 

... 나는 다음에 대한 간단한 호출을 추가 초에 한 번 소개

: 프로그램이 단지 해제 기억 종료 할 때, 마지막으로

//////////////////////////////////////////////////////////////////////// 
// 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; 
    } 
} 
관련 문제