본문 바로가기

Library/Windows Programming

비스타 이상에서 사운드 출력 레벨 설정하기

웨이브 출력 레벨을 설정하는 waveoutGetVolume, waveoutSetVolume은, XP까지는 잘 통용되는 방법이었지만 비스타 이상에서는 제대로 동작하지 않는다. 비스타 이상에서는 사운드 출력을 관리하는 믹서의 구성이 좀 더 복잡해졌기 때문에, waveout 관련 API를 호출해보면 MMSYSERR_NOTSUPPORT와 같은 에러를 받을 것이다. 이들 윈도우는 응용 프로그램 각각에 대해서 오디오 믹서 조절이 가능해졌는데, 사용자들에게는 다채로운 기능이지만 개발자에게는 약간 고달퍼진 셈이다. 그렇지만 조금 귀찮아졌을 뿐 사운드 출력 레벨 설정은 어렵지 않다. 사운드 출력 레벨을 조절하고 싶다면 다음 과정을 처리해주면 된다. COM 인터페이스를 사용해야 하는게 기존과 조금 달라진 부분이다.

먼저, IMMDeviceEnumerator 인터페이스를 생성한다. 그리고, IMMDeviceEnumerator::GetDefaultAudioEndpoint 인터페이스로 IMMDevice 인터페이스를 얻어낸 뒤, 이 인터페이스를 통해 얻어진 유효한 디바이스를 활성화시킨다. 볼륨을 조절할 수 있는 인터페이스는 IAudioEndpointVolume인데, 이것을 통해 볼륨을 조절할 수 있다. waveoutSetVolume, waveoutGetVolume과 달리 db 단위로 볼륨을 조절할 수 있고, 스칼라 값으로 조절할 수도 있다. waveoutSetVolue, waveGetVolume  함수들이 단순하게 32비트 값에서 워드 단위로 왼쪽, 오른쪽 출력 레벨을 설정하거나 리턴하는 것보다 더 정교해졌다고 할 수 있다. IAudioEndpointVolume은 현재 선택된 디바이스 특성을 자세하게 알아낼 수 있는 방법도 제공한다.

위의 과정을 간단히 코드로 표현하면 다음과 같다.


#include <windows.h>
#include <mmdeviceapi.h>
#nclude <endpointvolume.h>

// 에러 처리, 초기화 코드는 생략
IMMDeviceEnumerator *device_enum;
IMMDevice *device;
IAudioEndpointVolume *vol;

// COM 라이브러리 초기화
....

CoCreateInstance(__uuidof(MMDeviceEnumerator), 0, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (void **)&device);

// eRender, eConsole은 미리 라이브러리에서 미리 정의된 값
device_enum->GetDefaultAutioEndpoint(eRender, eConsole, &device);
device->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, 0, (void **)&vol);
vol->SetMasterVolumeLevelScalar(/* 원하는 값(float) */)

// 각 인터페이스 해제, COM 라이브러리 정리 작업
....