Audio.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /**
  2. * Copyright (c) 2006-2014 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #include "Audio.h"
  21. #include "common/delay.h"
  22. #include "sound/Decoder.h"
  23. #include <cstdlib>
  24. namespace love
  25. {
  26. namespace audio
  27. {
  28. namespace openal
  29. {
  30. Audio::PoolThread::PoolThread(Pool *pool)
  31. : pool(pool)
  32. , finish(false)
  33. {
  34. mutex = thread::newMutex();
  35. }
  36. Audio::PoolThread::~PoolThread()
  37. {
  38. delete mutex;
  39. }
  40. void Audio::PoolThread::threadFunction()
  41. {
  42. while (true)
  43. {
  44. {
  45. thread::Lock lock(mutex);
  46. if (finish)
  47. {
  48. return;
  49. }
  50. }
  51. pool->update();
  52. delay(5);
  53. }
  54. }
  55. void Audio::PoolThread::setFinish()
  56. {
  57. thread::Lock lock(mutex);
  58. finish = true;
  59. }
  60. Audio::Audio()
  61. : distanceModel(DISTANCE_INVERSE_CLAMPED)
  62. {
  63. // Passing zero for default device.
  64. device = alcOpenDevice(0);
  65. if (device == 0)
  66. throw love::Exception("Could not open device.");
  67. context = alcCreateContext(device, 0);
  68. if (context == 0)
  69. throw love::Exception("Could not create context.");
  70. alcMakeContextCurrent(context);
  71. if (alcGetError(device) != ALC_NO_ERROR)
  72. throw love::Exception("Could not make context current.");
  73. /*std::string captureName(alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
  74. const ALCchar * devices = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
  75. while (*devices)
  76. {
  77. std::string device(devices);
  78. devices += device.size() + 1;
  79. if (device.find("Mic") != std::string::npos || device.find("mic") != std::string::npos)
  80. {
  81. captureName = device;
  82. }
  83. }
  84. capture = alcCaptureOpenDevice(captureName.c_str(), 8000, AL_FORMAT_MONO16, 262144); // about 32 seconds
  85. if (!capture)
  86. {
  87. // We're not going to prevent LOVE from running without a microphone, but we should warn, at least
  88. std::cerr << "Warning, couldn't open capture device! No audio input!" << std::endl;
  89. }*/
  90. // pool must be allocated after AL context.
  91. pool = new Pool();
  92. poolThread = new PoolThread(pool);
  93. poolThread->start();
  94. }
  95. Audio::~Audio()
  96. {
  97. poolThread->setFinish();
  98. poolThread->wait();
  99. delete poolThread;
  100. delete pool;
  101. alcMakeContextCurrent(0);
  102. alcDestroyContext(context);
  103. //if (capture) alcCaptureCloseDevice(capture);
  104. alcCloseDevice(device);
  105. }
  106. const char *Audio::getName() const
  107. {
  108. return "love.audio.openal";
  109. }
  110. love::audio::Source *Audio::newSource(love::sound::Decoder *decoder)
  111. {
  112. return new Source(pool, decoder);
  113. }
  114. love::audio::Source *Audio::newSource(love::sound::SoundData *soundData)
  115. {
  116. return new Source(pool, soundData);
  117. }
  118. int Audio::getSourceCount() const
  119. {
  120. return pool->getSourceCount();
  121. }
  122. int Audio::getMaxSources() const
  123. {
  124. return pool->getMaxSources();
  125. }
  126. void Audio::play(love::audio::Source *source)
  127. {
  128. source->play();
  129. }
  130. void Audio::stop(love::audio::Source *source)
  131. {
  132. source->stop();
  133. }
  134. void Audio::stop()
  135. {
  136. pool->stop();
  137. }
  138. void Audio::pause(love::audio::Source *source)
  139. {
  140. source->pause();
  141. }
  142. void Audio::pause()
  143. {
  144. pool->pause();
  145. }
  146. void Audio::resume(love::audio::Source *source)
  147. {
  148. source->resume();
  149. }
  150. void Audio::resume()
  151. {
  152. pool->resume();
  153. }
  154. void Audio::rewind(love::audio::Source *source)
  155. {
  156. source->rewind();
  157. }
  158. void Audio::rewind()
  159. {
  160. pool->rewind();
  161. }
  162. void Audio::setVolume(float volume)
  163. {
  164. alListenerf(AL_GAIN, volume);
  165. }
  166. float Audio::getVolume() const
  167. {
  168. ALfloat volume;
  169. alGetListenerf(AL_GAIN, &volume);
  170. return volume;
  171. }
  172. void Audio::getPosition(float *v) const
  173. {
  174. alGetListenerfv(AL_POSITION, v);
  175. }
  176. void Audio::setPosition(float *v)
  177. {
  178. alListenerfv(AL_POSITION, v);
  179. }
  180. void Audio::getOrientation(float *v) const
  181. {
  182. alGetListenerfv(AL_ORIENTATION, v);
  183. }
  184. void Audio::setOrientation(float *v)
  185. {
  186. alListenerfv(AL_ORIENTATION, v);
  187. }
  188. void Audio::getVelocity(float *v) const
  189. {
  190. alGetListenerfv(AL_VELOCITY, v);
  191. }
  192. void Audio::setVelocity(float *v)
  193. {
  194. alListenerfv(AL_VELOCITY, v);
  195. }
  196. void Audio::record()
  197. {
  198. if (!canRecord()) return;
  199. alcCaptureStart(capture);
  200. }
  201. love::sound::SoundData *Audio::getRecordedData()
  202. {
  203. if (!canRecord())
  204. return NULL;
  205. int samplerate = 8000;
  206. ALCint samples;
  207. alcGetIntegerv(capture, ALC_CAPTURE_SAMPLES, 4, &samples);
  208. void *data = malloc(samples * (2/sizeof(char)));
  209. alcCaptureSamples(capture, data, samples);
  210. love::sound::SoundData *sd = new love::sound::SoundData(data, samples, samplerate, 16, 1);
  211. free(data);
  212. return sd;
  213. }
  214. love::sound::SoundData *Audio::stopRecording(bool returnData)
  215. {
  216. if (!canRecord())
  217. return NULL;
  218. love::sound::SoundData *sd = NULL;
  219. if (returnData)
  220. {
  221. sd = getRecordedData();
  222. }
  223. alcCaptureStop(capture);
  224. return sd;
  225. }
  226. bool Audio::canRecord()
  227. {
  228. return (capture != NULL);
  229. }
  230. Audio::DistanceModel Audio::getDistanceModel() const
  231. {
  232. return this->distanceModel;
  233. }
  234. void Audio::setDistanceModel(DistanceModel distanceModel)
  235. {
  236. this->distanceModel = distanceModel;
  237. switch (distanceModel)
  238. {
  239. case DISTANCE_NONE:
  240. alDistanceModel(AL_NONE);
  241. break;
  242. case DISTANCE_INVERSE:
  243. alDistanceModel(AL_INVERSE_DISTANCE);
  244. break;
  245. case DISTANCE_INVERSE_CLAMPED:
  246. alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
  247. break;
  248. case DISTANCE_LINEAR:
  249. alDistanceModel(AL_LINEAR_DISTANCE);
  250. break;
  251. case DISTANCE_LINEAR_CLAMPED:
  252. alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
  253. break;
  254. case DISTANCE_EXPONENT:
  255. alDistanceModel(AL_EXPONENT_DISTANCE);
  256. break;
  257. case DISTANCE_EXPONENT_CLAMPED:
  258. alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
  259. break;
  260. default:
  261. break;
  262. }
  263. }
  264. } // openal
  265. } // audio
  266. } // love