Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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. }