C++ 사운드 재생하기 - FMod Library (with Visual Studio)

FMod Library using Visual Studio, C++

C 계열 윈도우 어플리케이션에서 사운드를 출력할 때 사용하는 라이브러리이다.

WIN API에서 어느정도 사운드 관련 API를 제공하긴 하지만, 사용에 있어 굉장히 불편하다. (mp3가 지원이 안된다던가, 두 개의 사운드 동시 출력이 안된다던가)


* (의도한) 포스팅 난이도 : C++ 입문자 이상, Visual Studio 사용 경험 1일 이상


1. 세팅

(Visual Studio 프로젝트는 이미 생성했다고 가정)

1. Visual Studio 프로젝트에 소스파일, 리소스 파일 추가

> 프로젝트에 CSound.h, CSound.c, 사운드 파일을 추가
* 소스코드는 포스팅 하단에 있음





> 솔루션 탐색기에서 해당 파일들 추가 (추가 > 기존항목)


* 파일명, 위치 등은 개인에 입맛에 맞게 변경하면 됨.


2. FMod Library 설치

> https://www.fmod.com/ 회원가입 후 Windows용 FMod Studio 다운로드 후 설치(무료버전, 32bit)
> C:\Program Files (x86) 에 FMOD 관련 폴더가 있으면 정상

(appwiz.cpl에서, 정상적으로 설치한 경우)

(윈도우 파일 탐색기에서, 정상적으로 설치한 경우)

* 2019.10 기준. 폴더 이름 등은 살짝 달라질 수 있음.


3. 환경설정

> [프로젝트 - 속성 - VC++ 디렉터리] 에 옵션 추가
포함 디렉토리 
1
C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\inc
cs

라이브러리 디렉토리 
1
C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86
cs

* 단, 파일 경로는 PC마다 다름. 파일 탐색기로 맞는 경로인지 확인 후 추가



> [프로젝트 - 속성 - 링커 - 입력] 에 옵션 추가
추가 종속성
1
fmod_vc.lib
cs

* 단 파일명은 PC마다 다를 수 있음. 파일 탐색기로 확인할 것. (위치 : 라이브러리 디렉토리)

필자의 경우 C:\Program Files (x86)\FMOD SoundSystem\FMOD Studio API Windows\api\core\lib\x86 에 fmod_vc.lib이 있었음



4. 프로젝트에 .dll 파일 추가

> 라이브러리 디렉토리에 있는 fmod.dll을 복사, 프로젝트 폴더에다가 붙여넣는다.
> 위처럼 프로젝트 파일(.sln)와 동일 경로에 .dll을 두면 됨

중요한 점은, .exe가 실행될 때 fmod.dll이 있어야 한다는 점이다.
(잘 안된다면 fmod.dll 파일을 Debug, Release 폴더 등에 마구 복붙해보자)



5. 컴파일 잘 되는지 확인하기

Ctrl + F5!


여기까지 문제가 없다면, 세팅은 잘 된것이다.


2. 사용법

소스 코드

CSound.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#pragma once
#ifndef _CSOUND_H_
#define _CSOUND_H_
 
#include <fmod.h>
 
#define SOUND_MAX 1.0f
#define SOUND_MIN 0.0f
#define SOUND_DEFAULT 0.5f
#define SOUND_WEIGHT 0.1f
 
class CSound {
private:
    static FMOD_SYSTEM *g_sound_system;
 
    FMOD_SOUND *m_sound;
    FMOD_CHANNEL *m_channel;
 
    float m_volume;
    FMOD_BOOL m_bool;
public:
    CSound(const char* path, bool loop);
    ~CSound();
 
    static int Init();
    static int Release();
 
    int play();
    int pause();
    int resume();
    int stop();
    int volumeUp();
    int volumeDown();
 
    int Update();
};
 
#endif
cs

CSound.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "CSound.h"
 
FMOD_SYSTEM* CSound::g_sound_system;
 
CSound::CSound(const char* path, bool loop) {
    if (loop) {
        FMOD_System_CreateSound(g_sound_system, path, FMOD_LOOP_NORMAL, 0&m_sound);
    }
    else {
        FMOD_System_CreateSound(g_sound_system, path, FMOD_DEFAULT, 0&m_sound);
    }
 
    m_channel = nullptr;
    m_volume = SOUND_DEFAULT;
}
 
CSound::~CSound() {
    FMOD_Sound_Release(m_sound);
}
 
 
int CSound::Init() {
    FMOD_System_Create(&g_sound_system);
    FMOD_System_Init(g_sound_system, 32, FMOD_INIT_NORMAL, NULL);
 
    return 0;
}
 
int CSound::Release() {
    FMOD_System_Close(g_sound_system);
    FMOD_System_Release(g_sound_system);
 
    return 0;
}
 
 
int CSound::play() {
    FMOD_System_PlaySound(g_sound_system, m_sound, NULLfalse&m_channel);
 
    return 0;
}
 
int CSound::pause() {
    FMOD_Channel_SetPaused(m_channel, true);
 
    return 0;
}
 
int CSound::resume() {
    FMOD_Channel_SetPaused(m_channel, false);
 
    return 0;
}
 
int CSound::stop() {
    FMOD_Channel_Stop(m_channel);
 
    return 0;
}
 
int CSound::volumeUp() {
    if (m_volume < SOUND_MAX) {
        m_volume += SOUND_WEIGHT;
    }
 
    FMOD_Channel_SetVolume(m_channel, m_volume);
 
    return 0;
}
 
int CSound::volumeDown() {
    if (m_volume > SOUND_MIN) {
        m_volume -= SOUND_WEIGHT;
    }
 
    FMOD_Channel_SetVolume(m_channel, m_volume);
 
    return 0;
}
 
 
int CSound::Update() {
    FMOD_Channel_IsPlaying(m_channel, &m_bool);
 
    if (m_bool) {
        FMOD_System_Update(g_sound_system);
    }
 
    return 0;
}
cs


사용법(필독)

* 여기 기재된 내용을 한 개 이상 어길 경우, 아마 실패할 것이다.
(소리가 안나올 것이다)

프로그램 최초 실행시, 딱 한번
1
CSound::Init();
cs
코드가 실행되어야 한다.

프로그램 종료 직전,
1
CSound::Release();
cs
코드가 실행되어야 한다.


객체 생성은
1
CSound *m_bgm = new CSound("assets/MainBGM.mp3"false);
cs
와 같이 한다.

첫 인자는 exe기준 소리 파일 경로,
두번째 인자는 소리를 무한 반복 재생할지 여부이다.
(true : 무한 반복 재생, false : 한 번만 재생)


객체 소멸은
1
delete m_bgm;
cs
와 같이 한다.


프로그램 루틴 내에
1
m_bgm->Update();
cs
코드가 있어야 한다.
(꾸준히 Update 함수를 호출해야 한다)


소리 재생 패턴은 다음과 같다.
1. 소리 재생(Play)
2. 소리 일시 정지(Pause) -> 소리 다시 재생(Resume)
3. 소리 재생 종료(Stop)

stop() 후에는 다시 play() 해야만 소리가 나온다.
일시 정지 후 다시 재생은 pause() -> resume() 순으로 실행해야 하고, 무한번 실행할 수 있다.


소리 크기 조절은 volumeUp(), volumeDown()을 호출하여 사용할 수 있다.


(전체 예시 코드)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include "CSound.h"
 
int main(){
    // Init Fmod Library
    CSound::Init();
    
    // Allocate Object
    CSound* sound = new CSound("sound.mp3"false);
 
    while(true){
        // Play Sound | 사운드 재생 시작
        if( ){
            sound->play();
        }
        
        // Pause Sound | 사운드 재생 일시중지
        if( ){
            sound->pause();
        }
 
        // Resume Sound | 사운드 다시재생
        if( ){
            sound->resume();
        }
        
        // Stop Sound | 사운드 재생 종료
        if( ){
            sound->stop();
        }
 
 
        // Volume Up
        if( ){
            sound->volumeUp();
        }
 
        // Volume Down
        if( ){
            sound->volumeDown();
        }
        
 
        // Require Update
        sound->update();
    }
 
    // Free Object
    delete sound;
 
    // Release Fmod Llibrary
    CSound::Release();
}
cs


3. 테스트

소리가 잘 나오면 성공.

2개 이상의 파일을 동시에 Play할 경우 모두 들릴 것이다.
(예 : BGM 음악은 계속 나오고, 버튼을 클릭하면 클릭음이 짧게 들리는 경우)

댓글

댓글 쓰기