CSound.cpp
上传用户:liujun12jf
上传日期:2022-07-12
资源大小:638k
文件大小:4k
源码类别:

OpenGL

开发平台:

Visual C++

  1. #include "CSound.h"
  2. // brm!
  3. FMOD_VECTOR f2fmodv(float *pf)
  4. {
  5. FMOD_VECTOR fv;
  6. fv.x = pf[0];
  7. fv.y = pf[1];
  8. fv.z = pf[2];
  9. return fv;
  10. }
  11. void CSound::Frame()
  12. {
  13. UpdateListener();
  14. UpdatePositions();
  15. system->update();
  16. RemoveStoppedSounds();
  17. }
  18. void CSound::SetListener(float *pPos)
  19. {
  20. pListenerPos = pPos;
  21. }
  22. void CSound::UpdateListener()
  23. {
  24. if (!pListenerPos) return;
  25. FMOD_VECTOR fv = f2fmodv(pListenerPos);
  26. system->set3DListenerAttributes(0, &fv, 0, 0, 0);
  27. }
  28. void CSound::UpdateChannelPosition(FMOD::Channel *ch, float *pos)
  29. {
  30. if (!ch || !pos) return;
  31. FMOD_VECTOR fv = f2fmodv(pos);
  32. ch->set3DAttributes(&fv, 0);
  33. }
  34. void CSound::UpdatePositions()
  35. {
  36. vectorq<s_played*>::iterator i;
  37. for (i = vPlayed.begin() ; i != vPlayed.end() ; i++) 
  38. {
  39. if (!*i) continue;
  40. if (!(*i)->pPosition) continue;
  41. UpdateChannelPosition((*i)->pChannel, &(*i)->pPosition[0]);
  42. }
  43. }
  44. void CSound::RemoveStoppedSounds()
  45. {
  46. vectorq<s_played*>::iterator i;
  47. for (i = vPlayed.begin() ; i != vPlayed.end() ; i++) 
  48. {
  49. if (!*i) continue;
  50. bool playing, paused;
  51. (*i)->pChannel->isPlaying(&playing);
  52. paused = (*i)->bPaused;
  53. if (!playing && !paused) vPlayed.rm(i);
  54. }
  55. }
  56. bool CSound::AddSound(std::string name, std::string filename, int priority)
  57. {
  58. if (!name.length() || !filename.length()) return 0;
  59. if (FindSound(name)) return 0;
  60. s_sound *s = new s_sound;
  61. s->name = name;
  62. s->filename = filename;
  63. s->priority = priority;
  64. s->pSound = 0;
  65. vSounds.add(s);
  66. return 1;
  67. }
  68. bool CSound::LoadSound(s_sound *s)
  69. {
  70. int mode = 0;
  71. mode |= FMOD_3D;
  72. mode |= FMOD_HARDWARE;
  73. // mode |= FMOD_LOOP_NORMAL;
  74. result = system->createSound(s->filename.c_str(), mode, 0, &s->pSound);
  75. if (result != FMOD_OK)
  76. {
  77. errf("CSound::LoadSound - error creating sound from file", (char*)s->filename.c_str());
  78. return 0;
  79. }
  80. s->pSound->set3DMinMaxDistance(10, 1000);
  81. return 1;
  82. }
  83. void CSound::loadAndPlayLoop(std::string name)
  84. {
  85. s_sound *s = new s_sound;
  86. int mode = 0;
  87. mode |= FMOD_3D;
  88. mode |= FMOD_HARDWARE;
  89. mode |= FMOD_LOOP_NORMAL;
  90. result = system->createSound(name.c_str(), mode, 0, &s->pSound);
  91. if (result != FMOD_OK)
  92. {
  93. errf("CSound::LoadSound - error creating sound from file", (char*)s->filename.c_str());
  94. return;
  95. }
  96. s->pSound->set3DMinMaxDistance(50, 1000);
  97. system->playSound(FMOD_CHANNEL_FREE, s->pSound, 0, 0);
  98. }
  99. s_played *CSound::PlaySound(std::string name, float *pPos)
  100. {
  101. s_sound *s;
  102. s = FindSound(name);
  103. if (!s) return 0;
  104. if (!s->pSound) LoadSound(s);
  105. if (!s->pSound) return 0;
  106. s_played *ps = new s_played;
  107. if (pPos) ps->pPosition = pPos;
  108. else ps->pPosition = pListenerPos;
  109. system->playSound(FMOD_CHANNEL_FREE, s->pSound, 1, &ps->pChannel);
  110. UpdateChannelPosition(ps->pChannel, &ps->pPosition[0]);
  111. ps->pChannel->setPaused(0);
  112. ps->bPaused = 0;
  113. vPlayed.add(ps);
  114. return ps;
  115. }
  116. s_sound *CSound::FindSound(std::string name)
  117. {
  118. vectorq<s_sound*>::iterator i;
  119. for (i = vSounds.begin() ; i != vSounds.end() ; i++)
  120. {
  121. if (*i == 0) continue;
  122. if (! strcmp( name.c_str(), (*i)->name.c_str() ) ) return (*i);
  123. }
  124. return 0;
  125. }
  126. void CSound::SetPausedToAll(bool p)
  127. {
  128. vectorq<s_played*>::iterator i;
  129. for (i = vPlayed.begin() ; i != vPlayed.end() ; i++)
  130. {
  131. if (!*i) continue;
  132. (*i)->bPaused = p;
  133. (*i)->pChannel->setPaused(p);
  134. }
  135. }
  136. CSound::CSound()
  137. {
  138. }
  139. bool CSound::Init()
  140. {
  141. // Create the main system object.
  142. result = FMOD::System_Create(&system);
  143. CheckError();
  144. // Allow 100 software mixed voices to be audible at once.
  145. result = system->setSoftwareChannels(100);
  146. CheckError();
  147. // Require the soundcard to have at least 32 2D and 3D hardware voices
  148. // and clamp it to using 64 if it has more than this.
  149. // note: 3D sounds are set to zero, cos of my stupid onboard soundcard
  150. result = system->setHardwareChannels(32, 64, 0, 0);
  151. CheckError();
  152. // Initialize FMOD. (100 - # of virtual voices)
  153. result = system->init(100, FMOD_INIT_NORMAL, 0);
  154. CheckError();
  155. return true;
  156. }
  157. bool CSound::CheckError()
  158. {
  159. if (result != FMOD_OK)
  160. {
  161. errf("FMOD error!", FMOD_ErrorString(result));
  162. err(FMOD_ErrorString(result), "FMOD error!");
  163. exit(-1);
  164. }
  165. return 1;
  166. }
  167. void CSound::StopSound(s_played *p)
  168. {
  169. vPlayed.rm(p);
  170. }
  171. void CSound::KeepPosition(s_played *p)
  172. {
  173. s_played *ps;
  174. ps = *(vPlayed.Find(p));
  175. if (!ps) return;
  176. ps->pPosition = 0;
  177. }