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.

Sound.cpp 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /*!
  2. * \file Sound.cpp
  3. * \brief This is the audio manager Implementation
  4. *
  5. * Defining UNIT_TEST_SOUND builds Sound class as a console unit test
  6. *
  7. * \author Mongoose
  8. * \author xythobuz
  9. */
  10. #ifdef USING_OPENAL
  11. #ifdef __APPLE__
  12. #include <OpenAL/al.h>
  13. #include <OpenAL/alc.h>
  14. #include <AL/alut.h>
  15. #else
  16. #include <AL/al.h>
  17. #include <AL/alc.h>
  18. #include <AL/alut.h>
  19. #endif
  20. #else
  21. #warning "No OpenAL support. Won't play sound!"
  22. #endif
  23. #include <time.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <sys/time.h>
  27. #include <sys/types.h>
  28. #include <sys/stat.h>
  29. #include <fcntl.h>
  30. #include <unistd.h>
  31. #include <Sound.h>
  32. #ifdef DEBUG_MEMORY
  33. #include <memory_test.h>
  34. #endif
  35. Sound::Sound()
  36. {
  37. mSource[0] = 0;
  38. mBuffer[0] = 0;
  39. mNextBuffer = 0;
  40. mNextSource = 0;
  41. mInit = false;
  42. }
  43. Sound::~Sound()
  44. {
  45. if (mInit)
  46. {
  47. #ifdef USING_OPENAL
  48. alutExit();
  49. #endif
  50. }
  51. }
  52. int Sound::init()
  53. {
  54. #ifndef __APPLE__
  55. int fd;
  56. fd = open("/dev/dsp", O_RDWR);
  57. if (fd < 0)
  58. {
  59. perror("Sound::Init> Could not open /dev/dsp : ");
  60. return -1;
  61. }
  62. close(fd);
  63. #endif
  64. #ifdef USING_OPENAL
  65. alutInit(NULL, 0);
  66. mInit = true;
  67. printf("Created OpenAL Context\n");
  68. #else
  69. printf("Couldn't create sound Context!\n");
  70. #endif
  71. return 0;
  72. }
  73. void Sound::listenAt(float pos[3], float angle[3])
  74. {
  75. if (!mInit)
  76. return;
  77. #ifdef USING_OPENAL
  78. alListenerfv(AL_POSITION, pos);
  79. alListenerfv(AL_ORIENTATION, angle);
  80. #endif
  81. }
  82. void Sound::sourceAt(int source, float pos[3])
  83. {
  84. if (!mInit || source < 0)
  85. return;
  86. #ifdef USING_OPENAL
  87. alSourcefv(mSource[source-1], AL_POSITION, pos);
  88. #endif
  89. }
  90. //! \fixme Seperate sourcing and buffering, Mongoose 2002.01.04
  91. int Sound::addFile(char *filename, int *source, unsigned int flags)
  92. {
  93. #ifdef USING_OPENAL
  94. ALsizei size;
  95. ALfloat freq;
  96. ALenum format;
  97. ALvoid *data;
  98. #endif
  99. if (!mInit || !filename || !source)
  100. {
  101. printf("Sound::AddFile> ERROR pre condition assertion failed\n");
  102. return -1000;
  103. }
  104. *source = -1;
  105. #ifdef USING_OPENAL
  106. alGetError();
  107. alGenBuffers(1, &mBuffer[mNextBuffer]);
  108. if (alGetError() != AL_NO_ERROR)
  109. {
  110. fprintf(stderr, "Sound::AddFile> alGenBuffers call failed\n");
  111. return -1;
  112. }
  113. alGetError();
  114. alGenSources(1, &mSource[mNextSource]);
  115. if (alGetError() != AL_NO_ERROR)
  116. {
  117. fprintf(stderr, "Sound::AddFile> alGenSources call failed\n");
  118. return -2;
  119. }
  120. // err = alutLoadWAV(filename, &data, &format, &size, &bits, &freq);
  121. // is deprecated!
  122. data = alutLoadMemoryFromFile(filename, &format, &size, &freq);
  123. if (alGetError() != AL_NO_ERROR)
  124. {
  125. fprintf(stderr, "Could not load %s\n", filename);
  126. return -3;
  127. }
  128. alBufferData(mBuffer[mNextBuffer], format, data, size, freq);
  129. alSourcei(mSource[mNextSource], AL_BUFFER, mBuffer[mNextBuffer]);
  130. if (flags & SoundFlagsLoop)
  131. {
  132. alSourcei(mSource[mNextSource], AL_LOOPING, 1);
  133. }
  134. ++mNextBuffer;
  135. ++mNextSource;
  136. *source = mNextBuffer;
  137. return 0;
  138. #else
  139. return -1;
  140. #endif
  141. }
  142. int Sound::addWave(unsigned char *wav, unsigned int length, int *source, unsigned int flags)
  143. {
  144. #ifdef USING_OPENAL
  145. ALsizei size;
  146. ALfloat freq;
  147. ALenum format;
  148. ALvoid *data;
  149. #endif
  150. if (!mInit || !wav || !source)
  151. {
  152. printf("Sound::AddWave> ERROR pre condition assertion failed\n");
  153. return -1000;
  154. }
  155. *source = -1;
  156. #ifdef USING_OPENAL
  157. data = wav;
  158. alGetError();
  159. alGenBuffers(1, &mBuffer[mNextBuffer]);
  160. if (alGetError() != AL_NO_ERROR)
  161. {
  162. fprintf(stderr, "Sound::AddWave> alGenBuffers call failed\n");
  163. return -1;
  164. }
  165. alGetError();
  166. alGenSources(1, &mSource[mNextSource]);
  167. if (alGetError() != AL_NO_ERROR)
  168. {
  169. fprintf(stderr, "Sound::AddWave> alGenSources call failed\n");
  170. return -2;
  171. }
  172. //AL_FORMAT_WAVE_EXT does not exist on Mac!"
  173. // alBufferData(mBuffer[mNextBuffer], AL_FORMAT_WAVE_EXT, data, size, freq);
  174. // Idea: Fill Buffer with
  175. // alutLoadMemoryFromFileImage
  176. // (const ALvoid *data, ALsizei length, ALenum *format, ALsizei *size, ALfloat *frequency)
  177. data = alutLoadMemoryFromFileImage(wav, length, &format, &size, &freq);
  178. if ((alGetError() != AL_NO_ERROR) || (data == NULL)) {
  179. fprintf(stderr, "Could not load wav buffer\n");
  180. return -3;
  181. }
  182. alBufferData(mBuffer[mNextBuffer], format, data, size, freq);
  183. alSourcei(mSource[mNextSource], AL_BUFFER, mBuffer[mNextBuffer]);
  184. if (flags & SoundFlagsLoop)
  185. {
  186. alSourcei(mSource[mNextSource], AL_LOOPING, 1);
  187. }
  188. ++mNextBuffer;
  189. ++mNextSource;
  190. *source = mNextBuffer;
  191. return 0;
  192. #else
  193. return -1;
  194. #endif
  195. }
  196. void Sound::play(int source)
  197. {
  198. if (!mInit)
  199. {
  200. printf("Sound::Play> ERROR: Sound not initialized\n");
  201. return;
  202. }
  203. if (source < 0)
  204. {
  205. printf("Sound::Play> ERROR: Source Id invalid\n");
  206. return;
  207. }
  208. #ifdef USING_OPENAL
  209. alSourcePlay(mSource[source-1]);
  210. #endif
  211. }
  212. void Sound::stop(int source)
  213. {
  214. if (!mInit || source < 0)
  215. {
  216. printf("Sound::Stop> ERROR pre condition assertion failed\n");
  217. return;
  218. }
  219. #ifdef USING_OPENAL
  220. alSourceStop(mSource[source-1]);
  221. #endif
  222. }
  223. ///////////////////////////////////////////////////////
  224. #ifdef UNIT_TEST_SOUND
  225. /*!
  226. * \brief Sound Unit Test
  227. * \param argc Number of arguments. Has to be > 1
  228. * \param argv Argument array. argv[1] will be played as wav file
  229. * \returns always zero
  230. */
  231. int main(int argc, char* argv[])
  232. {
  233. Sound snd;
  234. FILE *f;
  235. unsigned int l;
  236. unsigned char *buf;
  237. int id, ret;
  238. if (argc > 1)
  239. {
  240. snd.init();
  241. printf("Loading %s\n", argv[1]);
  242. ret = snd.addFile(argv[1], &id, snd.SoundFlagsNone);
  243. printf("Load returned %i\n", ret);
  244. printf("Playing %u::%s\n", id, argv[1]);
  245. snd.play(id);
  246. printf("Waiting...\n");
  247. sleep(1);
  248. f = fopen(argv[1], "rb");
  249. if (f)
  250. {
  251. fseek(f, 0, SEEK_END);
  252. l = ftell(f);
  253. fseek(f, 0, SEEK_SET);
  254. buf = new unsigned char[l];
  255. fread(buf, l, 1, f);
  256. fclose(f);
  257. printf("Loading buffer of %s\n", argv[1]);
  258. ret = snd.addWave(buf, l, &id, snd.SoundFlagsNone);
  259. printf("Load returned %i\n", ret);
  260. printf("Playing buffer of %u::%s\n", id, argv[1]);
  261. snd.play(id);
  262. delete [] buf;
  263. printf("Waiting...\n");
  264. sleep(1);
  265. }
  266. }
  267. else
  268. {
  269. printf("%s filename.wav\n", argv[0]);
  270. }
  271. return 0;
  272. }
  273. #endif