프로그래밍 관련/사운드

DirectSound 설명(best) 관련

AlrepondTech 2020. 9. 17. 10:33
반응형

 

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: 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
        DirectSound 생성 함수 원형

        HRESULT DirectSound Create(LPGUID lpGuid,
 
        //GUID of sound card

            //NULL:default device
          LPDIRECTSOUND *lpDS,//pointer

        IUnknown *pUnkOuter)//always NULL



< 실제 사용예 >

 

LPDIRECTSOUND lpds;
if(DirectSoundCreate(NULL, &lpds, NULL)!=DS_OK)

      {/*error*/}

b. Setting the cooperation level

HRESULT SetCooperativeLevel(HWND hwnd,//window handle
            DWORD dwLevel);//cooperation level setting

DSSCL_NORMAL : 모든 것들과 같이 동작하는 상태로 설정하며, 일반적으로 대부분의 프로그램들이 이 레벨을 지정한다. 이렇게 하는 이유는 멀티 태스킹이나 리소스 공유 등이 용이하기 때문이다.

DSSCL_PRIORITY : 프로그램을 우선 순위 레벨로 설정한다. 이 레벨로 설정이 되었을 경우에는 IDirectSoundBufffer::SetFormat와 IDirectSound::Compact를 호출할 수 있다.

DSSCL_EXCLUSIVE : 프로그램을 배타적(EXCLUSIVE)인 레벨로 설정한다.

DSSCL_WRETEPRIMARY : 가장 최상위 레벨로서 최상위 버퍼로의 쓰기 접근 권한을 가지게 된다.

< 사용 예 >

if(lpds->SetCooperativeLevel(main_window_handle,DSSCL_NORMAL)!=DS_OK)
      {/*error*/}

이제 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 구조체

이 구조체는 웨이브 셩식의 오디오 데이터에 대한 정보를 명시한다.

 

 

 

 

반응형

 

728x90

 

 

 

typedef struct{
        DWORD wFormatTag;

        DWORD nChannels;

        DWORD nSamplesPerSec;

        DWORD nAvgBytesPerSec;

        WORD nBlockAlign;

      } WAVEFORMAT;

* wFormatTag : 데이터의 형식을 지시하며, 다음에 나오는 형식이 사용된다.

WAVE_FORMAT_PCM : 웨이브 형식의 오디오 데이터가 PCM 형식이다.

* nChannels : 웨이브 형식의 오디오 데이터에서 사용하는 채널의 개수를 지시한다. 모노 데이터는 하나의 채널을 사용하며, 스테레오 데이터는 두 개의 채널을 사용한다.

* nSamplesPerSec : 샘플링 비율을 의미한다.

* nAvgBytesPerSec : 평균적인 데이터전송율로서 초당 바이트의 수치로서 사용된다.

* nBlockAlign : 바이트 단위의 블록의 크기

이제 IDirectSound::CreateSoundBuffer로 들어가자. 이 함수는 DirectSoundBuffer의 객체를 생성하는데 사용되며, 원형은 다음과 같다.

HRESULT CreateSoundBufffer(
            LPCDSBUFFERDESC lpcDSBufferDesc,
 
          LPLPDIRECTSOUNDBUFFER lplpDirectSoundBuffer,IUnknown *pUnkOuter);

* lpcDSBufferDesc : 생성되는 사운드 버퍼에 대한 특성을 가지고 잇는 DSBUFFERDESC 구조체의 포인터이다.

* lplpDirectSoundBuffer : 호출이 성공적이면, 생성되는 DirectSoundBuffer의 객체를 되돌릴 포인터이다.

* pUnkOuter : NULL

d. 버퍼의 잠금과 해제

지금까지의 작업으로 사운드 버퍼까지 생성을 하였다. 이제 필요한 웨이브 사운드 파일을 불러들여와서 스피커를 통큁여 출력을 하면 된다. 이러한 사운드의 출력을 위해서는 우선적으로 IDirectSoundBuffer::Lock을 이용하여 사운드 버퍼에 대해 잠금을 하며, 잠금이 되었을 경우 오디오 데이터를 버퍼에 쓰고, 다시 IDirectSounBuffer::Unlock을 이용하여 사운드 버퍼의 잠금을 해제해야한다.

그럼 이제 IDirectSoundBuffer::Lock에 대해 알아보자.

HRESULT Lock(
        DWORD dwWriteCursor,

        DWORD dwWriteBytes,

        LPVOID lplpvAudioPtr1,

        LPDWORD lpdwAudioBytes1,

        LPVOID lplpvAudioPtr2,

        LPDWORD lpdwAudioBytes2,

      DWORD dwFlags);

* 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(
        LPVOID lpvAudioPtr1,

        DWORD dwAudioBytes1,

        LPVOID lpvAudioPtr2,

      DWORD dwAudioBytes2);

* lpAudioPtr1 : IDirectSounBuffer:Lock에서 lplpvAudioPtr1으로되돌려진 포인터

* dwAudioBytes1 : lpvAudioPtr1으로 실제적으로 쓰여진 바이트의 개수

* lpvAudioPtr2 : IDirectSoundBuffer::Lock에서 lplpvAdioPtr2로 되돌려진 포인터

* dwAudioBytes2 : lpvAudioPtr2로 실제적으로 쓰여진 바이트의 개수

 

 

 

=================================

=================================

=================================

 

 

반응형