|
|
@@ -7,109 +7,224 @@
|
|
|
namespace BansheeEngine
|
|
|
{
|
|
|
FMODAudioSource::FMODAudioSource()
|
|
|
+ : mChannel(nullptr), mStreamingSound(nullptr), mTime(0.0f), mGloballyPaused(false)
|
|
|
+ , mGlobalUnpauseState(AudioSourceState::Stopped)
|
|
|
{
|
|
|
gFMODAudio()._registerSource(this);
|
|
|
- // TODO
|
|
|
}
|
|
|
|
|
|
FMODAudioSource::~FMODAudioSource()
|
|
|
{
|
|
|
gFMODAudio()._unregisterSource(this);
|
|
|
- // TODO
|
|
|
+
|
|
|
+ if (mStreamingSound != nullptr)
|
|
|
+ mStreamingSound->release();
|
|
|
+
|
|
|
+ if (mChannel != nullptr)
|
|
|
+ mChannel->stop();
|
|
|
}
|
|
|
|
|
|
void FMODAudioSource::setClip(const HAudioClip& clip)
|
|
|
{
|
|
|
- AudioSource::setClip(clip);
|
|
|
+ stop();
|
|
|
|
|
|
- // TODO
|
|
|
+ AudioSource::setClip(clip);
|
|
|
}
|
|
|
|
|
|
void FMODAudioSource::setPosition(const Vector3& position)
|
|
|
{
|
|
|
AudioSource::setPosition(position);
|
|
|
|
|
|
- // TODO
|
|
|
+ if (mChannel != nullptr)
|
|
|
+ {
|
|
|
+ FMOD_VECTOR fmodPosition = { position.x, position.y, position.z };
|
|
|
+ mChannel->set3DAttributes(&fmodPosition, nullptr);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void FMODAudioSource::setVelocity(const Vector3& velocity)
|
|
|
{
|
|
|
AudioSource::setVelocity(velocity);
|
|
|
|
|
|
- // TODO
|
|
|
+ if (mChannel != nullptr)
|
|
|
+ {
|
|
|
+ FMOD_VECTOR fmodVelocity = { velocity.x, velocity.y, velocity.z };
|
|
|
+ mChannel->set3DAttributes(nullptr, &fmodVelocity);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void FMODAudioSource::setVolume(float volume)
|
|
|
{
|
|
|
AudioSource::setVolume(volume);
|
|
|
|
|
|
- // TODO
|
|
|
+ if (mChannel != nullptr)
|
|
|
+ mChannel->setVolume(mVolume);
|
|
|
}
|
|
|
|
|
|
void FMODAudioSource::setPitch(float pitch)
|
|
|
{
|
|
|
AudioSource::setPitch(pitch);
|
|
|
|
|
|
- // TODO
|
|
|
+ if (mChannel != nullptr)
|
|
|
+ mChannel->setPitch(mVolume);
|
|
|
}
|
|
|
|
|
|
void FMODAudioSource::setIsLooping(bool loop)
|
|
|
{
|
|
|
AudioSource::setIsLooping(loop);
|
|
|
|
|
|
- // TODO
|
|
|
+ if (mChannel != nullptr)
|
|
|
+ mChannel->setMode(loop ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
|
|
|
}
|
|
|
|
|
|
- void FMODAudioSource::setPriority(UINT32 priority)
|
|
|
+ void FMODAudioSource::setPriority(INT32 priority)
|
|
|
{
|
|
|
AudioSource::setPriority(priority);
|
|
|
|
|
|
- // TODO
|
|
|
+ if (mChannel != nullptr)
|
|
|
+ mChannel->setPriority(priority);
|
|
|
}
|
|
|
|
|
|
- void FMODAudioSource::setMinDistance(float distance)
|
|
|
+ void FMODAudioSource::play()
|
|
|
{
|
|
|
- AudioSource::setMinDistance(distance);
|
|
|
-
|
|
|
- // TODO
|
|
|
+ mGlobalUnpauseState = AudioSourceState::Playing;
|
|
|
+
|
|
|
+ if (mGloballyPaused)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (!mAudioClip.isLoaded())
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (mChannel == nullptr)
|
|
|
+ {
|
|
|
+ assert(mStreamingSound == nullptr);
|
|
|
+
|
|
|
+ FMOD::System* fmod = gFMODAudio()._getFMOD();
|
|
|
+
|
|
|
+ FMODAudioClip* fmodClip = static_cast<FMODAudioClip*>(mAudioClip.get());
|
|
|
+ FMOD::Sound* sound;
|
|
|
+ if(mAudioClip->getReadMode() == AudioReadMode::Stream)
|
|
|
+ {
|
|
|
+ mStreamingSound = fmodClip->createStreamingSound();
|
|
|
+ sound = mStreamingSound;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ sound = fmodClip->getSound();
|
|
|
+ }
|
|
|
+
|
|
|
+ if(fmod->playSound(sound, nullptr, true, &mChannel) != FMOD_OK)
|
|
|
+ {
|
|
|
+ LOGERR("Failed playing sound.");
|
|
|
+
|
|
|
+ if (mStreamingSound != nullptr)
|
|
|
+ {
|
|
|
+ mStreamingSound->release();
|
|
|
+ mStreamingSound = nullptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ mChannel->setUserData(this);
|
|
|
+ mChannel->setVolume(mVolume);
|
|
|
+ mChannel->setPitch(mVolume);
|
|
|
+ mChannel->setMode(mLoop ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
|
|
|
+ mChannel->setPriority(mPriority);
|
|
|
+ mChannel->setPosition((UINT32)(mTime * 1000.0f), FMOD_TIMEUNIT_MS);
|
|
|
+
|
|
|
+ FMOD_VECTOR fmodPosition = { mPosition.x, mPosition.y, mPosition.z };
|
|
|
+ FMOD_VECTOR fmodVelocity = { mVelocity.x, mVelocity.y, mVelocity.z };
|
|
|
+ mChannel->set3DAttributes(&fmodPosition, &fmodVelocity);
|
|
|
+ }
|
|
|
+
|
|
|
+ mChannel->setPaused(false);
|
|
|
}
|
|
|
|
|
|
- void FMODAudioSource::setAttenuation(float attenuation)
|
|
|
+ void FMODAudioSource::pause()
|
|
|
{
|
|
|
- AudioSource::setAttenuation(attenuation);
|
|
|
+ mGlobalUnpauseState = AudioSourceState::Paused;
|
|
|
|
|
|
- // TODO
|
|
|
+ if (mChannel != nullptr)
|
|
|
+ mChannel->setPaused(true);
|
|
|
}
|
|
|
|
|
|
- void FMODAudioSource::play()
|
|
|
+ void FMODAudioSource::stop()
|
|
|
{
|
|
|
- AudioSource::play();
|
|
|
+ mGlobalUnpauseState = AudioSourceState::Stopped;
|
|
|
|
|
|
- // TODO
|
|
|
+ if (mChannel != nullptr)
|
|
|
+ {
|
|
|
+ mChannel->stop();
|
|
|
+ mChannel = nullptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(mStreamingSound != nullptr)
|
|
|
+ {
|
|
|
+ mStreamingSound->release();
|
|
|
+ mStreamingSound = nullptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ mTime = 0.0f;
|
|
|
}
|
|
|
|
|
|
- void FMODAudioSource::pause()
|
|
|
+ void FMODAudioSource::setGlobalPause(bool doPause)
|
|
|
{
|
|
|
- AudioSource::pause();
|
|
|
+ if (mGloballyPaused == doPause)
|
|
|
+ return;
|
|
|
|
|
|
- // TODO
|
|
|
+ mGloballyPaused = doPause;
|
|
|
+
|
|
|
+ if(doPause)
|
|
|
+ {
|
|
|
+ mGlobalUnpauseState = getState();
|
|
|
+
|
|
|
+ if (getState() == AudioSourceState::Playing)
|
|
|
+ pause();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (mGlobalUnpauseState == AudioSourceState::Playing)
|
|
|
+ play();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- void FMODAudioSource::stop()
|
|
|
+ AudioSourceState FMODAudioSource::getState() const
|
|
|
{
|
|
|
- AudioSource::stop();
|
|
|
+ if(mChannel == nullptr)
|
|
|
+ return AudioSourceState::Stopped;
|
|
|
|
|
|
- // TODO
|
|
|
+ bool isPlaying = false;
|
|
|
+ mChannel->isPlaying(&isPlaying);
|
|
|
+
|
|
|
+ if (isPlaying)
|
|
|
+ return AudioSourceState::Playing;
|
|
|
+
|
|
|
+ bool isPaused = false;
|
|
|
+ mChannel->getPaused(&isPaused);
|
|
|
+ if (isPaused)
|
|
|
+ return AudioSourceState::Paused;
|
|
|
+
|
|
|
+ return AudioSourceState::Stopped;
|
|
|
}
|
|
|
|
|
|
void FMODAudioSource::setTime(float time)
|
|
|
{
|
|
|
- // TODO
|
|
|
+ if (mChannel != nullptr)
|
|
|
+ mChannel->setPosition((UINT32)(time * 1000.0f), FMOD_TIMEUNIT_MS);
|
|
|
+ else
|
|
|
+ mTime = time;
|
|
|
}
|
|
|
|
|
|
float FMODAudioSource::getTime() const
|
|
|
{
|
|
|
- // TODO
|
|
|
+ if(mChannel != nullptr)
|
|
|
+ {
|
|
|
+ UINT32 position = 0;
|
|
|
+ mChannel->getPosition(&position, FMOD_TIMEUNIT_MS);
|
|
|
+
|
|
|
+ return position / 1000.0f;
|
|
|
+ }
|
|
|
|
|
|
return 0.0f;
|
|
|
}
|