Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SoundAL.cpp 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*!
  2. * \file src/system/SoundAL.cpp
  3. * \brief This is the OpenAL audio manager Implementation
  4. *
  5. * \author Mongoose
  6. * \author xythobuz
  7. */
  8. #ifdef __APPLE__
  9. #include <OpenAL/al.h>
  10. #else
  11. #include <AL/al.h>
  12. #include <fcntl.h>
  13. #include <unistd.h>
  14. #endif
  15. #include <AL/alut.h>
  16. #include "global.h"
  17. #include "Log.h"
  18. #include "system/SoundAL.h"
  19. bool SoundAL::init = false;
  20. bool SoundAL::enabled = true;
  21. float SoundAL::volume = 1.0f;
  22. std::vector<unsigned int> SoundAL::buffers;
  23. std::vector<unsigned int> SoundAL::sources;
  24. std::vector<unsigned int> SoundAL::listenerSources;
  25. float SoundAL::lastPosition[3] = { 0.0f, 0.0f, 0.0f };
  26. int SoundAL::initialize() {
  27. if (init)
  28. return 0;
  29. ALCdevice* device = alcOpenDevice(nullptr);
  30. ALCcontext* context = alcCreateContext(device, nullptr);
  31. alcMakeContextCurrent(context);
  32. if (alutInitWithoutContext(nullptr, nullptr) == AL_FALSE) {
  33. getLog() << "SoundAL Error: " << alutGetErrorString(alutGetError()) << Log::endl;
  34. return -1;
  35. }
  36. init = true;
  37. setVolume(volume);
  38. return 0;
  39. }
  40. void SoundAL::shutdown() {
  41. if (!init)
  42. return;
  43. clear();
  44. if (alutExit() == AL_FALSE)
  45. getLog() << "SoundAL Error: " << alutGetErrorString(alutGetError()) << Log::endl;
  46. init = false;
  47. }
  48. void SoundAL::clear() {
  49. if (!init)
  50. return;
  51. stopAll();
  52. alGetError();
  53. alDeleteSources(sources.size(), &sources[0]);
  54. sources.clear();
  55. if (alGetError() != AL_NO_ERROR) {
  56. getLog() << "SoundAL: Error while deleting sources!" << Log::endl;
  57. }
  58. alGetError();
  59. alDeleteSources(listenerSources.size(), &listenerSources[0]);
  60. listenerSources.clear();
  61. if (alGetError() != AL_NO_ERROR) {
  62. getLog() << "SoundAL: Error while deleting listener sources!" << Log::endl;
  63. }
  64. alGetError();
  65. alDeleteBuffers(buffers.size(), &buffers[0]);
  66. buffers.clear();
  67. if (alGetError() != AL_NO_ERROR) {
  68. getLog() << "SoundAL: Error while deleting buffers!" << Log::endl;
  69. }
  70. for (int i = 0; i < 3; i++)
  71. lastPosition[i] = 0.0f;
  72. float orientation[6] = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };
  73. listenAt(lastPosition, orientation);
  74. }
  75. int SoundAL::numBuffers() {
  76. return buffers.size();
  77. }
  78. int SoundAL::loadBuffer(unsigned char* buffer, unsigned int length) {
  79. if (!init)
  80. return -1;
  81. alGetError();
  82. unsigned int r = alutCreateBufferFromFileImage(buffer, length);
  83. if (r == AL_NONE) {
  84. getLog() << "SoundAL Error: " << alutGetErrorString(alutGetError()) << Log::endl;
  85. return -2;
  86. }
  87. buffers.push_back(r);
  88. return r;
  89. }
  90. int SoundAL::numSources(bool atListener) {
  91. if (atListener)
  92. return listenerSources.size();
  93. else
  94. return sources.size();
  95. }
  96. int SoundAL::addSource(int buffer, float volume, bool atListener, bool loop) {
  97. if ((!init) || (buffer < 0) || (buffer >= buffers.size()))
  98. return -1;
  99. unsigned int id;
  100. alGetError();
  101. alGenSources(1, &id);
  102. if (alGetError() != AL_NO_ERROR) {
  103. getLog() << "SoundAL Error: Could not create source!" << Log::endl;
  104. return -2;
  105. }
  106. alSourcei(id, AL_BUFFER, buffers.at(buffer));
  107. alSourcef(id, AL_GAIN, volume);
  108. if (loop)
  109. alSourcei(id, AL_LOOPING, AL_TRUE);
  110. if (atListener) {
  111. alSourcefv(id, AL_POSITION, lastPosition);
  112. listenerSources.push_back(id);
  113. return listenerSources.size() - 1;
  114. } else {
  115. sources.push_back(id);
  116. return sources.size() - 1;
  117. }
  118. }
  119. int SoundAL::sourceAt(int source, float pos[3]) {
  120. if (!init)
  121. return -1;
  122. if ((source < 0) || (source >= sources.size()) || (pos == nullptr)) {
  123. getLog() << "SoundAL: Can't position non-existing source!" << Log::endl;
  124. return -2;
  125. }
  126. alSourcefv(sources.at(source), AL_POSITION, pos);
  127. return 0;
  128. }
  129. void SoundAL::listenAt(float pos[3], float orientation[6]) {
  130. if ((!init) || (pos == nullptr) || (orientation == nullptr))
  131. return;
  132. alListenerfv(AL_POSITION, pos);
  133. alListenerfv(AL_ORIENTATION, orientation);
  134. for (auto& s : listenerSources) {
  135. alSourcefv(s, AL_POSITION, pos);
  136. }
  137. for (int i = 0; i < 3; i++)
  138. lastPosition[i] = pos[i];
  139. }
  140. void SoundAL::play(int source, bool atListener) {
  141. if ((!init) || (!enabled))
  142. return;
  143. if (atListener) {
  144. if ((source >= 0) && (source < listenerSources.size()))
  145. alSourcePlay(listenerSources.at(source));
  146. else
  147. getLog() << "SoundAL: Can't play non-existing listener source!" << Log::endl;
  148. } else {
  149. if ((source >= 0) && (source < sources.size()))
  150. alSourcePlay(sources.at(source));
  151. else
  152. getLog() << "SoundAL: Can't play non-existing source!" << Log::endl;
  153. }
  154. }
  155. void SoundAL::stopAll() {
  156. if (!init)
  157. return;
  158. alSourceStopv(sources.size(), &sources[0]);
  159. alSourceStopv(listenerSources.size(), &listenerSources[0]);
  160. }
  161. void SoundAL::setEnabled(bool on) {
  162. enabled = on;
  163. }
  164. bool SoundAL::getEnabled() {
  165. return enabled;
  166. }
  167. void SoundAL::setVolume(float vol) {
  168. volume = vol;
  169. if (init)
  170. alListenerf(AL_GAIN, volume);
  171. }
  172. float SoundAL::getVolume() {
  173. return volume;
  174. }