BsFMODAudioSource.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsFMODAudioSource.h"
  4. #include "BsFMODAudio.h"
  5. #include "BsFMODAudioClip.h"
  6. namespace bs
  7. {
  8. FMODAudioSource::FMODAudioSource()
  9. : mChannel(nullptr), mStreamingSound(nullptr), mTime(0.0f), mGloballyPaused(false)
  10. , mGlobalUnpauseState(AudioSourceState::Stopped)
  11. {
  12. gFMODAudio()._registerSource(this);
  13. }
  14. FMODAudioSource::~FMODAudioSource()
  15. {
  16. gFMODAudio()._unregisterSource(this);
  17. if (mStreamingSound != nullptr)
  18. FMODAudioClip::releaseStreamingSound(mStreamingSound);
  19. if (mChannel != nullptr)
  20. mChannel->stop();
  21. }
  22. void FMODAudioSource::setClip(const HAudioClip& clip)
  23. {
  24. stop();
  25. AudioSource::setClip(clip);
  26. }
  27. void FMODAudioSource::setTransform(const Transform& transform)
  28. {
  29. AudioSource::setTransform(transform);
  30. if(mChannel != nullptr)
  31. {
  32. Vector3 position = transform.getPosition();
  33. FMOD_VECTOR fmodPosition = { position.x, position.y, position.z };
  34. mChannel->set3DAttributes(&fmodPosition, nullptr);
  35. }
  36. }
  37. void FMODAudioSource::setVelocity(const Vector3& velocity)
  38. {
  39. AudioSource::setVelocity(velocity);
  40. if (mChannel != nullptr)
  41. {
  42. FMOD_VECTOR fmodVelocity = { velocity.x, velocity.y, velocity.z };
  43. mChannel->set3DAttributes(nullptr, &fmodVelocity);
  44. }
  45. }
  46. void FMODAudioSource::setVolume(float volume)
  47. {
  48. AudioSource::setVolume(volume);
  49. if (mChannel != nullptr)
  50. mChannel->setVolume(mVolume);
  51. }
  52. void FMODAudioSource::setPitch(float pitch)
  53. {
  54. AudioSource::setPitch(pitch);
  55. if (mChannel != nullptr)
  56. mChannel->setPitch(mPitch);
  57. }
  58. void FMODAudioSource::setIsLooping(bool loop)
  59. {
  60. AudioSource::setIsLooping(loop);
  61. if (mChannel != nullptr)
  62. mChannel->setMode(loop ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
  63. }
  64. void FMODAudioSource::setPriority(INT32 priority)
  65. {
  66. AudioSource::setPriority(priority);
  67. if (mChannel != nullptr)
  68. mChannel->setPriority(priority);
  69. }
  70. void FMODAudioSource::play()
  71. {
  72. mGlobalUnpauseState = AudioSourceState::Playing;
  73. if (mGloballyPaused)
  74. return;
  75. if (!mAudioClip.isLoaded())
  76. return;
  77. if (mChannel == nullptr)
  78. {
  79. assert(mStreamingSound == nullptr);
  80. FMOD::System* fmod = gFMODAudio()._getFMOD();
  81. FMODAudioClip* fmodClip = static_cast<FMODAudioClip*>(mAudioClip.get());
  82. FMOD::Sound* sound;
  83. if(fmodClip->requiresStreaming())
  84. {
  85. mStreamingSound = fmodClip->createStreamingSound();
  86. sound = mStreamingSound;
  87. }
  88. else
  89. {
  90. sound = fmodClip->getSound();
  91. }
  92. if(fmod->playSound(sound, nullptr, true, &mChannel) != FMOD_OK)
  93. {
  94. LOGERR("Failed playing sound.");
  95. if (mStreamingSound != nullptr)
  96. {
  97. FMODAudioClip::releaseStreamingSound(mStreamingSound);
  98. mStreamingSound = nullptr;
  99. }
  100. return;
  101. }
  102. mChannel->setUserData(this);
  103. mChannel->setVolume(mVolume);
  104. mChannel->setPitch(mVolume);
  105. mChannel->setMode(mLoop ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
  106. mChannel->setPriority(mPriority);
  107. mChannel->setPosition((UINT32)(mTime * 1000.0f), FMOD_TIMEUNIT_MS);
  108. Vector3 position = getTransform().getPosition();
  109. FMOD_VECTOR fmodPosition = { position.x, position.y, position.z };
  110. FMOD_VECTOR fmodVelocity = { mVelocity.x, mVelocity.y, mVelocity.z };
  111. mChannel->set3DAttributes(&fmodPosition, &fmodVelocity);
  112. }
  113. mChannel->setPaused(false);
  114. }
  115. void FMODAudioSource::pause()
  116. {
  117. mGlobalUnpauseState = AudioSourceState::Paused;
  118. if (mChannel != nullptr)
  119. mChannel->setPaused(true);
  120. }
  121. void FMODAudioSource::stop()
  122. {
  123. mGlobalUnpauseState = AudioSourceState::Stopped;
  124. if (mChannel != nullptr)
  125. {
  126. mChannel->stop();
  127. mChannel = nullptr;
  128. }
  129. if(mStreamingSound != nullptr)
  130. {
  131. FMODAudioClip::releaseStreamingSound(mStreamingSound);
  132. mStreamingSound = nullptr;
  133. }
  134. mTime = 0.0f;
  135. }
  136. void FMODAudioSource::setGlobalPause(bool doPause)
  137. {
  138. if (mGloballyPaused == doPause)
  139. return;
  140. mGloballyPaused = doPause;
  141. if(doPause)
  142. {
  143. AudioSourceState currentState = getState();
  144. if (getState() == AudioSourceState::Playing)
  145. pause();
  146. mGlobalUnpauseState = currentState;
  147. }
  148. else
  149. {
  150. if (mGlobalUnpauseState == AudioSourceState::Playing)
  151. play();
  152. }
  153. }
  154. AudioSourceState FMODAudioSource::getState() const
  155. {
  156. if(mChannel == nullptr)
  157. return AudioSourceState::Stopped;
  158. bool isPlaying = false;
  159. mChannel->isPlaying(&isPlaying);
  160. if (isPlaying)
  161. return AudioSourceState::Playing;
  162. bool isPaused = false;
  163. mChannel->getPaused(&isPaused);
  164. if (isPaused)
  165. return AudioSourceState::Paused;
  166. return AudioSourceState::Stopped;
  167. }
  168. void FMODAudioSource::setTime(float time)
  169. {
  170. if (mChannel != nullptr)
  171. mChannel->setPosition((UINT32)(time * 1000.0f), FMOD_TIMEUNIT_MS);
  172. else
  173. mTime = time;
  174. }
  175. float FMODAudioSource::getTime() const
  176. {
  177. if(mChannel != nullptr)
  178. {
  179. UINT32 position = 0;
  180. mChannel->getPosition(&position, FMOD_TIMEUNIT_MS);
  181. return position / 1000.0f;
  182. }
  183. return 0.0f;
  184. }
  185. void FMODAudioSource::onClipChanged()
  186. {
  187. AudioSourceState state = getState();
  188. float savedTime = getTime();
  189. stop();
  190. setTime(savedTime);
  191. if (state != AudioSourceState::Stopped)
  192. play();
  193. if (state == AudioSourceState::Paused)
  194. pause();
  195. }
  196. }