SoundUtil.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /***************************************************************************
  2. SoundUtil.cpp - description
  3. -------------------
  4. begin : Thu Jan 11 2001
  5. copyright : (C) 2001 by Henrik Enqvist
  6. email : henqvist@excite.com
  7. ***************************************************************************/
  8. #include "Private.h"
  9. #include "SoundUtil.h"
  10. #include "EMath.h"
  11. #include "Config.h"
  12. #include <iostream>
  13. SoundUtil* SoundUtil::p_SoundUtil = NULL;
  14. SoundUtil::SoundUtil() {
  15. m_bInited = false;
  16. m_iLoopingMusic = -1;
  17. }
  18. SoundUtil::~SoundUtil() {
  19. p_SoundUtil = NULL;
  20. }
  21. SoundUtil* SoundUtil::getInstance() {
  22. if (p_SoundUtil == NULL) {
  23. p_SoundUtil = new SoundUtil();
  24. }
  25. return p_SoundUtil;
  26. }
  27. int SoundUtil::initSound()
  28. {
  29. #if EM_USE_SDL
  30. int audio_rate = EM_AUDIO_FREQ;
  31. Uint16 audio_format = EM_AUDIO_FORMAT;
  32. int audio_channels = EM_AUDIO_CHANNELS;
  33. if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
  34. {
  35. cerr << "Couldn't init SDL aduio: " << SDL_GetError() << endl;
  36. m_bInited = false;
  37. return -1;
  38. }
  39. if (Mix_OpenAudio(audio_rate, audio_format, audio_channels, 1024) < 0)
  40. {
  41. cerr << "Couldn't open audio mixer: " << SDL_GetError() << endl;
  42. m_bInited = false;
  43. return -1;
  44. }
  45. Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
  46. cerr << "Opened audio at " << audio_rate << " Hz "
  47. << (audio_format & 0xFF) << " bit "
  48. << (audio_channels > 1 ? "stereo" : "mono") << endl << endl;
  49. m_bInited = true;
  50. return 0;
  51. #endif
  52. #if EM_USE_ALLEGRO
  53. if (install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL) < 0) {
  54. cerr << "Couldn't open audio: " << allegro_error << endl;
  55. return -1;
  56. }
  57. cerr << "Opened audio" << endl << endl;
  58. m_bInited = true;
  59. return 0;
  60. #endif
  61. }
  62. void SoundUtil::stopSound() {
  63. cerr << "Stopping sound...";
  64. if (!m_bInited) return;
  65. // clean samples and music otherwise we will get segfaults cause stoping sounds
  66. // de-allocates waves and midis, or does it de-allocate
  67. // vector<EmSample*>::iterator sampleiter = m_vEmSample.begin();
  68. // vector<EmSample*>::iterator sampleend = m_vEmSample.end();
  69. // for (; sampleiter != sampleend; ++sampleiter) {
  70. // (*sampleiter) = NULL;
  71. // }
  72. // vector<EmMusic*>::iterator musiciter = m_vEmMusic.begin();
  73. // vector<EmMusic*>::iterator musicend = m_vEmMusic.end();
  74. // for (; musiciter != musicend; ++musiciter) {
  75. // (*musiciter) = NULL;
  76. // }
  77. #if EM_USE_SDL
  78. Mix_CloseAudio();
  79. SDL_QuitSubSystem(SDL_INIT_AUDIO);
  80. #endif
  81. cerr << "ok." << endl;
  82. m_bInited = false;
  83. m_iLoopingMusic = -1;
  84. }
  85. void SoundUtil::applyConfigVolume()
  86. {
  87. // If no volume for sound or music then stop sound module
  88. if (Config::getInstance()->getSound() == 0 &&
  89. Config::getInstance()->getMusic() == 0)
  90. {
  91. if (m_bInited)
  92. this->stopSound();
  93. }
  94. // We have some sound or music volume, start sound module
  95. else
  96. {
  97. if (!m_bInited)
  98. {
  99. if (this->initSound() == 0)
  100. {
  101. if (Config::getInstance()->getMusic() == 0)
  102. {
  103. #if EM_USE_SDL
  104. Mix_HaltMusic();
  105. m_iLoopingMusic = -1;
  106. #endif
  107. }
  108. #if EM_USE_SDL
  109. Mix_Volume(-1, Config::getInstance()->getSound()*8);
  110. Mix_VolumeMusic(Config::getInstance()->getMusic()*8);
  111. #endif
  112. }
  113. else
  114. {
  115. Config::getInstance()->setSound(0);
  116. Config::getInstance()->setMusic(0);
  117. cerr << "******************************************" << endl;
  118. cerr << "Error opening audio device, check that" << endl;
  119. cerr << "no other application is occupying audio" << endl;
  120. cerr << "resources. Try to kill artsd and/or esd." << endl;
  121. cerr << "******************************************" << endl;
  122. }
  123. }
  124. }
  125. }
  126. int SoundUtil::loadSample(const char* filename)
  127. {
  128. // NOTE! Load samples even if the volume is off, if we change the volume
  129. // settings we don't have to reload the table
  130. // TODO: If volume off then the samples are initialized to NULL...
  131. // The samples must be re-loaded anyway...!
  132. // Find a way to solve this...
  133. // look if the sound is already loaded
  134. if (m_hEmSample.find(string(filename)) != m_hEmSample.end())
  135. {
  136. EM_COUT("SoundUtil::loadSample Found sample " << filename
  137. << " in cache", 0);
  138. map<string, int>::iterator element = m_hEmSample.find(string(filename));
  139. return (*element).second;
  140. }
  141. #if EM_USE_SDL
  142. Mix_Chunk * wave = Mix_LoadWAV(filename);
  143. // Error message if we can't load wave file
  144. if (wave == NULL && m_bInited)
  145. cerr << "ERROR Mix_LoadWAV: " << Mix_GetError() << endl;
  146. #endif
  147. #if EM_USE_ALLEGRO
  148. SAMPLE* wave = load_sample(filename);
  149. #endif
  150. m_vEmSample.push_back(wave);
  151. int sound = m_vEmSample.size()-1;
  152. m_hEmSample.insert(pair<string, int>(string(filename), sound));
  153. m_hSoundName.insert(pair<int, string>(sound, string(filename)));
  154. if (wave == NULL && m_bInited)
  155. {
  156. cerr << "SoundUtil::loadSample Unable to load " << filename
  157. << " inserting a NULL wave" << endl;
  158. }
  159. return sound;
  160. }
  161. const char * SoundUtil::getSoundName(int sound) {
  162. map<int, string>::iterator element = m_hSoundName.find(sound);
  163. if (element != m_hSoundName.end()) {
  164. return (*element).second.c_str();
  165. }
  166. cerr << "SoundUtil::getSoundName could not find sound name" << endl;
  167. return NULL;
  168. }
  169. const char * SoundUtil::getMusicName(int music) {
  170. map<int, string>::iterator element = m_hMusicName.find(music);
  171. if (element != m_hMusicName.end()) {
  172. return (*element).second.c_str();
  173. }
  174. cerr << "SoundUtil::getMusicName could not find music name" << endl;
  175. return NULL;
  176. }
  177. int SoundUtil::loadMusic(const char * filename) {
  178. //if (!m_bInited) return -1;
  179. // look if the sound is already loaded
  180. if (m_hEmMusic.find(string(filename)) != m_hEmMusic.end()) {
  181. EM_COUT("Found music " << filename << " in cache", 0);
  182. map<string, int>::iterator element = m_hEmMusic.find(string(filename));
  183. return (*element).second;
  184. }
  185. #if EM_USE_SDL
  186. Mix_Music * music = Mix_LoadMUS(filename);
  187. #endif
  188. #if EM_USE_ALLEGRO
  189. MIDI * music = load_midi(filename);
  190. #endif
  191. m_vEmMusic.push_back(music);
  192. int sound = m_vEmMusic.size()-1;
  193. m_hEmMusic.insert(pair<string, int>(string(filename), sound));
  194. m_hMusicName.insert(pair<int, string>(sound, string(filename)));
  195. if (music == NULL) {
  196. cerr << "SoundUtil::loadMusic Unable to load " << filename << " inserting a NULL stream" << endl;
  197. }
  198. return sound;
  199. }
  200. void SoundUtil::playSample(int sound, bool loop) {
  201. if (!m_bInited) return;
  202. if (Config::getInstance()->getSound() == 0) return;
  203. if (sound < 0 || sound >= (signed)m_vEmSample.size()) return;
  204. EM_COUT("SoundUtil::playSample " << sound, 1);
  205. #if EM_USE_SDL
  206. if (m_vEmSample[sound] != NULL) {
  207. Mix_PlayChannel(-1, m_vEmSample[sound], (loop ? -1 : 0));
  208. }
  209. #endif // EM_USE_SDL
  210. #if EM_USE_ALLEGRO
  211. if (m_vEmSample[sound] != NULL) {
  212. play_sample(m_vEmSample[sound], 255, 127, 1000, (int)loop);
  213. }
  214. #endif
  215. }
  216. void SoundUtil::playMusic(int music, bool loop) {
  217. if (!m_bInited) return;
  218. if (Config::getInstance()->getMusic() == 0) return;
  219. if (music < 0 || music >= (signed)m_vEmMusic.size()) return;
  220. if (loop && m_iLoopingMusic == music) return;
  221. m_iLoopingMusic = music;
  222. EM_COUT("SoundUtil::playMusic " << music, 1);
  223. #if EM_USE_SDL
  224. Mix_HaltMusic();
  225. if (m_vEmMusic[music] != NULL) {
  226. Mix_PlayMusic(m_vEmMusic[music], (loop ? -1 : 0));
  227. }
  228. #endif
  229. #if EM_USE_ALLEGRO
  230. if (m_vEmMusic[music] != NULL) {
  231. play_midi(m_vEmMusic[music], (int)loop);
  232. }
  233. #endif
  234. }
  235. void SoundUtil::stopMusic() {
  236. if (!m_bInited) return;
  237. #if EM_USE_SDL
  238. Mix_HaltMusic();
  239. m_iLoopingMusic = -1;
  240. #endif
  241. }
  242. void SoundUtil::pauseMusic() {
  243. if (!m_bInited) return;
  244. #if EM_USE_SDL
  245. Mix_PauseMusic();
  246. #endif
  247. }
  248. void SoundUtil::resumeMusic() {
  249. if (!m_bInited) return;
  250. #if EM_USE_SDL
  251. Mix_ResumeMusic();
  252. #endif
  253. }