본문 바로가기

Programming/DirectX

[DirectSound] 3. DirectSound의 사운드 카드 열거

반응형

이전 글에서 DirectSound가 재생할 재료가 되는 Wave의 전체적인 구조를 확인했습니다.

DirectSound는 DirectX를 구성하는 기술 중 한 가지입니다.

소리의 재생과 녹음을 담당하는 기능을 포함하고 있습니다.

사운드를 재생하는데는 사운드 카드가 필요합니다.

최근에는 대부분 메인보드에서 기본으로 제공되는 내장 사운드 카드를 사용합니다.

기본적으로 사운드 카드는 한 개를 주로 사용하기 때문에 장치 열거가 필요없는 경우가 다수입니다.

다만 여러 개의 사운드 카드가 설치되어 있고 특정 장치를 통해서 재생을 하고 싶은 경우에 장치 열거가 필요합니다.

장치 열거를 위해서 다음과 같은 형태의 콜백 함수(Callback Function)이 필요합니다.

BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext)

함수의 이름은 자유롭게 변경이 가능합니다.

열거를 계속하기 위해서는 TRUE를 리턴해야 하고 중단하고 싶을 경우에는 FALSE를 리턴하면 됩니다.

처음 3개의 인자는 OS에서 제공하기 때문에 전달된 값을 사용하기만 하면 됩니다.

마지막 값은 호출할 때 넘겨주고 싶은 값을 넘겨주면 됩니다.

4byte(64bit 환경에서는 8byte) 값을 전달할 수 있기 때문에 컨트롤의 핸들 등을 전달할 때 사용하면 됩니다.

DirectSoundEnumerate()를 호출해서 장치 열거가 가능합니다.

전체 소스 코드는 다음과 같이 작성하면 됩니다.

#include <Windows.h>
#include <dsound.h>
#include <iostream>
#include <vector>
#include <tuple>
#include <string>

#pragma comment(lib, "dsound")

typedef std::tuple<GUID, std::wstring, std::wstring> DeviceTuple;

BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCTSTR lpcstrDescription, LPCTSTR lpcstrModule, LPVOID lpContext)
{
	auto vSoundDevice = reinterpret_cast<std::vector<DeviceTuple>*>(lpContext);
	std::wcout.imbue(std::locale(""));
	std::wcout << lpcstrDescription << std::endl;

	GUID guid;
	memset(&guid, 0x00, sizeof(guid));
	if (nullptr != lpGuid)
	{
		memcpy(&guid, lpGuid, sizeof(guid));
	}
	vSoundDevice->push_back(std::make_tuple(guid, std::wstring(lpcstrDescription), std::wstring(lpcstrModule)));

	return TRUE;
}

int main()
{
	std::vector<DeviceTuple> vSoundDevice;
	DirectSoundEnumerate((LPDSENUMCALLBACK)DSEnumCallback, (LPVOID)&vSoundDevice);

	return 0;
}

간단히 확인할 수 있도록 콘솔에서 작동되도록 코드를 작성했습니다.

헤더가 많이 추가가 되었지만 중요한 헤더는 dsound.h 입니다.

그리고 dsound.lib를 반드시 추가해야 합니다.

콜백 함수가 전달하는 값을 저장하기 위해서 tuple을 사용했습니다.

main에서 생성한 vSoundDevice를 포인터로 전달해서 사용할 수 있도록 했습니다.

그리고 콜백 함수 내부에서는 vector 타입으로 lpContext를 다시 변경하고 값을 입력하도록 했습니다.

DirectSoundEnumerate()가 호출이 종료된 이후에 vector 안에 사운드 카드의 정보가 저장되어 있습니다.

참고로 처음에 열거되는 장치는 항상 Primary Sound Driver(주 사운드 드라이버)입니다.

그리고 LPGUID 값은 NULL이 전달됩니다.

GUID 값은 나중에 실제 장치를 열 때 사용하게 되는 값입니다.

그렇기 때문에 NULL이 전달되면 주 사운드 드라이버인 기본 사운드 카드를 통해서 재생이 됩니다.

반응형