pszSound : 연주할 사운드 파일의 이름. 파일의 경로를 넣을 더 수도 있다.
hmod : 리소스에 있는 Wave파일을 연주할 경우 리소스를 가진 실행파일의 핸들인데, 그 외의 경우는 NULL로 준다.
fdwSound : 사운드의 연주방식과 연주할 사운드의 종류를 정의하는 플래그이다. 이것에 따라 첫 번째, 두 번째 인수의 해석 방식이 달라진다. 여러 플래그 중 몇 가지만 알아보자.
- SND_FILENAME : 첫 번째 인수인 pszSound는 사운드 파일의 이름이다.
- SND_ASYNC : 비동기화된 연수를 한다. 연주시작 후 바로 리턴하므로 다른 작업을 바로 시작할 수 있다.
- SND_LOOP : 지정한 사운드를 반복적으로 계속 연주한다. 이 플래그는 반드시 SND_ASYNC와 함께 사용되어야 한다.
- SND_SYNC : 동기화된 연주를 한다. 사운드 파일의 연주가 완전히 끝나기 전에는 리턴하지 않는다.
예제)
AppWizard를 사용하여 Sound라는 이름으로 SDI 프로젝트를 만든다.
뷰에 WM_LBUTTONDOWN메시지의 핸들러를 만들고
OnLButtonDown 핸들러에 다음과 같이 코드를 작성한다.
~cpp
#include "mmsystem.h"
void CSoundView::.....
{
PlaySound("Battle.wav", NULL, SND_SYNC);
CView:....
}
PlaySound 함수를 사용하려면 mmsystem.h 파일을 먼저 include 해주어야 하고,
Project/ Settings/Link 탭에서 winmm.lib를 링크해 주어야 한다.
그 후 컴파일하고 실행한 후 작업영역을 왼쪽 마우스 버튼으로 누르면 소리가 날 것이다. 시스템에 사운드카드가 장착되어 있어야 하며 같은 디렉토리에 Battle.wav라는 파일이 있어야 할 것이다.
1-2) 비동기 연주
앞서 만든 예제를 보면
PlaySound 함수는 사운드 파일 연주가 완전히 종료되기 전에는 리턴하지 않으므로 연주중인 동안은 어떤 일도 할 수 없다. 이런 방법을 동기화 방식이라고 한다.
반대로
PlaySound함수가 연주를 시작해 놓고 곧바로 리턴하는 비동기 연주 방식이 있다.
이번에는 SND_LOOP 플래그를 사용하여 작성해 보고, WM_RBUTTONDOWN 메시지의 핸들러도 같이 만들어보자.
~cpp
void CSoundView::OnLB.........
{
PlaySound("Battle.wav", NULL, SND_ASYNC | SND_LOOP);
CView:....
}
void CSoundView::OnRB......
{
PlaySound(NULL, NULL, 0);
CView:....
}
SND_LOOP 플래그를 지정하면 반복적인 효과음이나 배경음악을 연주하는 등의 설정을 할 수 있을 것이다. 연주를 중지시키려면
PlaySound 함수의 첫 번째 인수를 NULL로 하여 다시 호출해 주면 된다. 따라서, 오른쪽 마우스 버튼을 누르면 연주가 중지될 것이다. 주의할 것은 SND_LOOP 플래그는 반드시 SND_ASYNC와 함께 사용해야 한다. 만약 동기화 연주방식으로 반복연주를 하면 무한 루프로 빠져버릴 위험이 있다.
1-3) 리소스의 Wave 연주
사운드 파일을 연주하는 것은 사용하기는 간단하지만 연주할 때마다 디스크에서 사운드 파일을 읽어와야 하므로 반응 속도가 느리다. 따라서 이 경우에는 사운드 파일을 리소스에 포함시켜 놓고 리소스에서 읽어서 연주하는 방법으로 하는 것이 좋을 것이다.
앞에서 만든 예제를 수정해서 Battle.wav 파일을 실행파일에 합쳐보자.
리소스 뷰의 팝업메뉴에서 Import 메뉴항목을 선택하고 리소스에 포함시키고자 하는 Wave 파일을 선택한다. 그러면 IDR_
WAVE1이라는 ID로 리소스에 삽입될 것이다.
리소스에 포함된 사운드를 연주하려면
PlaySound의 세 번째 인수에 SND_RESOURCE 플래그를 주고 첫 번째 인수에 리소스의 ID를 준다. 두 번째 인수에는 리소스를 가진 실행파일의 인스턴스 핸들을 주어야 하는데 MFC에서는
AfxGetInstanceHandle() 전역함수로 인스턴스 핸들을 구할 수 있다. 다음과 같이 코드를 작성해 보자.
~cpp
void CSoundView::OnLButtonDown(UINT nFlags, CPoint point)
{
PlaySound(MAKEINTRESOURCE(IDR_WAVE1), AfxGetInstanceHandle(), SND_RESOURCE | SND_ASYNC);
CView:OnLButtonDown(nFlags, point);
}
이렇게 하면 실행파일 속에 wav파일이 포함되어 Battle.wav파일이 없어도 연주할수 있게 된다.
1-4) MCI (Media Control Interface)
PlaySound함수는 메모리 크기의 제한을 받아서 1-2분 정도의 사운드 밖에 낼 수 없다는 점, Wave형태만 지원한다는 점, 연주과정에 사용자가 개입할 수 없다는 단점이 있다.
MCI는 멀티미디어 요소에 대한 지원을 장치독립적으로 제공하는 일종의 라이브러리이다. 이것은
PlaySound 함수가 하지 못하는 여러 가지 일을 할 수 있지만, 사용 방법은 훨씬 더 복잡하다.