AudioManager.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. #include <list>
  2. #include <boost/thread.hpp>
  3. #include "core/AudioManager.h"
  4. #include "core/XmlMusicsFile.h"
  5. #include "core/Logger.h"
  6. template<>AudioManager *Ogre::Singleton<AudioManager>::msSingleton = nullptr;
  7. ALsizei AudioManager::m_ChannelBufferNumber = 2;
  8. int AudioManager::m_ChannelBufferSize = 96 * 1024;
  9. AudioManager::AudioManager():
  10. m_Initialized(false),
  11. m_ThreadContinue(true),
  12. m_UpdateMutex(),
  13. m_Music(&m_UpdateMutex)
  14. {
  15. m_ALDevice = alcOpenDevice(nullptr);
  16. if(m_ALDevice != nullptr)
  17. {
  18. m_ALContext = alcCreateContext(m_ALDevice, nullptr);
  19. if(m_ALContext != nullptr)
  20. {
  21. alcMakeContextCurrent(m_ALContext);
  22. // listeners
  23. ALfloat position[3] = { 0.0f, 0.0f, 0.0f };
  24. ALfloat velocity[3] = { 0.0f, 0.0f, 0.0f };
  25. ALfloat orientation[6] = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };
  26. alListenerfv( AL_POSITION, position );
  27. alListenerfv( AL_VELOCITY, velocity );
  28. alListenerfv( AL_ORIENTATION, orientation );
  29. m_Initialized = true;
  30. m_Buffer = new char[m_ChannelBufferSize];
  31. m_UpdateThread = new boost::thread(boost::ref(*this));
  32. LOG_TRIVIAL("AudioManager initialised.");
  33. }
  34. else
  35. {
  36. LOG_ERROR("AudioManager failed to initialised. Could not create context for sound device.");
  37. }
  38. }
  39. else
  40. {
  41. LOG_ERROR("AudioManager failed to initialised. There's no default sound device.");
  42. }
  43. // Load musics
  44. XmlMusicsFile musics("./data/musics.xml");
  45. musics.LoadMusics();
  46. }
  47. AudioManager::~AudioManager()
  48. {
  49. MusicStop();
  50. if(m_Initialized)
  51. {
  52. m_ThreadContinue = false;
  53. m_UpdateThread->join();
  54. delete m_UpdateThread;
  55. delete[] m_Buffer;
  56. alcMakeContextCurrent(nullptr);
  57. alcDestroyContext(m_ALContext);
  58. alcCloseDevice(m_ALDevice);
  59. LOG_TRIVIAL("AudioManager destroyed.");
  60. }
  61. }
  62. void
  63. AudioManager::operator()()
  64. {
  65. while(m_ThreadContinue)
  66. {
  67. Update();
  68. boost::xtime xt;
  69. boost::xtime_get(&xt, boost::TIME_UTC_);
  70. xt.nsec += 250000000; // sleep for 250 ms
  71. boost::thread::sleep(xt);
  72. m_UpdateThread->yield();
  73. }
  74. }
  75. void
  76. AudioManager::Update()
  77. {
  78. boost::recursive_mutex::scoped_lock lock(m_UpdateMutex);
  79. m_Music.Update();
  80. }
  81. void
  82. AudioManager::MusicPause()
  83. {
  84. boost::recursive_mutex::scoped_lock lock(m_UpdateMutex);
  85. m_Music.Pause();
  86. }
  87. void
  88. AudioManager::MusicPlay(const Ogre::String& name)
  89. {
  90. if(m_Initialized)
  91. {
  92. boost::recursive_mutex::scoped_lock lock(m_UpdateMutex);
  93. AudioManager::Music* music = GetMusic(name);
  94. if(music == nullptr)
  95. {
  96. LOG_ERROR("No music found with name \"" + name + "\".");
  97. return;
  98. }
  99. m_Music.SetLoop(music->loop);
  100. m_Music.Play(music->file);
  101. }
  102. }
  103. void
  104. AudioManager::MusicStop()
  105. {
  106. boost::recursive_mutex::scoped_lock lock(m_UpdateMutex);
  107. m_Music.Stop();
  108. }
  109. void
  110. AudioManager::AddMusic(const AudioManager::Music& music)
  111. {
  112. boost::recursive_mutex::scoped_lock lock(m_UpdateMutex);
  113. for(std::list<AudioManager::Music>::iterator it = m_MusicList.begin(); it != m_MusicList.end(); ++it )
  114. {
  115. if(it->name == music.name)
  116. {
  117. LOG_ERROR( "Music with name '" + music.name + "' already exists." );
  118. return;
  119. }
  120. }
  121. m_MusicList.push_back(music);
  122. }
  123. AudioManager::Music*
  124. AudioManager::GetMusic(const Ogre::String& name)
  125. {
  126. boost::recursive_mutex::scoped_lock lock(m_UpdateMutex);
  127. for(auto it = m_MusicList.begin(); it != m_MusicList.end(); ++it)
  128. {
  129. if(it->name == name)
  130. {
  131. return &(*it);
  132. }
  133. }
  134. return nullptr;
  135. }
  136. const char*
  137. AudioManager::ALError()
  138. {
  139. //ALenum error_code = alGetError();
  140. //if( error_code == AL_NO_ERROR )
  141. {
  142. return nullptr;
  143. }
  144. //else
  145. //{
  146. //return alGetString( error_code );
  147. //}
  148. }
  149. const char*
  150. AudioManager::ALCError(const ALCdevice* device)
  151. {
  152. //const ALCdevice *alc_device = ( ( device == nullptr ) ? const_cast< ALCdevice* >( m_ALDevice ) : const_cast< ALCdevice* >( device ) );
  153. //ALCenum error_code = alcGetError( const_cast< ALCdevice* >( alc_device ) );
  154. //if( error_code == ALC_NO_ERROR )
  155. {
  156. return nullptr;
  157. }
  158. //else
  159. //{
  160. //return alcGetString( const_cast< ALCdevice* >( device ), error_code );
  161. //}
  162. }
  163. AudioManager::Player::Player(boost::recursive_mutex* mutex):
  164. m_Loop(-1.0),
  165. m_VorbisInfo(nullptr),
  166. m_VorbisSection(0),
  167. m_StreamFinished(false),
  168. m_UpdateMutex(mutex)
  169. {
  170. }
  171. AudioManager::Player::~Player()
  172. {
  173. Stop();
  174. }
  175. void
  176. AudioManager::Player::Pause()
  177. {
  178. boost::recursive_mutex::scoped_lock lock(*m_UpdateMutex);
  179. alSourcePause(m_Source);
  180. }
  181. void
  182. AudioManager::Player::Play(const Ogre::String &file)
  183. {
  184. boost::recursive_mutex::scoped_lock lock(*m_UpdateMutex);
  185. // open vorbis file
  186. if(ov_fopen(const_cast<char*>(file.c_str()), &m_VorbisFile))
  187. {
  188. LOG_ERROR("Can't play file \"" + file + "\".");
  189. return;
  190. }
  191. // get file info
  192. m_VorbisInfo = ov_info(&m_VorbisFile, -1.0f);
  193. // create sound source
  194. alGenSources(1, &m_Source);
  195. // create buffers
  196. ALuint buffers[m_ChannelBufferNumber];
  197. alGenBuffers(m_ChannelBufferNumber, buffers);
  198. // set source parameters
  199. alSourcei(m_Source, AL_LOOPING, AL_FALSE);
  200. // fill buffers
  201. for(int i = 0; i < m_ChannelBufferNumber; ++i)
  202. {
  203. ALsizei buffer_size = FillBuffer();
  204. if(buffer_size)
  205. {
  206. alBufferData(buffers[i], m_VorbisInfo->channels ==
  207. 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16,
  208. (const ALvoid*)AudioManager::getSingleton().m_Buffer,
  209. (ALsizei)buffer_size, (ALsizei)m_VorbisInfo->rate);
  210. alSourceQueueBuffers(m_Source, 1, &buffers[i]);
  211. }
  212. else
  213. {
  214. m_StreamFinished = true;
  215. alDeleteBuffers(1, &buffers[i]);
  216. }
  217. }
  218. // start playback
  219. alSourcePlay(m_Source);
  220. }
  221. void
  222. AudioManager::Player::Stop()
  223. {
  224. boost::recursive_mutex::scoped_lock lock(*m_UpdateMutex);
  225. // stop source
  226. alSourceStop(m_Source);
  227. // get source buffers
  228. int queued_count = 0;
  229. alGetSourcei(m_Source, AL_BUFFERS_QUEUED, &queued_count);
  230. // unqueue and delete buffers
  231. for(int i = 0; i < queued_count; ++i)
  232. {
  233. ALuint buffer_id;
  234. alSourceUnqueueBuffers(m_Source, 1, &buffer_id);
  235. alDeleteBuffers(1, &buffer_id);
  236. }
  237. // delete source
  238. alDeleteSources(1, &m_Source);
  239. // rest cleanup
  240. ov_clear(&m_VorbisFile);
  241. }
  242. void
  243. AudioManager::Player::SetLoop(const float loop)
  244. {
  245. boost::recursive_mutex::scoped_lock lock(*m_UpdateMutex);
  246. m_Loop = loop;
  247. }
  248. void
  249. AudioManager::Player::Update()
  250. {
  251. // try to fill processed buffers
  252. {
  253. int processed;
  254. alGetSourcei(m_Source, AL_BUFFERS_PROCESSED, &processed);
  255. for(int i = 0; i < processed; ++i)
  256. {
  257. // try fill buffer
  258. ALsizei buffer_size = FillBuffer();
  259. if(buffer_size)
  260. {
  261. ALuint buffer_id;
  262. alSourceUnqueueBuffers(m_Source, 1, &buffer_id);
  263. alBufferData(buffer_id, m_VorbisInfo->channels ==
  264. 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16,
  265. (const ALvoid*)AudioManager::getSingleton().m_Buffer,
  266. (ALsizei)buffer_size, (ALsizei)m_VorbisInfo->rate);
  267. alSourceQueueBuffers(m_Source, 1, &buffer_id);
  268. }
  269. // finished reading stream
  270. else
  271. {
  272. m_StreamFinished = true;
  273. break;
  274. }
  275. }
  276. }
  277. // manage source state
  278. {
  279. int processed;
  280. alGetSourcei(m_Source, AL_BUFFERS_PROCESSED, &processed);
  281. int queued;
  282. alGetSourcei(m_Source, AL_BUFFERS_QUEUED, &queued);
  283. if(m_StreamFinished && processed == queued)
  284. {
  285. Stop();
  286. }
  287. else
  288. {
  289. ALenum source_state;
  290. alGetSourcei(m_Source, AL_SOURCE_STATE, &source_state);
  291. if(source_state == AL_STOPPED)
  292. {
  293. alSourcePlay(m_Source);
  294. }
  295. }
  296. }
  297. }
  298. ALsizei
  299. AudioManager::Player::FillBuffer()
  300. {
  301. ALsizei read = 0;
  302. if(m_StreamFinished)
  303. {
  304. return read;
  305. }
  306. char *&buffer = AudioManager::getSingleton().m_Buffer;
  307. bool finished = false;
  308. do
  309. {
  310. long result = ov_read(&m_VorbisFile, buffer + read,
  311. m_ChannelBufferSize - read, 0, 2, 1,
  312. &m_VorbisSection);
  313. switch(result)
  314. {
  315. // error
  316. case OV_HOLE:
  317. case OV_EBADLINK:
  318. case OV_EINVAL:
  319. {
  320. finished = true;
  321. }
  322. break;
  323. // end of stream
  324. case 0:
  325. {
  326. // if there isn't loop point or can't seek
  327. if(m_Loop < 0.0f || ov_time_seek(&m_VorbisFile, m_Loop))
  328. {
  329. finished = true;
  330. }
  331. }
  332. break;
  333. // readed "result" bytes
  334. default:
  335. {
  336. read += result;
  337. if(read == m_ChannelBufferSize)
  338. {
  339. finished = true;
  340. }
  341. }
  342. }
  343. }
  344. while(finished == false);
  345. return read;
  346. }
  347. float
  348. AudioManager::Player::GetPosition()
  349. {
  350. boost::recursive_mutex::scoped_lock lock(*m_UpdateMutex);
  351. int play_offset;
  352. alGetSourcei(m_Source, AL_SAMPLE_OFFSET, &play_offset);
  353. return (ov_pcm_tell(&m_VorbisFile) -
  354. (m_ChannelBufferNumber * m_ChannelBufferSize /
  355. m_VorbisInfo->channels / sizeof(int16_t) -
  356. play_offset)) * 1000 / m_VorbisInfo->rate;
  357. }