directsound 프로그래밍

22
DirectSound 프프프프프 DirectSound 프 프프프프 프프 프프 프프 프프프 프프프프 프프 프 , 프프프프프프프프 프프프프 프프프프 프프프프 프프프 프 프프 . DirectSound 프프프프프프 프프프프 프프프 프프 프프프 프프프프 프프 . WAV 프프프 프프 프프 프프프프프프 프프프프 프프프프 . 프프프 프프프프 프프프 프프프프 . 프프프프프프 프프프 3D 프프프 프프프프 프프프프 . 프프프프 프프프 프프 프프프프 프프프 , 프프프프 프프프프프 프프프프 프프프프 . 프프프 프프 프 프프 프프프프프프 WAV 프프프프 프프프프 .

Upload: nathalie-dumont

Post on 30-Dec-2015

106 views

Category:

Documents


0 download

DESCRIPTION

DirectSound 프로그래밍. DirectSound 를 사용하면 매우 짧은 지연 시간에 사운드를 재생해, 애플리케이션으로 하드웨어 리소스를 치밀하게 제어할 수 있다. DirectSound 인터페이스를 사용하여 다음과 같은 처리가 가능하게 된다. WAV 포맷의 파일 또는 리소스로부터 사운드를 재생한다. 복수의 사운드를 동시에 재생한다. 커스터마이즈 가능한 3 D 환경에 사운드를 배치한다. 메아리나 코러스 등의 이펙트를 추가해, 이펙트의 파라미터를 동적으로 변경한다. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: DirectSound  프로그래밍

DirectSound 프로그래밍 DirectSound 를 사용하면 매우 짧은 지연 시간에

사운드를 재생해 , 애플리케이션으로 하드웨어 리소스를 치밀하게 제어할 수 있다 .

DirectSound 인터페이스를 사용하여 다음과 같은 처리가 가능하게 된다 .

WAV 포맷의 파일 또는 리소스로부터 사운드를 재생한다 . 복수의 사운드를 동시에 재생한다 . 커스터마이즈 가능한 3D 환경에 사운드를 배치한다 . 메아리나 코러스 등의 이펙트를 추가해 , 이펙트의

파라미터를 동적으로 변경한다 . 마이크 또는 그 외의 입력으로부터 WAV 사운드를

캡춰한다 .

Page 2: DirectSound  프로그래밍

DirectSound 프로그래밍의 순서 장치 개체를 생성 한다 .

DirectSoundCreate8 를 호출해 , IDirectSound8 인터페이스를 지원 하는 개체를 생성 한다 .

이 개체는 보통 디폴트 재생 장치를 나타낸다 . 2 차 버퍼를 생성 한다 .

IDirectSound8::CreateSoundBuffer 를 사용해 사운드 데이터를 보관 유지하는 버퍼 개체를 생성 한다 .

이러한 버퍼는 , 모든 사운드를 믹싱 하는 개체인 1 차 버퍼와 구별하기 위해 , 2 차 버퍼라고 부른다 .

PCM 데이터를 얻어온다 . WAV 파일 또는 리소스로부터 1 차 버퍼에 데이터를 읽어낸다 .

데이터를 버퍼에 저장 한다 . DirectSoundBuffer::Lock 를 호출해 , 쓰기 조작용으로 2 차 버퍼를 준비한

다 . 1 차 버퍼로부터 그 주소에 데이터를 복사 한 후 ,

IDirectSoundBuffer8::Unlock 를 호출한다 . 버퍼를 재생한다 .

IDirectSoundBuffer8::Play 를 호출해 사운드를 재생한다 . 버퍼에 대해서는 , 마지막에 달한 시점에서 정지하는지 , 또는

IDirectSoundBuffer8::Stop 를 호출할 때까지 반복 재생을 계속하는지를 지시할 수 있다 .

같은 데이터를 보관 유지하는 버퍼를 별도 생성하지 않는 한 , 한번에 연주할 수 있는 사운드의 인스턴스는 1 개 뿐이다 .

임의의 수의 버퍼를 한 번에 재생할 수 있는 믹싱은 자동적으로 행해진다 .

Page 3: DirectSound  프로그래밍

DirectSound 장치 개체의 생성 DirectSound 를 사용하기 위해 장치 개체를

초기화를 한다 . DirectSoundCreate 함수 원형

HRESULT WINAPI DirectSoundCreate8( LPCGUID lpcGuidDevice, LPDIRECTSOUND8 * ppDS8, LPUNKNOWN pUnkOuter );

DirectSoundCreate 함수 샘플 코드LPDIRECTSOUND8 lpds; HRESULT hr =

DirectSoundCreate8(NULL, &lpds, NULL));

Page 4: DirectSound  프로그래밍

협조 레벨 설정 DirectSound 에서는 3 종류의 협조 레벨이 ,

사운드 장치에 대해서 정의되고 있다 . DSSCL_NORMAL 표준 협조 레벨

애플리케이션간 장치의 변환이 가장 원활히 행해진다 .

DSSCL_PRIORITY 우선 협조 레벨 거의 모든 게임 애플리케이션에서 사용하며 샘플링 레이트와 비트

깊이에 대한 애플리케이션 제어를 가능하게 하면서 , 가장 강력하게 동작한다 .

DSSCL_WRITEPRIMARY 쓰기 우선 협조 레벨 1 차 버퍼내의 오디오 샘플에 직접 쓰기 액세스를 실시하려면 ,

애플리케이션을 쓰기 우선 레벨로 설정해야 한다 . 애플리케이션이 이 레벨로 설정되지 않은 경우 , 1 차 버퍼에 대한

IDirectSoundBuffer::Lock 메서드의 호출은 모두 실패한다 .

Page 5: DirectSound  프로그래밍

협조 레벨 설정 장치개체를 생성한 후

IDirectSound8::SetCooperativeLevel 메 서드를 사용해 장치 협조 레벨을 설정해야 한다 .

협조레벨을 설정하지 않을 경우 소리가 나지 않는다 .

다음의 예는 lpds 에 의 DirectSound 인터페이스에 의해 나타내지는 DirectSound 의 장치 협조 레벨을 설정하고 있다 .

hwnd 파라미터는 , 애플리케이션 윈도우의 핸들이다 .

HRESULT hr = lpDirectSound->SetCooperativeLevel(hwnd, DSSCL_PRIORITY); if (FAILED(hr)) {

ErrorHandler(hr); // 에러 처리를 여기에 추가한다 . }

Page 6: DirectSound  프로그래밍

버퍼의 설정 DSBUFFERDESC 구조체는 , 새로운 버퍼 개체의 특성을

기술한다 . IDirectSound8::CreateSoundBuffer 메서드 및

DirectSoundFullDuplexCreate8 함수로 사용된다 . typedef struct {

DWORD dwSize; DWORD dwFlags; DWORD dwBufferBytes; DWORD dwReserved; LPWAVEFORMATEX lpwfxFormat; GUID guid3DAlgorithm;

} DSBUFFERDESC, *LPDSBUFFERDESC; typedef const DSBUFFERDESC *LPCDSBUFFERDESC;

Page 7: DirectSound  프로그래밍

버퍼의 설정 DSBUFFERDESC 구조체 멤버

dwSize 구조체의 사이즈 . 사용하기 전에 , 이 멤버를 초기화해야 한다 .

dwFlags 버퍼의 능력을 나타내는 플래그

dwBufferBytes 새로운 버퍼의 사이즈 ( 바이트 단위 ) 1 차 버퍼를 생성할 때는 0 을 설정 .

dwReserved 예약이 끝난 상태 . 0 이 아니면 안된다 .

lpwfxFormat 버퍼의 웨이브 폼 포맷을 지정하는 WAVEFORMATEX 구조체 또는

WAVEFORMATEXTENSIBLE 구조체의 주소 1 차 버퍼에서는 , 이 값은 NULL 이어야 한다 . 애플리케이션은 IDirectSoundBuffer::SetFormat 를 사용해 , 1 차

버퍼의 포맷을 설정할 수 있다 . guid3DAlgorithm

DirectSound3D 의 하드웨어 에뮬레이션이 사용하는 2 스피커 가상화 알고리즘의 일의인 식별자

Page 8: DirectSound  프로그래밍

버퍼의 설정

버퍼 설정 및 생성 예제 코드

LPDIRECTSOUNDBUFFER pDSBPrimary = NULL;DSBUFFERDESC dsbd;

ZeroMemory(&dsbd, sizeof(DSBUFFERDESC));

// 구조체 멤버 설정dsbd.dwSize = sizeof(DSBUFFERDESC);dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;dsbd.dwBufferBytes = 0;dsbd.lpwfxFormat = NULL;

HRESULT hr = m_pDS->CreateSoundBuffer(&dsbd, &pDSBPrimary, NULL );

Page 9: DirectSound  프로그래밍

버퍼의 설정 웨이브 폼 오디오 데이터의 포맷을 정의하는 코드 .

WAVEFORMATEX wfx; ZeroMemory(&wfx, sizeof(WAVEFORMATEX)); wfx.wFormatTag = (WORD)WAVE_FORMAT_PCM; wfx.nChannels = (WORD)2; wfx.nSamplesPerSec = (DWORD)22050; wfx.wBitsPerSample = (WORD)16; wfx.nBlockAlign = (WORD)(wfx.wBitsPerSample / 8 * wfx.nChannels); wfx.nAvgBytesPerSec = (DWORD)(wfx.nSamplesPerSec * wfx.nBlockAlign);HRESULT hr = pDSBPrimary->SetFormat(&wfx)

Page 10: DirectSound  프로그래밍

DirectSound 의 예제 DirectSound 샘플의 중심적인 기능을 하는 Dsutil.h 에

선언되고 Dsutil.cpp 에서 구현된 클래스들을 가지고 간단한 예제를 구현한다 .

DirectSound 샘플에서 사용되는 클래스는 다음과 같다 . Csound 클래스 : 스태틱 버퍼 를 나타낸다 . CSoundManager 클래스 : DirectSound 의 생성과 초기화 ,

1 차 버퍼에의 액세스 , 2 차 버퍼의 생성을 위한 기능을 포함한다 .

CStreamingSound 클래스 : 스트리밍 버퍼 내의 사운드를 나타낸다 .

CWaveFile 클래스 : WAV 파일의 read 와 쓰기 , 메모리에 저장 되고 있는 WAV 리소스 또는 웨이브 폼으로부터의 read에 사용된다 .

Page 11: DirectSound  프로그래밍

DirectSound 의 예제 CSoundManager 클래스를 이용한 초기화 , 협조레벨

설정CSoundManager m_pCSM;m_pCSM.Initialize(hWnd, (DWORD)DSSCL_PRIORITY);hWnd 는 윈도우 핸들이며 우선협조레벨로 설정하고 있다 .

1 차 버퍼의 포맷 형태를 설정m_pCSM.SetPrimaryBufferFormat((DWORD)2,(DWORD)22050, (DWORD)16);위의 코드에서 1 차 버퍼를 2 채널 ( 스테레오 ), 22050kHz 의 샘플링 , 한 샘플을 16bit 으로 표현하는 형태로 정의하고있다

Page 12: DirectSound  프로그래밍

DirectSound 의 예제 CSoundManager 클래스를 이용한 생성

CSound *m_pCSBGSound; m_pCSM.Create(&m_pCSBGSound,

strWaveFileName, 0, GUID_NULL, 5);

CSoundManager::Create() 함수를 호출하여 생성을 한다 .

인자로는 Csound 의 객체포인터가 필요하며 , WAVE 화일명 , 그리고 0 과 GUID_NULL 은 DSBUFFERDESC 의 구조체를 채우는데 사용되며 , 마지막 인자인 5 는 만들어지는 버퍼 배열의 갯수이다 .

Page 13: DirectSound  프로그래밍

DirectSound 의 예제 CSound::Play() 를 이용하여 재생을 한다 .

CSound::Play() 함수의 인자는 다음과 같다CSound::Play(DWORD dwPriority, DWORD dwFlags, LONG lVolume, LONG lFrequency, LONG lPan)

첫번째는 사운드의 우선도를 나타내고 , 두번째 플래그에서는 사운드를 반복 할 수 있는 DSBPLAY_LOOPING 플래그를 사용 할 수 있다 . 나머지 3개의 플래그는 볼륨 설정 , 샘플링 오디오의 재생 주파수 설정 , 좌우축의 음원 위치를 설정할 수 있는 플래그이다 .

Page 14: DirectSound  프로그래밍

DirectSound 의 예제 CSound::Stop() 를 이용한 재생 중지

m_pCSBGSound->Stop();

재생을 할 때 DSBPLAY_LOOPING 플래그를 설정하고 재생하면 멈추지 않고 계속 재생을 하게 된다 .

이 때 CSound::Stop() 함수를 호출 하면 재생을 중지 시킬수 있다 .

Page 15: DirectSound  프로그래밍

DirectSound 의 예제 예제에서는 사용을 편리 하게 하기 위해 MyDirectSound 라는

클래스를 만들었다 .

#ifndef MYDIRECTSOUND_H

#define MYDIRECTSOUND_H

#define LOOP (DWORD)DSBPLAY_LOOPING // 반복 재생을 위한 정의

typedef struct { // 재생 정보를 구조체로 정의

DWORD dwPriority;

DWORD dwFlags;

LONG lVolume;

LONG lFrequency;

LONG lPan;

}PLAYINFO;

Page 16: DirectSound  프로그래밍

DirectSound 의 예제class MyDirectSound{private:

CSoundManager m_pCSM;CSound *m_pCSBGSound;CSound *m_pCSFGSound;HRESULT hr;PLAYINFO pi;

public:

MyDirectSound();

~MyDirectSound();

HRESULT Initialize(HWND hWnd);

HRESULT CreateBGSound(LPTSTR

strWaveFileName);

HRESULT CreateFGSound(LPTSTR

strWaveFileName);

HRESULT PlayBGSound();

HRESULT PlayFGSound(DWORD

dwFlag = 0);

HRESULT StopBGSound();

HRESULT StopFGSound();

};

Page 17: DirectSound  프로그래밍

DirectSound 의 예제 코딩순서 기존에 생성 되어 있는 프로젝트에

Source Files 에 DSUtil.cpp 와 MyDirectSound.cpp 를 Header Files에 DSUtil.h 와 MyDirectSound.h 파일을 추가한다 .

WinMain 함수가 있는 cpp 파일에서 DSUtil.h 와 MyDirectSound.h 파일을 인클루드 시킨다 .

Page 18: DirectSound  프로그래밍

DirectSound 의 예제 코딩순서 인클루드 시킨다음 전역변수로 MyDirectSound 객체를

선언하고 ex) MyDirectSound mydsapp; 메시지프로시저함수 안에

case WM_CREATE: mydsapp.Initialize(hWnd); mydsapp.CreateBGSound("11.wav");mydsapp.CreateFGSound("bounce.wav");mydsapp.PlayBGSound();return(0);

와 같이 코딩을 하면 실행시에 11.wav 를 배경음악으로 bounce.wav 를 효과음악으로 로드하며 프로그램실행과 동시에 배경음악을 플레이 하도록 되어있다 .

Page 19: DirectSound  프로그래밍

DirectSound 의 예제 코딩순서 위의 코드에서

mydsapp.CreateBGSound("11.wav");mydsapp.CreateFGSound("bounce.wav");따옴표안의 화일명을 고치면 다른 파일로 변경할 수 있다 .배경음악과 효과음악을 구분해놓은 이유는 배경음악은 LOOP 옵션을 기본적으로 주었고 효과음악은 재생시에 PlayFGSound(); 를 호출하면 한번 재생 , PlayFGSound(LOOP); 로 호출하면 반복재생할 수 있다 .

Page 20: DirectSound  프로그래밍

DirectSound 의 예제 코딩순서 키보드의 입력을 받을 때마다 효과음악을

재생하고자 하면 WndProc(메시지프로시저함수 ) 에서 switch 문안에 case WM_KEYDOWN:

mydsapp.PlayFGSound();return(0);

와같이 코딩하여 호출하면 키보드 입력이 있을 때마다 효과음악을 재생하게 된다 .

Page 21: DirectSound  프로그래밍

DirectSound 의 예제 MyDirectSound::Initialize(HWND hWnd)

DirectSound 를 초기화하는 동시에 협조레벨을 우선 협조레벨로 설정하고있다 .

1 차버퍼의 포맷을 2 채널 22050 샘플링 비율 16 비트로 정의한다 . MyDirectSound ::CreateBGSound(LPTSTR

strWaveFileName) 인자로 되어있는 화일이름을 배경음악으로 읽어들인다 .

MyDirectSound ::CreateFGSound(LPTSTR strWaveFileName)

인자로 되어있는 화일이름을 효과음으로 읽어들인다 . MyDirectSound ::PlayBGSound()

배경음악을 재생하는 함수이다 . 기본적으로 반복재생을 한다 . MyDirectSound ::PlayBGSound()

재생을 할 수 있는 함수 두번째 플래그에 (DWORD)DSBPLAY_LOOPING 인자값을 넣으면 반복 재생을 할 수 있다 .

Page 22: DirectSound  프로그래밍

DirectSound 의 예제 MyDirectSound ::StopBGSound()

배경음악 재생을 멈추는 함수 생성된 Csound 객체멤버함수인 Reset() 를 호출하면

처음부터 재생을 한다 . MyDirectSound ::StopFGSound()

효과음 재생을 멈추는 함수 생성된 Csound 객체멤버함수인 Reset() 를 호출하면

처음부터 재생을 한다 .