-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaudio.cpp
More file actions
148 lines (124 loc) · 3.68 KB
/
audio.cpp
File metadata and controls
148 lines (124 loc) · 3.68 KB
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include "audio.hpp"
//namespace TerraNova::Audio { ////// this is the C++17 version
namespace TerraNova {
namespace Audio {
namespace {
Mix_Music* activeMusic;
Mix_Music* enqueuedMusic = nullptr;
Mix_Chunk* soundChunk;
} // anonymous namespace
bool Initialize() {
int flags = MIX_INIT_OGG;
if ((Mix_Init(flags) & flags) != flags) {
std::cerr << "Error: failed to initialize SDL_mixer." << std::endl;
return false;
}
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) == -1) {
std::cerr << "Error: Mix_OpenAudio failed with this error: "
<< Mix_GetError() << std::endl;
Mix_Quit();
return false;
}
return true;
}
void Deactivate() {
Mix_CloseAudio();
if (activeMusic) {
FreeMusic();
}
if (soundChunk) {
Mix_FreeChunk(soundChunk);
soundChunk = nullptr;
}
Mix_Quit();
}
void PlayMusic(const std::string& filename) {
Mix_Music* loadedMusic = LoadMusic(filename);
if (loadedMusic == nullptr) return;
if (activeMusic) {
ReplaceMusic(loadedMusic);
//Mix_FreeMusic(musicChunk);
} else {
activeMusic = loadedMusic;
if (Mix_FadeInMusic(activeMusic, -1, 2000) == -1) {
std::cerr << "Error: could not play music from " << filename << ", "
<< "getting error " << Mix_GetError() << std::endl;
return;
}
}
}
// load and return a pointer to music, *not* other sounds!
Mix_Music* LoadMusic(const std::string& filename) {
Mix_Music* loadedMusic = Mix_LoadMUS(File::AbsolutePath(
"music/" + filename + ".ogg").c_str());
if (loadedMusic == nullptr) {
std::cerr << "Error: failed to load music file at " << filename
<< ", getting error " << Mix_GetError() << std::endl;
return nullptr;
}
return loadedMusic;
}
// fade out new music, then free it once it's done
void TurnOffMusic() {
Mix_FadeOutMusic(2000);
Mix_HookMusicFinished(FreeMusic);
}
// free music which is already off
void FreeMusic() {
Mix_FreeMusic(activeMusic);
activeMusic = nullptr;
}
// fade out current music, fade in new music
void ReplaceMusic(Mix_Music* newMusic) {
Mix_FadeOutMusic(2000);
enqueuedMusic = newMusic;
Mix_HookMusicFinished(ReplaceMusicCallback);
}
// this exists to be handed to Mix; don't call it
void ReplaceMusicCallback() {
Mix_FreeMusic(activeMusic);
activeMusic = enqueuedMusic;
enqueuedMusic = nullptr;
if (Mix_FadeInMusic(activeMusic, -1, 2000) == -1) {
std::cerr << "Error: could not fade in new music, getting error "
<< Mix_GetError() << std::endl;
return;
}
}
// this function should only be used to play miscellaneous sounds; for music,
// use PlayMusic
void PlaySound(const std::string& filename, const int loops) {
Mix_Chunk* loadedChunk = LoadSound(filename);
if (loadedChunk == nullptr) return;
if (soundChunk) Mix_FreeChunk(soundChunk);
soundChunk = loadedChunk;
if (Mix_PlayChannel(-1, soundChunk, loops) == -1) {
std::cerr << "Error: could not play audio from " << filename << ", "
<< "getting error " << Mix_GetError() << std::endl;
return;
}
//std::cout << "Playing " << filename << " " << loops << " time(s)."
//<< std::endl;
//Resume();
}
// load and return a pointer to a sound file, *not* music!
//
// despite its name, Mix_LoadWAV can load WAV, AIFF, RIFF, OGG, and VOC
Mix_Chunk* LoadSound(const std::string& filename) {
Mix_Chunk* loadedSound = Mix_LoadWAV(File::AbsolutePath(filename).c_str());
if (loadedSound == nullptr) {
std::cerr << "Error: failed to load audio file at " << filename
<< ", getting error " << Mix_GetError() << std::endl;
return nullptr;
}
return loadedSound;
}
void Pause() {
//if(device != 0) SDL_PauseAudioDevice(device, 1);
}
void Resume(const int) {
//if(device != 0) SDL_PauseAudioDevice(device, 0);
//Mix_PlayChannel(0, soundChunk, loops);
}
} // namespace Audio
} // namespace TerraNova