Audio.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /**
  2. * Copyright (c) 2006-2013 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() : distanceModel(DISTANCE_INVERSE_CLAMPED)
  61. {
  62. // Passing zero for default device.
  63. device = alcOpenDevice(0);
  64. if (device == 0)
  65. throw love::Exception("Could not open device.");
  66. context = alcCreateContext(device, 0);
  67. if (context == 0)
  68. throw love::Exception("Could not create context.");
  69. alcMakeContextCurrent(context);
  70. if (alcGetError(device) != ALC_NO_ERROR)
  71. throw love::Exception("Could not make context current.");
  72. /*std::string captureName(alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
  73. const ALCchar * devices = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
  74. while (*devices)
  75. {
  76. std::string device(devices);
  77. devices += device.size() + 1;
  78. if (device.find("Mic") != std::string::npos || device.find("mic") != std::string::npos)
  79. {
  80. captureName = device;
  81. }
  82. }
  83. capture = alcCaptureOpenDevice(captureName.c_str(), 8000, AL_FORMAT_MONO16, 262144); // about 32 seconds
  84. if (!capture)
  85. {
  86. // We're not going to prevent LOVE from running without a microphone, but we should warn, at least
  87. std::cerr << "Warning, couldn't open capture device! No audio input!" << std::endl;
  88. }*/
  89. // pool must be allocated after AL context.
  90. pool = new Pool();
  91. poolThread = new PoolThread(pool);
  92. poolThread->start();
  93. }
  94. Audio::~Audio()
  95. {
  96. poolThread->setFinish();
  97. poolThread->wait();
  98. delete poolThread;
  99. delete pool;
  100. alcMakeContextCurrent(0);
  101. alcDestroyContext(context);
  102. //if (capture) alcCaptureCloseDevice(capture);
  103. alcCloseDevice(device);
  104. }
  105. const char *Audio::getName() const
  106. {
  107. return "love.audio.openal";
  108. }
  109. love::audio::Source *Audio::newSource(love::sound::Decoder *decoder)
  110. {
  111. return new Source(pool, decoder);
  112. }
  113. love::audio::Source *Audio::newSource(love::sound::SoundData *soundData)
  114. {
  115. return new Source(pool, soundData);
  116. }
  117. int Audio::getNumSources() const
  118. {
  119. return pool->getNumSources();
  120. }
  121. int Audio::getMaxSources() const
  122. {
  123. return pool->getMaxSources();
  124. }
  125. void Audio::play(love::audio::Source *source)
  126. {
  127. source->play();
  128. }
  129. void Audio::stop(love::audio::Source *source)
  130. {
  131. source->stop();
  132. }
  133. void Audio::stop()
  134. {
  135. pool->stop();
  136. }
  137. void Audio::pause(love::audio::Source *source)
  138. {
  139. source->pause();
  140. }
  141. void Audio::pause()
  142. {
  143. pool->pause();
  144. }
  145. void Audio::resume(love::audio::Source *source)
  146. {
  147. source->resume();
  148. }
  149. void Audio::resume()
  150. {
  151. pool->resume();
  152. }
  153. void Audio::rewind(love::audio::Source *source)
  154. {
  155. source->rewind();
  156. }
  157. void Audio::rewind()
  158. {
  159. pool->rewind();
  160. }
  161. void Audio::setVolume(float volume)
  162. {
  163. alListenerf(AL_GAIN, volume);
  164. }
  165. float Audio::getVolume() const
  166. {
  167. ALfloat volume;
  168. alGetListenerf(AL_GAIN, &volume);
  169. return volume;
  170. }
  171. void Audio::getPosition(float *v) const
  172. {
  173. alGetListenerfv(AL_POSITION, v);
  174. }
  175. void Audio::setPosition(float *v)
  176. {
  177. alListenerfv(AL_POSITION, v);
  178. }
  179. void Audio::getOrientation(float *v) const
  180. {
  181. alGetListenerfv(AL_ORIENTATION, v);
  182. }
  183. void Audio::setOrientation(float *v)
  184. {
  185. alListenerfv(AL_ORIENTATION, v);
  186. }
  187. void Audio::getVelocity(float *v) const
  188. {
  189. alGetListenerfv(AL_VELOCITY, v);
  190. }
  191. void Audio::setVelocity(float *v)
  192. {
  193. alListenerfv(AL_VELOCITY, v);
  194. }
  195. void Audio::record()
  196. {
  197. if (!canRecord()) return;
  198. alcCaptureStart(capture);
  199. }
  200. love::sound::SoundData *Audio::getRecordedData()
  201. {
  202. if (!canRecord())
  203. return NULL;
  204. int samplerate = 8000;
  205. ALCint samples;
  206. alcGetIntegerv(capture, ALC_CAPTURE_SAMPLES, 4, &samples);
  207. void *data = malloc(samples * (2/sizeof(char)));
  208. alcCaptureSamples(capture, data, samples);
  209. love::sound::SoundData *sd = new love::sound::SoundData(data, samples, samplerate, 16, 1);
  210. free(data);
  211. return sd;
  212. }
  213. love::sound::SoundData *Audio::stopRecording(bool returnData)
  214. {
  215. if (!canRecord())
  216. return NULL;
  217. love::sound::SoundData *sd = NULL;
  218. if (returnData)
  219. {
  220. sd = getRecordedData();
  221. }
  222. alcCaptureStop(capture);
  223. return sd;
  224. }
  225. bool Audio::canRecord()
  226. {
  227. return (capture != NULL);
  228. }
  229. Audio::DistanceModel Audio::getDistanceModel() const
  230. {
  231. return this->distanceModel;
  232. }
  233. void Audio::setDistanceModel(DistanceModel distanceModel)
  234. {
  235. this->distanceModel = distanceModel;
  236. switch (distanceModel)
  237. {
  238. case DISTANCE_NONE:
  239. alDistanceModel(AL_NONE);
  240. break;
  241. case DISTANCE_INVERSE:
  242. alDistanceModel(AL_INVERSE_DISTANCE);
  243. break;
  244. case DISTANCE_INVERSE_CLAMPED:
  245. alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
  246. break;
  247. case DISTANCE_LINEAR:
  248. alDistanceModel(AL_LINEAR_DISTANCE);
  249. break;
  250. case DISTANCE_LINEAR_CLAMPED:
  251. alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
  252. break;
  253. case DISTANCE_EXPONENT:
  254. alDistanceModel(AL_EXPONENT_DISTANCE);
  255. break;
  256. case DISTANCE_EXPONENT_CLAMPED:
  257. alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
  258. break;
  259. default:
  260. break;
  261. }
  262. }
  263. } // openal
  264. } // audio
  265. } // love