=================================
=================================
=================================
출처: http://www.misofruit.co.kr/seojewoo/programming/direct5.htm
DirectSound 객체 Interface
1)
* IUnknown : 모든 COM object들의 base COM object
* IDirectSound : DirectSound의 main object로서 audio hardware를 나타낸다.
어떤 컴퓨터에는 하나 이상의 사운드 카드가 있는데 그럴 경우에는 각 카드마다 DirectSound object를 필요로한다.
* IDirectSoundBuffer : 실제 sound와 hardware의 mixing.
두가지 종류의 버퍼가 있다.-primary와 secondary
primary buffer는 현재 play되고 있는 mixed된 사운드 버퍼이고 secondary buffer는 play하기 위한 sound를 저장하고 있는 buffer이다.
* IDirectSoundCapture : 이번 강의에서는 이 interface를 사용하지 않는다.이 interface는 sound capture나 recording에 사용하고 실시간으로 voice를 capture할 수도 있다.
* IDirectSoundNotify : 이것은 DirectSound로 message들을 돌려보낸다. 복잡한 sound system을 가지고 있는 게임에서 필요하지만 이것을 사용하지 않고도 프로그램을 짤 수 있다.
DirectSound를 이용한 효과음 출력
a. Creating a DirectSound object
LPDIRECTSOUND lpds; //DirectSound interface pointer
|
< 실제 사용예 >
LPDIRECTSOUND lpds; if(DirectSoundCreate(NULL, &lpds, NULL)!=DS_OK)
|
b. Setting the cooperation level
HRESULT SetCooperativeLevel(HWND hwnd,//window handle
|
DSSCL_NORMAL : 모든 것들과 같이 동작하는 상태로 설정하며, 일반적으로 대부분의 프로그램들이 이 레벨을 지정한다. 이렇게 하는 이유는 멀티 태스킹이나 리소스 공유 등이 용이하기 때문이다.
DSSCL_PRIORITY : 프로그램을 우선 순위 레벨로 설정한다. 이 레벨로 설정이 되었을 경우에는 IDirectSoundBufffer::SetFormat와 IDirectSound::Compact를 호출할 수 있다.
DSSCL_EXCLUSIVE : 프로그램을 배타적(EXCLUSIVE)인 레벨로 설정한다.
DSSCL_WRETEPRIMARY : 가장 최상위 레벨로서 최상위 버퍼로의 쓰기 접근 권한을 가지게 된다.
< 사용 예 >
if(lpds->SetCooperativeLevel(main_window_handle,DSSCL_NORMAL)!=DS_OK)
|
이제 DirectSound의 객체를 생성하고 프로세서 독점에 관한 레벨을 설정하였으면 사운드 버퍼를 생성하고 필요한 파일을 불러들여서 스피커로 출력하는 작업만 남았다.
c. Creating Sound Buffers
사운드 버퍼를 생성하기 위해서는 IDirectSound::CreateSoundBuffer의 인자로 사용되 는 DSBUFFERDESC 구조체를 관련된 값으로 설정한후 IDirectSound::CreateSoundBuffer의 호출시에 인자로 넘겨주면 비로소 사운드 버퍼가 생성된다.
< DSBUFFERDESC 구조체 >
typedef struct{ DWORD dwSize; DWORD dwFlags; DWORD dwBufferBytes; DWORD dwReserved; LPWAVEFORMATEX lpwfxFormat; } DSBUFFERDESC, *LPDSBUFFERDESC; |
* dwSize : 구조체의 크기
* dwFlags : DirectSoundBuffer의 객체를 생성할 때 사용되는 특성들을 지정하며, 다음의 플래그들의 조합을 이용하게 된다.
DSBCAPS_CTRLALL-버퍼가 모든 특성에 대한 제어권을 가지게 된다.
DSBCAPS_CTRLDEFAULT-기본적인 제어권을 가지게 된다. 이것은 DSBCAPS_CTRLPAN,DSBCAPS_CTRLVOLUME, DSBCAPS_CTRLFREQUENCY 플래그를 명시한 것과 동일하다.
DSBCAPS_CTRLFREQUENCY-버퍼가 주파수에 대한 제어권을 가지게 된다.
DSBCAPS_CTRLPAN-버퍼가 팬(pan)의 제어권을 가지게 된다.
DSBCAPS_CTRLVOLUME-버머가 볼륨의 제어권을 가지게 된다.
DSBCAPS_PRIMARYBUFFER-버퍼가 최상위 사운드 버퍼임을 지시한다. 이 플래그가 지시되지 않는다면, 제2의 사운드 버퍼가 생성된 것이다.
DSBCAPS_STATIC-버퍼가 스태틱한 사운드 데이터를 사용하도록한다. 일반적으로 이러한 버퍼들은 한번 로드한 후에 많은 수의 play를 하게된다. 이러한 버퍼들은 하드웨어 메모리를 사용한다.
DSBCAPS_LOCHARDWARE-DSBCAPS_STATIC가 명시되지 않은 경우에도 버퍼가 하드웨어 믹싱을 사용하도록 지정한다. 사운드 장치가 하드웨어 믹싱을 지원하지 않거나 사용가능한 하드웨어 메모리가 부족하다면 IDirectSound::CreateSoundBuffer의 호출은 실패한다.
DSBCAPS_LOCSOFTWARE-하드웨어 리소스가 사용가능하고 DSBCAPS_STATIC이 명시된 경우에도 버퍼가 소프트웨어 메모리 상에 위치하도록 지시하며, 소프트웨어 믹싱을 사용하도록 지시한다.
대부분의 경우에서 DSBCAPS_CTRLDEFAULT | DSBCAPS_STATIC | DSBCAPS_LOCSOFTWARE를 사용한다.
* dwBufferBytes : 새로운 버퍼의 크기이다. 최상위 버퍼를 생성할 때는 반드시 0이어야 한다. 제2의 버퍼에 대해서는 DSBSIZE_MIN과 DSBSIZE_MAX를 이용하여 최소한의 크기와 최대한의 크기를 지정할 수 있다.
* dwReserved : 사용되지 않는다.
* lpwfxFormat : 버퍼에 대해 웨이브 형태의 형식을 설정하기 위한 정보를 가지고 있는 구조체의 포인터이다. 이값은 최상위 버퍼에 대해서는 반드시 NULL이 되어야 한다. 프로그램은 IDirectSoundBuffer::SetFormat을 이용하여 최상위 버퍼에 대한 형식을 설정할 수 있다.
WAVEFORMAT 구조체
이 구조체는 웨이브 셩식의 오디오 데이터에 대한 정보를 명시한다.
typedef struct{
|
* wFormatTag : 데이터의 형식을 지시하며, 다음에 나오는 형식이 사용된다.
WAVE_FORMAT_PCM : 웨이브 형식의 오디오 데이터가 PCM 형식이다.
* nChannels : 웨이브 형식의 오디오 데이터에서 사용하는 채널의 개수를 지시한다. 모노 데이터는 하나의 채널을 사용하며, 스테레오 데이터는 두 개의 채널을 사용한다.
* nSamplesPerSec : 샘플링 비율을 의미한다.
* nAvgBytesPerSec : 평균적인 데이터전송율로서 초당 바이트의 수치로서 사용된다.
* nBlockAlign : 바이트 단위의 블록의 크기
이제 IDirectSound::CreateSoundBuffer로 들어가자. 이 함수는 DirectSoundBuffer의 객체를 생성하는데 사용되며, 원형은 다음과 같다.
HRESULT CreateSoundBufffer(
|
* lpcDSBufferDesc : 생성되는 사운드 버퍼에 대한 특성을 가지고 잇는 DSBUFFERDESC 구조체의 포인터이다.
* lplpDirectSoundBuffer : 호출이 성공적이면, 생성되는 DirectSoundBuffer의 객체를 되돌릴 포인터이다.
* pUnkOuter : NULL
d. 버퍼의 잠금과 해제
지금까지의 작업으로 사운드 버퍼까지 생성을 하였다. 이제 필요한 웨이브 사운드 파일을 불러들여와서 스피커를 통큁여 출력을 하면 된다. 이러한 사운드의 출력을 위해서는 우선적으로 IDirectSoundBuffer::Lock을 이용하여 사운드 버퍼에 대해 잠금을 하며, 잠금이 되었을 경우 오디오 데이터를 버퍼에 쓰고, 다시 IDirectSounBuffer::Unlock을 이용하여 사운드 버퍼의 잠금을 해제해야한다.
그럼 이제 IDirectSoundBuffer::Lock에 대해 알아보자.
HRESULT Lock(
|
* dwWriteCursor : 버퍼에서 잠금이 시작되는 부분의 바이트 단위의 오프셋, dwFlags에 DSBLOCK_FROMWRITECURSOR가 사용되었다면 이 파라미터는 무시된다.
* dwWritebytes : 잠금이 되는 부분의 바이트 단위의 크기
* lplpvAudioPtr1 : 잠금이 되는 사운드 버퍼의 첫번째 블록이 되돌려질 포인터
* lpdwAudioBytes1 : lplpvAudioPtr1에 의해서 지시된 부분의 바이트 안위의 크기를 되돌릴 포인터, 이값이 dwWriteBytes보다 작다면, lplpvAudioPtr2는 사운드 데이터의 두 번째 블록을 지시할 것이다.
* lplpvAudioPtr2 : 잠금이 되는 사운드 버퍼의 두 번째 블록이 되돌려질 포인터.
이 값이 NULL일 경우, lplpvAudioPtr1은 사운드 버퍼의 잠금이 되는 전체의 부분을 지시한다.
* lpdwAudioBytes2 : lplpvAudioPtr2에 의해서 지시된 바이트 단위의 크기를 되돌릴 포인터.
lplpvAudioPtr2가 NULL이라면, 이값은 0이 된다.
* dwFlags : 잠금을 하기 위한 플래그이며, 다음의 플래그들이 사용된다.
DSBLOCK_FROMWRITECURSOR : 현재 쓰기를 하는 부분에서부터 잠금을 한다. 이 플래그가 사용되는 경우에는 dwWriteCursor 파라미터의 값이 무시된다.
DSBLOCK_ENTIREBUFFER : 버퍼 전체에 대해 잠금을 한다. dwWriteBytes 파라미터가 무시된다.
다음으로 잠금을 한 사운드 버퍼를 해제시키는 함수 IDirectSoundBuffer::Unlock에 대해 공부하자.
HRESULT Unlock(
|
* lpAudioPtr1 : IDirectSounBuffer:Lock에서 lplpvAudioPtr1으로되돌려진 포인터
* dwAudioBytes1 : lpvAudioPtr1으로 실제적으로 쓰여진 바이트의 개수
* lpvAudioPtr2 : IDirectSoundBuffer::Lock에서 lplpvAdioPtr2로 되돌려진 포인터
* dwAudioBytes2 : lpvAudioPtr2로 실제적으로 쓰여진 바이트의 개수
=================================
=================================
=================================
'프로그래밍 관련 > 사운드' 카테고리의 다른 글
DirectSound C++ Document (0) | 2020.09.19 |
---|---|
다이렉트사운드(DirectSound) 관련 (0) | 2020.09.17 |
D3Direct Sound 관련 (0) | 2020.09.17 |
DSound 사용시 1차 버퍼를 그대로 사용하면 안됩니다.|작성자 제프 Direct Sound 동시 사운드 (동시 믹싱 예상) (0) | 2020.09.17 |
OGG 재생 어떻게들 하시나요? (gpg 사이트) (0) | 2020.09.17 |