OpenRaider  0.1.4-dev
Open Source Tomb Raider Game Engine implementation
SoundAL.cpp
Go to the documentation of this file.
1 
9 #ifdef __APPLE__
10 #include <OpenAL/al.h>
11 #else
12 #include <AL/al.h>
13 #endif
14 
15 #include <AL/alut.h>
16 
17 #include "global.h"
18 #include "Log.h"
19 #include "system/SoundAL.h"
20 
21 const static float soundTravelSectors = 15.0f;
22 const static float referenceDistance = 1024.0f;
24 
25 bool SoundAL::init = false;
26 bool SoundAL::enabled = true;
27 float SoundAL::volume = 1.0f;
28 std::vector<unsigned int> SoundAL::buffers;
29 std::vector<unsigned int> SoundAL::sources;
30 std::vector<unsigned int> SoundAL::listenerSources;
31 glm::vec3 SoundAL::lastPosition(0.0f, 0.0f, 0.0f);
32 
34  if (init) {
35  Log::get(LOG_WARNING) << "SoundAL Warning: Already initialized..." << Log::endl;
36  return 0;
37  }
38 
39  ALCdevice* device = alcOpenDevice(nullptr);
40  ALCcontext* context = alcCreateContext(device, nullptr);
41  alcMakeContextCurrent(context);
42 
43  if (alutInitWithoutContext(nullptr, nullptr) == AL_FALSE) {
44  Log::get(LOG_ERROR) << "SoundAL Error: " << alutGetErrorString(alutGetError()) << Log::endl;
45  return -1;
46  }
47 
48  init = true;
50 
51  alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
52 
53  lastPosition = glm::vec3(0.0f, 0.0f, 0.0f);
54  glm::vec3 at(0.0f, 0.0f, -1.0f);
55  glm::vec3 up(0.0f, 1.0f, 0.0f);
56  listenAt(lastPosition, at, up);
57 
58  return 0;
59 }
60 
62  if (!init) {
63  Log::get(LOG_ERROR) << "SoundAL Error: Shutdown but not initialized!" << Log::endl;
64  return;
65  }
66 
67  clear();
68  init = false;
69 
70  if (alutExit() == AL_FALSE)
71  Log::get(LOG_ERROR) << "SoundAL Error: " << alutGetErrorString(alutGetError()) << Log::endl;
72 }
73 
75  if (!init) {
76  Log::get(LOG_ERROR) << "SoundAL Error: Clear but not initialized!" << Log::endl;
77  return;
78  }
79 
80  stopAll();
81 
82  alGetError();
83  alDeleteSources(sources.size(), &sources[0]);
84  sources.clear();
85  if (alGetError() != AL_NO_ERROR) {
86  Log::get(LOG_ERROR) << "SoundAL: Error while deleting sources!" << Log::endl;
87  }
88 
89  alGetError();
90  alDeleteSources(listenerSources.size(), &listenerSources[0]);
91  listenerSources.clear();
92  if (alGetError() != AL_NO_ERROR) {
93  Log::get(LOG_ERROR) << "SoundAL: Error while deleting listener sources!" << Log::endl;
94  }
95 
96  alGetError();
97  alDeleteBuffers(buffers.size(), &buffers[0]);
98  buffers.clear();
99  if (alGetError() != AL_NO_ERROR) {
100  Log::get(LOG_ERROR) << "SoundAL: Error while deleting buffers!" << Log::endl;
101  }
102 
103  lastPosition = glm::vec3(0.0f, 0.0f, 0.0f);
104  glm::vec3 at(0.0f, 0.0f, -1.0f);
105  glm::vec3 up(0.0f, 1.0f, 0.0f);
106  listenAt(lastPosition, at, up);
107 }
108 
110  return buffers.size();
111 }
112 
113 int SoundAL::loadBuffer(unsigned char* buffer, unsigned int length) {
114  if (!init) {
115  Log::get(LOG_ERROR) << "SoundAL Error: Buffer load, but not initialized!" << Log::endl;
116  return -1;
117  }
118 
119  alGetError();
120  unsigned int r = alutCreateBufferFromFileImage(buffer, length);
121  if (r == AL_NONE) {
122  Log::get(LOG_ERROR) << "SoundAL Error: " << alutGetErrorString(alutGetError()) << Log::endl;
123  return -2;
124  }
125  buffers.push_back(r);
126  return r;
127 }
128 
129 int SoundAL::numSources(bool atListener) {
130  if (atListener)
131  return listenerSources.size();
132  else
133  return sources.size();
134 }
135 
136 int SoundAL::addSource(int buffer, float volume, bool atListener, bool loop) {
137  if (!init) {
138  Log::get(LOG_ERROR) << "SoundAL Error: Adding source, but not initialized!" << Log::endl;
139  return -1;
140  }
141 
142  if ((buffer < 0) || (buffer >= buffers.size())) {
143  Log::get(LOG_ERROR) << "SoundAL Error: Adding source, but '" << buffer
144  << "' invalid (max '" << buffers.size() << "')!" << Log::endl;
145  return -2;
146  }
147 
148  unsigned int id;
149 
150  alGetError();
151  alGenSources(1, &id);
152  if (alGetError() != AL_NO_ERROR) {
153  Log::get(LOG_ERROR) << "SoundAL Error: Could not create source!" << Log::endl;
154  return -3;
155  }
156 
157  alSourcei(id, AL_BUFFER, buffers.at(buffer));
158  alSourcef(id, AL_GAIN, volume);
159  alSourcef(id, AL_REFERENCE_DISTANCE, referenceDistance);
160  alSourcef(id, AL_MAX_DISTANCE, maxDistance);
161 
162  if (loop)
163  alSourcei(id, AL_LOOPING, AL_TRUE);
164 
165  if (atListener) {
166  alSourcefv(id, AL_POSITION, &lastPosition[0]);
167  listenerSources.push_back(id);
168  return listenerSources.size() - 1;
169  } else {
170  sources.push_back(id);
171  return sources.size() - 1;
172  }
173 }
174 
175 int SoundAL::sourceAt(int source, glm::vec3 pos) {
176  if (!init) {
177  Log::get(LOG_ERROR) << "SoundAL Error: Positioning source, but not initialized!" << Log::endl;
178  return -1;
179  }
180 
181  if ((source < 0) || (source >= sources.size())) {
182  Log::get(LOG_ERROR) << "SoundAL: Can't position non-existing source!" << Log::endl;
183  return -2;
184  }
185 
186  alSourcefv(sources.at(source), AL_POSITION, &pos[0]);
187 
188  return 0;
189 }
190 
191 void SoundAL::listenAt(glm::vec3 pos, glm::vec3 at, glm::vec3 up) {
192  if (!init) {
193  Log::get(LOG_ERROR) << "SoundAL Error: Positioning listener, but not initialized!" << Log::endl;
194  return;
195  }
196 
197  float orientation[6] = { at.x, at.y, at.z, up.x, up.y, up.z };
198  alListenerfv(AL_POSITION, &pos[0]);
199  alListenerfv(AL_ORIENTATION, orientation);
200 
201  for (auto& s : listenerSources) {
202  alSourcefv(s, AL_POSITION, &pos[0]);
203  }
204 
205  lastPosition = pos;
206 }
207 
208 void SoundAL::play(int source, bool atListener) {
209  if ((!init) || (!enabled))
210  return;
211 
212  if (atListener) {
213  if ((source >= 0) && (source < listenerSources.size()))
214  alSourcePlay(listenerSources.at(source));
215  else
216  Log::get(LOG_ERROR) << "SoundAL: Can't play non-existing listener source!" << Log::endl;
217  } else {
218  if ((source >= 0) && (source < sources.size()))
219  alSourcePlay(sources.at(source));
220  else
221  Log::get(LOG_ERROR) << "SoundAL: Can't play non-existing source!" << Log::endl;
222  }
223 }
224 
225 void SoundAL::stop(int source) {
226  if (!init)
227  return;
228 
229  if ((source >= 0) && (source < sources.size()))
230  alSourceStop(sources.at(source));
231  else
232  Log::get(LOG_ERROR) << "SoundAL: Can't stop non-existing source!" << Log::endl;
233 }
234 
236  if (!init)
237  return;
238 
239  alSourceStopv(sources.size(), &sources[0]);
240  alSourceStopv(listenerSources.size(), &listenerSources[0]);
241 }
242 
243 void SoundAL::setEnabled(bool on) {
244  enabled = on;
245 }
246 
248  return enabled;
249 }
250 
251 void SoundAL::setVolume(float vol) {
252  volume = vol;
253 
254  if (init)
255  alListenerf(AL_GAIN, volume);
256 }
257 
259  return volume;
260 }
261 
static void setEnabled(bool on)
Definition: SoundAL.cpp:243
#define LOG_WARNING
Definition: Log.h:20
static const float referenceDistance
Definition: SoundAL.cpp:22
static int initialize()
Definition: SoundAL.cpp:33
static void clear()
Definition: SoundAL.cpp:74
static float getVolume()
Definition: SoundAL.cpp:258
static int loadBuffer(unsigned char *buffer, unsigned int length)
Definition: SoundAL.cpp:113
static glm::vec3 lastPosition
Definition: SoundAL.h:47
Included everywhere.
static LogLevel & get(int level)
Definition: Log.cpp:14
Global Logging Utility.
static bool init
Definition: SoundAL.h:39
static void stopAll()
Definition: SoundAL.cpp:235
OpenAL Sound Implementation.
static bool enabled
Definition: SoundAL.h:40
static void play(int source, bool atListener)
Definition: SoundAL.cpp:208
static const float soundTravelSectors
Definition: SoundAL.cpp:21
static int numSources(bool atListener)
Definition: SoundAL.cpp:129
static const char endl
Definition: Log.h:35
static std::vector< unsigned int > listenerSources
Definition: SoundAL.h:45
static bool getEnabled()
Definition: SoundAL.cpp:247
static std::vector< unsigned int > sources
Definition: SoundAL.h:44
#define LOG_ERROR
Definition: Log.h:19
static void stop(int source)
Definition: SoundAL.cpp:225
static void setVolume(float vol)
Definition: SoundAL.cpp:251
static void listenAt(glm::vec3 pos, glm::vec3 at, glm::vec3 up)
Definition: SoundAL.cpp:191
static void shutdown()
Definition: SoundAL.cpp:61
static int numBuffers()
Definition: SoundAL.cpp:109
static std::vector< unsigned int > buffers
Definition: SoundAL.h:43
static float volume
Definition: SoundAL.h:41
static int addSource(int buffer, float volume, bool atListener, bool loop)
Definition: SoundAL.cpp:136
static const float maxDistance
Definition: SoundAL.cpp:23
static int sourceAt(int source, glm::vec3 pos)
Definition: SoundAL.cpp:175