[C++] 1.5 FMOD를 이용한 소리 재생
카테고리: C++ games
태그: Cpp Graphics OpenGL Programming
인프런에 있는 홍정모 교수님의 홍정모의 게임 만들기 연습 문제 패키지 강의를 듣고 정리한 필기입니다.😀
🌜 공부에 사용된 홍정모 교수님의 코드들 보러가기
🌜 [홍정모의 게임 만들기 연습 문제 패키지] 강의 들으러 가기!
Chapter 1. 기본 기능 구현
1.5 FMOD를 이용한 소리 재생
FMOD 설치 및 위치와 설정
설치는 FMOP 공식 사이트에서! https://www.fmod.com
FMOD API 문서 https://www.fmod.com/resources/documentation-api
로컬 위치
- 설치 경로로 찾아가자.
/📁FMOD Studio API Windows
- 아래와 같은 파일 & 폴더들을 내 C++ 프로젝트 폴더에 복사해주자.
- 📁core 혹은 📁fmod_lowlevel
- 이 폴더안에는 📁inc 폴더와 📁lib이 들어 있는데 📁inc 폴더는 include해야 하는 헤더 파일들이 들어있고 📁lib 폴더엔 dll 파일들이 들어있다.
- 사용할 🎵wav 파일 혹은 🎵mp3 파일
- dll 파일들
- 📃fmod.dll
- 📃fmod64.dll
- 📁core 혹은 📁fmod_lowlevel
비주얼 스튜디오에서의 라이브러리 설정
프로젝트 속성이 x64
로 맞춰있어야 한다.
- 프로젝트 속성 - V/C++디렉터리 - 라이브러리 디렉터리 - 편집
- 하얀창에다가 같은 프로젝트 폴더로 복사해서 옮겨온 fmod의 (fmod_lowlevel) 📁lib파일의 경로를 복사하여 쓰고 확인.
- 프로젝트 속성 - V/C++디렉터리 - 포함 디렉터리 - 편집
- 하얀창에다가 같은 프로젝트 폴더로 복사해서 옮겨온 fmod의 (fmod_lowlevel) 📁inc파일의 경로를 복사하여 쓰고 확인.
- 프로젝트 속성 - 링커 - 입력 - 추가 종속성 - 편집
- 하얀창에다가 “fmod64_vc.lib” 입력 후 확인
FMOD 를 사용한 코드 설명
//#include "fmod.h" // c-context
#include "fmod.hpp"
#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
cout << "FMOD cpp conext example" << endl;
FMOD::System *system(nullptr);
FMOD::Sound *sound(nullptr);
FMOD::Channel *channel(nullptr);
FMOD_RESULT result;
unsigned int version;
void *extradriverdata(nullptr); // 본 예제에서는 사용 x
/* ==============================================================================
각 함수마다 함수가 잘 실행됐는지 체크하는 파트 !
문제가 있다면 return -1 하고 종료
각 함수가 정상적으로 실행 됐다면 FMOD_OK가 true일 것
*/
result = FMOD::System_Create(&system);
if (result != FMOD_OK) return -1; // 첫번째로 꼭 꼭 !! 시스템 객체를 먼저 생성시켜야 한다.
result = system->getVersion(&version);
if (result != FMOD_OK) return -1;
else printf("FMOD version %08x\n", version);
result = system->init(32, FMOD_INIT_NORMAL, extradriverdata); // 시스템 초기화 : chaneel 32개까지 사용하겠다.
if (result != FMOD_OK) return -1;
//result = system->createSound("singing.wav", FMOD_LOOP_NORMAL, 0, &sound);
result = system->createSound("singing.wav", FMOD_LOOP_OFF, 0, &sound); // wav 파일로부터 sound 생성
if (result != FMOD_OK) return -1;
result = system->playSound(sound, 0, false, &channel); // 재생. 단 이때 딱 한번만 실행되므로 제대로 사운드가 끝까지 재생되지 않는다. 무한루프 안에서 시스템 객체를 계~~속 업데이트 시켜줘야 함.
if (result != FMOD_OK) return -1;
/* ===============================================================================*/
while (true)
{
//시스템을 계속해서 업데이트 해주고 문제가 있나 체크 (사실 이 부분이 없어도 잘 돌아간다. 그치만 해주자)
result = system->update();
if (result != FMOD_OK) return -1;
// 1. 이부분 실행해보거나
if (channel)
{
bool playing = false;
result = channel->isPlaying(&playing); // 곡이 재생 중이라면 playing이 true가 되고 재생이 끝났다면 false가 되어 무한 루프 빠져나오고 프로그램 종료
if (!playing) break;
}
// 2. 이 부분 실행해보기 ( 1, 2 중 하나만. 하나는 주석 처리하고 실행시켜 보기. 2에서 퍼즈할거니까 1 주석처리 )
cout << "Press 0 to pause, 1 to resume, and x to exit" << endl;
int i = getch(); // 키보드 입력 받아들이기. 이때 i는 아스키 코드로 정수.
if (i == '0') // 0 키를 눌렀다면 채널을 잠깐 멈추기 퍼즈
channel->setPaused(true); // 단 channel->setPaused 는 FMOD_LOOP_NORMAL 일때만 사용 가능하다. FMOD_LOOP_NORMAL 로 바꿔주기
else if (i == '1') // 0 키를 눌렀다면 음악을 다시 재생
channel->setPaused(false);
else if (i == 'x') // x 키를 눌렀다면 프로그램 종료 (그냥 무한루프 나가면 됨)
break;
}
system->release(); // 프로그램이 끝난 후에는 리소스 릴리즈. 시스템 객체 해제.
}
C
를 사용할거면 #include “fmod.h”C++
을 사용할거면 #include “fmod.hpp”- hpp는 C++ 전용 헤더파일이다.
- FMOD 네임스페이스에
System
,Sound
,Channel
이 정의 되어 있다.- FMOD::System * system
- 보통 1개를 설정
- FMOD::Sound * sound
- 게임 내에서 사운드는 여러개가 쓰이기 때문에 보통 여러개 설정 (배열로 정리)
- FMOD::Channel * channel
- 얘도 보통 여러개 둠. 채널을 컨트롤하여 사운드를 볼륨 설정하거나 퍼즈함
채널
은 그 해당 채널에 담긴 사운드를 통째로 컨트롤 하는 용도. 볼륨 설정하거나 끄거나 퍼즈하거나.
- FMOD::System * system
FMOD_RESULT result
- 작업 결과가 잘 나왔나 확인하는 flag
unsigned int version
- FMOD 버전 확인
CreateSound
system->createSound("singing.wav", FMOD_LOOP_OFF, 0, &sound);
- 사운드 객체를 만드는건 System이다.
- wav, mp3 파일로부터 sound 생성한다.
FMOD_LOOP_OFF
: 무한재생 끔FMOD_LOOP_NORMAL
: 무한재생 켬
PlaySound
system->playSound(sound, 0, false, &channel); // 재생
&channel
: 어떤 채널을 통해서 재생 되는지 마지막 파라미터로 해당 채널의 포인터 넘기기- 사운드 객체를 재생시키는건 시스템이다.
- 한 채널에서 여러개의 사운드를 재생할 수 있다.
- ⭐ 단 이 함수는 딱 한번만 실행 되기 때문에 이 함수가 한 파일을 끝까지 재생시키려면
무한 루프를 넣어서 시스템을 계속해서 업데이트 시켜야함
- 그래서
while(true)
문 안에서result = system->update();
를 해주어 프로그램을 계속 실행 상태로 유지하는 것. - 무한루프 없다면 바로 playSound 한번 실행하고 음악 1초도 재생 안되서 프로그램 자체가 종료 될테니까!
- 그래서
while(true) 무한 루프
- 무한 루프문을 돌리는 이유
- 사운드 재생시키는 함수를 실행하고 프로그램이 바로 끝나버리지 않기 위하여.
- 즉 사운드 끝까지 재생이 다 끝날 때까지 프로그램이 종료되지 않게 함.
result = system->update();
PlaySound
함수가 한 파일을 끝까지 재생시키게 하기 위해 무한 루프 안에서 계속 system을 업데이트
channel->isPlaying(&playing)
- 채널의
isPlaying
함수- 현재 재생 중이면 playing이 true가됨.
- 재생 중이 아니라서 false면 while문 break
- 채널의
channel->setPaused(true)
- true면 퍼즈 false면 퍼즈를 푼다.
- 단 이 함수를 실행하려면 system->createSound(“singing.wav”, FMOD_LOOP_NORMAL, 0, &sound) Normal 상태여야 한다.
FMOD_LOOP_NORMAL
상태 일때만 사용 가능
기타
- 프로그램이 끝난 후에는
system->release();
해주어 리소스를 릴리즈 시킨다. - 🎵파일 이름 꼭 검토하기!
.mp3
파일인데.wmv
라고 쓰면 실행되지 않는다. 파일 이름 쓸 때 확장자까지 명확히 써주어야 함.
사운드 구하기
저작권 없는 무료 효과음들을 이 사이트에서 구하자. https://freesound.org
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글남기기