1.PlaySound() |
#include <windows.h>
#pragma comment (lib, "winmm.lib")
#include <mmsystem.h>;
PlaySound(TEXT(wav파일의 위치), NULL, 옵션1 | 옵션2)
가장 간단한 방법은 PlaySound 함수를 이용하는 것이다.
이 함수를 이용하기 위해선 mmsystem.h
가 필요하다.
그리고 별도의 라이브러리로 winmm.lib
가 필요하다. #pragma
로 추가해주면 된다.
PlaySound(TEXT("bgm.wav"), NULL, SND_ASYNC) // 일반 재생
PlaySound(TEXT("bgm.wav"), NULL, SND_ASYNC | SND_LOOP) // 반복 재생
docs.microsoft.com/en-us/previous-versions/dd743680(v=vs.85)
함수에 주어지는 인자를 자세히 알고 싶다면 microsoft에서 제공하는 정보를 참고하자.
하지만 이 함수는 내가 원하던 함수는 아니다.
우선 BGM을 깔아둔 채로 효과음을 재생할 수 없다.
또한 wav 파일을 사용하기 때문에 음악 파일의 용량이 크다.
단순히 BGM만 들리게 프로그램을 만든다면 간단하게 사용해볼 수 있겠지만, 부족한 점이 많다.
동시에 음악을 구현하려면 mciSendCommand 를 이용하면 된다.
2.MCI |
MCI는 Media Control Interface의 약자로, mp3 파일도 재생할 수 있어서 이용하기 편하다.
docs.microsoft.com/ko-kr/windows/win32/multimedia/mci
역시 마이크로소프트에서 문서를 제공하므로 자세한 정보를 알고 싶다면 접속해보시면 되겠다.
여기서는 '음악 동시 재생'을 위한 코드만 소개한다.
#include <windows.h> //키보드 입력
#pragma comment (lib, "winmm.lib") //음악
#include <mmsystem.h>; //음악
#include <Digitalv.h>; //음악
MCI_OPEN_PARMS openBgm;
MCI_PLAY_PARMS playBgm;
MCI_OPEN_PARMS openShuffleSound;
MCI_PLAY_PARMS playShuffleSound;
#define BGM "C:\\BGM.mp3" //BGM 경로 지정
#define SHUFFLE "C:\\shuffle.mp3" //효과음 경로 지정
int dwID;
void playingBgm(void) {
openBgm.lpstrElementName = BGM; //파일 오픈
openBgm.lpstrDeviceType = "mpegvideo"; //mp3 형식
mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT | MCI_OPEN_TYPE, (DWORD)(LPVOID)&openBgm);
dwID = openBgm.wDeviceID;
mciSendCommand(dwID, MCI_PLAY, MCI_DGV_PLAY_REPEAT, (DWORD)(LPVOID)&openBgm); //음악 반복 재생
}
void playingShuffleSound(void) {
openShuffleSound.lpstrElementName = SHUFFLE; //파일 오픈
openShuffleSound.lpstrDeviceType = "mpegvideo"; //mp3 형식
mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT | MCI_OPEN_TYPE, (DWORD)(LPVOID)&openShuffleSound);
dwID = openShuffleSound.wDeviceID;
mciSendCommand(dwID, MCI_PLAY, MCI_NOTIFY, (DWORD)(LPVOID)&openShuffleSound); //음악을 한 번 재생
Sleep(1800); //효과음이 재생될 때까지 정지했다가
mciSendCommand(dwID, MCI_SEEK, MCI_SEEK_TO_START, (DWORD)(LPVOID)NULL); //음원 재생 위치를 처음으로 초기화
}
원하는 동작은 BGM이 실행되는 도중 특정한 상황에서 효과음이 들리도록 하는 것이다.
그래서 음악 재생을 별도의 함수로 구현했다.
#include <windows.h> //키보드 입력
#pragma comment (lib, "winmm.lib") //음악
#include <mmsystem.h>; //음악
#include <Digitalv.h>; //음악
PlaySound와 마찬가지로 winmm.lib
를 추가하고, mmsystem.h
헤더 파일을 추가하면 된다. 추가적으로 Digitalv
헤더파일도 필요하다.
MCI_OPEN_PARMS openBgm;
MCI_PLAY_PARMS playBgm;
MCI_OPEN_PARMS openShuffleSound;
MCI_PLAY_PARMS playShuffleSound;
#define BGM "C:\\BGM.mp3" //BGM 경로 지정
#define SHUFFLE "C:\\shuffle.mp3" //효과음 경로 지정
int dwID;
MCI_OPEN_PARMS
는 MCI_OPEN
커맨드를 위한 정보가 담긴 구조체이다.
MCIERROR mciSendCommand(
MCIDEVICEID wDeviceID,
MCI_OPEN,
DWORD dwFlags,
(DWORD) (LPMCI_OPEN_PARMS) lpOpen
);
여기서 lpOpen
위치에 MCI_OPEN_PARMS
가 들어간다.
MIC_PLAY_PARMS
는 재생할 위치 정보를 담고 있는 구조체이다.
BGM
을 재생하기 위해 openBgm
과 playBgm
이라는 두 구조체를 선언했고,
효과음을 재생하기 위해 openShuffleSound
와 playShuffleSound
라는 두 구조체를 선언했다.
파일 이름은 경로를 포함해야 하므로 길어질 수 있어서 #define
으로 경로를 간단하게 표현했다.
dwID
는 MCI_OPEN_PARMS
이 담고 있는 wDeviceID
를 받기 위한 변수다.
이제 BGM을 재생하는 함수를 살펴보자.
void playingBgm(void) {
openBgm.lpstrElementName = BGM; //파일 오픈
openBgm.lpstrDeviceType = "mpegvideo"; //mp3 형식
mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT | MCI_OPEN_TYPE, (DWORD)(LPVOID)&openBgm);
dwID = openBgm.wDeviceID;
mciSendCommand(dwID, MCI_PLAY, MCI_DGV_PLAY_REPEAT, (DWORD)(LPVOID)&openBgm); //음악 반복 재생
}
MIC_OPEN_PARMS
구조체 내의 lpstrElementName
은 "Device element (often a path)"라고 설명되어 있다. 재생하고 싶은 파일의 경로를 지정하면 된다.
lpstrDeviceType
을 "mpegvideo"로 지정하면 mp3 파일을 이용할 수 있게 된다.
MCIERROR mciSendCommand(
MCIDEVICEID IDDevice,
UINT uMsg,
DWORD_PTR fdwCommand,
DWORD_PTR dwParam
);
mciSendCommand
함수는 네 가지 인수가 있다.
IDDevice
는 디바이스 식별자로 mci open 메시지인 경우 NULL
로 처리한다.
uMsg
에는 커맨드를 주고, fdwCommand
에 주는 인자에 대해서는
docs.microsoft.com/ko-kr/windows/win32/multimedia/mci-open
이 페이지를 참고하면 된다.
우리가 세팅한 것이 이름과 형식이기 때문에 MIC_OPEN_ELEMENT
와 MCI_OPEN_TYPE
을 주었다.
dwParam
은 정보를 담고 있는 구조체를 가리킨다.
재생 역시 mciSendCommand
를 이용한다.
이번엔 MCI_OPEN
대신 MCI_PLAY
를 사용한다.
PLAY에 대해선
docs.microsoft.com/ko-kr/windows/win32/multimedia/mci-play
이 페이지를 참고하면 되겠다.
효과음을 재생하는 함수 역시 마찬가지로 설정하면 된다. 조금 다른 점은 원하는 타이밍에 실행해야 한다는 것.
void playingShuffleSound(void) {
openShuffleSound.lpstrElementName = SHUFFLE; //파일 오픈
openShuffleSound.lpstrDeviceType = "mpegvideo"; //mp3 형식
mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT | MCI_OPEN_TYPE, (DWORD)(LPVOID)&openShuffleSound);
dwID = openShuffleSound.wDeviceID;
mciSendCommand(dwID, MCI_PLAY, MCI_NOTIFY, (DWORD)(LPVOID)&openShuffleSound); //음악을 한 번 재생
Sleep(1800); //효과음이 재생될 때까지 정지했다가
mciSendCommand(dwID, MCI_SEEK, MCI_SEEK_TO_START, (DWORD)(LPVOID)NULL); //음원 재생 위치를 처음으로 초기화
}
그런데 음악이 한 번 재생되면 재생위치를 기억하기 때문에, 다시 효과음을 사용하려면 재생 위치를 처음으로 바꾸어야 한다. 마지막 코드를 추가하면 된다.
또 하나 문제는 효과음을 재생하고 처음 위치로 되돌리는 커맨드가 이어서 실행되면 아무 소리도 들리지 않는다는 것이다. 내가 추측할 때는 재생되자마자 정지버튼을 누르는 상황인 것 같다. 그래서, 효과음 파일이 재생되는 동안(약 1.8초, 파일마다 다름) Sleep
을 통해 잠시 진행을 멈춘 후에 실행되도록 했다.
블랙잭 게임(조별과제였다.)에서 카드를 섞는 효과음을 주기 위해서 이름을 shuffle
로 지었다.
잘 실행된다.
'프로그래밍 > C, C++' 카테고리의 다른 글
<C프로그래밍-새내기를 위한 첫 C 언어 책>연습문제 chapter 11(1번~10번) (0) | 2020.11.26 |
---|---|
<C프로그래밍-새내기를 위한 첫 C 언어 책>연습문제 chapter 10(16번~21번) (0) | 2020.11.26 |
<C프로그래밍-새내기를 위한 첫 C 언어 책>연습문제 chapter 10(11, 12, 13, 14, 15) (0) | 2020.10.18 |
<C프로그래밍-새내기를 위한 첫 C 언어 책>연습문제 chapter 10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) (0) | 2020.10.17 |
<C프로그래밍-새내기를 위한 첫 C 언어 책>연습문제 chapter 9 (1, 2, 3, 4, 5) (0) | 2020.10.16 |