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.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /*!
  2. * \file src/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 <cstdio>
  17. #include <cstdlib>
  18. #include <assert.h>
  19. #include "math/math.h"
  20. #include "SoundAL.h"
  21. SoundAL::SoundAL() {
  22. mEnabled = false;
  23. mInit = false;
  24. mVolume = 1.0f;
  25. }
  26. SoundAL::~SoundAL() {
  27. if (mInit)
  28. alutExit();
  29. }
  30. int SoundAL::initialize() {
  31. assert(mInit == false);
  32. if (!mEnabled)
  33. return 0;
  34. #ifndef __APPLE__
  35. int fd = open("/dev/dsp", O_RDWR);
  36. if (fd < 0) {
  37. printf("Could not initialize OpenAL (/dev/dsp)\n");
  38. return -1;
  39. }
  40. close(fd);
  41. #endif
  42. ALCdevice *Device = alcOpenDevice("OSS");
  43. ALCcontext *Context = alcCreateContext(Device, NULL);
  44. alcMakeContextCurrent(Context);
  45. if (alutInitWithoutContext(NULL, NULL) == AL_FALSE) {
  46. printf("ALUT-Error: %s\n", alutGetErrorString(alutGetError()));
  47. return -2;
  48. }
  49. mInit = true;
  50. return 0;
  51. }
  52. void SoundAL::setEnabled(bool on) {
  53. mEnabled = on;
  54. }
  55. void SoundAL::setVolume(float vol) {
  56. assert(mSource.size() == mBuffer.size());
  57. if (mEnabled) {
  58. if ((mSource.size() > 0) && (!equalEpsilon(mVolume, vol))) {
  59. // Apply new volume to old sources if needed
  60. for (size_t i = 0; i < mSource.size(); i++)
  61. alSourcef(mSource[i], AL_GAIN, vol);
  62. }
  63. }
  64. mVolume = vol;
  65. }
  66. int SoundAL::registeredSources() {
  67. assert(mSource.size() == mBuffer.size());
  68. if ((!mEnabled) || (!mInit))
  69. return 0;
  70. return mSource.size();
  71. }
  72. void SoundAL::clear() {
  73. assert(mSource.size() == mBuffer.size());
  74. if ((!mEnabled) || (!mInit))
  75. return;
  76. for (size_t i = 0; i < mSource.size(); i++) {
  77. alDeleteSources(1, &mSource[i]);
  78. alDeleteBuffers(1, &mBuffer[i]);
  79. }
  80. mSource.clear();
  81. mBuffer.clear();
  82. }
  83. void SoundAL::listenAt(float pos[3], float angle[3]) {
  84. assert(mSource.size() == mBuffer.size());
  85. assert(pos != NULL);
  86. assert(angle != NULL);
  87. if ((!mEnabled) || (!mInit))
  88. return;
  89. alListenerfv(AL_POSITION, pos);
  90. alListenerfv(AL_ORIENTATION, angle);
  91. }
  92. void SoundAL::sourceAt(int source, float pos[3]) {
  93. assert(mSource.size() == mBuffer.size());
  94. assert(source >= 0);
  95. assert(source < (int)mSource.size());
  96. assert(pos != NULL);
  97. if ((!mEnabled) || (!mInit))
  98. return;
  99. alSourcefv(mSource[source], AL_POSITION, pos);
  100. }
  101. //! \fixme Seperate sourcing and buffering, Mongoose 2002.01.04
  102. int SoundAL::addFile(const char *filename, int *source, unsigned int flags) {
  103. ALsizei size;
  104. ALfloat freq;
  105. ALenum format;
  106. ALvoid *data;
  107. int id;
  108. assert(mSource.size() == mBuffer.size());
  109. assert(filename != NULL);
  110. assert(filename[0] != '\0');
  111. assert(source != NULL);
  112. if ((!mEnabled) || (!mInit)) {
  113. *source = 0;
  114. return 0;
  115. }
  116. *source = -1;
  117. id = mSource.size();
  118. mSource.push_back(0);
  119. mBuffer.push_back(0);
  120. alGetError();
  121. alGenBuffers(1, &mBuffer[id]);
  122. if (alGetError() != AL_NO_ERROR) {
  123. printf("Could not load wav file (alGenBuffers)\n");
  124. return -1;
  125. }
  126. alGetError();
  127. alGenSources(1, &mSource[id]);
  128. if (alGetError() != AL_NO_ERROR) {
  129. printf("Could not load wav file (alGenSources)\n");
  130. return -2;
  131. }
  132. data = alutLoadMemoryFromFile(filename, &format, &size, &freq);
  133. if (alutGetError() != ALUT_ERROR_NO_ERROR) {
  134. printf("Could not load %s\n", filename);
  135. return -3;
  136. }
  137. alBufferData(mBuffer[id], format, data, size, static_cast<ALsizei>(freq));
  138. alSourcei(mSource[id], AL_BUFFER, mBuffer[id]);
  139. if (flags & SoundFlagsLoop) {
  140. alSourcei(mSource[id], AL_LOOPING, 1);
  141. }
  142. alSourcef(mSource[id], AL_GAIN, mVolume);
  143. *source = id;
  144. return 0;
  145. }
  146. int SoundAL::addWave(unsigned char *wav, unsigned int length, int *source, unsigned int flags) {
  147. ALsizei size;
  148. ALfloat freq;
  149. ALenum format;
  150. ALvoid *data;
  151. int error = 0;
  152. int id;
  153. assert(mSource.size() == mBuffer.size());
  154. assert(wav != NULL);
  155. assert(source != NULL);
  156. if ((!mEnabled) || (!mInit)) {
  157. *source = 0;
  158. return 0;
  159. }
  160. *source = -1;
  161. id = mSource.size();
  162. mSource.push_back(0);
  163. mBuffer.push_back(0);
  164. data = wav;
  165. alGetError();
  166. alGenBuffers(1, &mBuffer[id]);
  167. if (alGetError() != AL_NO_ERROR) {
  168. printf("Could not load wav (alGenBuffers)\n");
  169. return -1;
  170. }
  171. alGetError();
  172. alGenSources(1, &mSource[id]);
  173. if (alGetError() != AL_NO_ERROR) {
  174. printf("Could not load wav (alGenSources)\n");
  175. return -2;
  176. }
  177. data = alutLoadMemoryFromFileImage(wav, length, &format, &size, &freq);
  178. if (((error = alutGetError()) != ALUT_ERROR_NO_ERROR) || (data == NULL)) {
  179. printf("Could not load wav buffer (%s)\n", alutGetErrorString(error));
  180. return -3;
  181. }
  182. alBufferData(mBuffer[id], format, data, size, static_cast<ALsizei>(freq));
  183. alSourcei(mSource[id], AL_BUFFER, mBuffer[id]);
  184. if (flags & SoundFlagsLoop) {
  185. alSourcei(mSource[id], AL_LOOPING, 1);
  186. }
  187. alSourcef(mSource[id], AL_GAIN, mVolume);
  188. *source = id;
  189. //! \fixme Should free alut buffer?
  190. return 0;
  191. }
  192. void SoundAL::play(int source) {
  193. assert(mSource.size() == mBuffer.size());
  194. assert(source >= 0);
  195. assert(source < (int)mSource.size());
  196. if ((!mEnabled) || (!mInit))
  197. return;
  198. alSourcePlay(mSource[source]);
  199. }
  200. void SoundAL::stop(int source) {
  201. assert(mSource.size() == mBuffer.size());
  202. assert(source >= 0);
  203. assert(source < (int)mSource.size());
  204. if ((!mEnabled) || (!mInit))
  205. return;
  206. alSourceStop(mSource[source]);
  207. }