From f5f34e08245883ff0b0061ee9cd618ce7740200e Mon Sep 17 00:00:00 2001 From: windpeeskillet <1062133853@qq.com> Date: Fri, 22 Nov 2019 13:52:53 +0800 Subject: [PATCH] AudioSource --- Mx/Component/AudioSource/MxAudioSource.cpp | 221 +++++++++--------- Mx/Component/AudioSource/MxAudioSource.h | 247 ++++++--------------- 2 files changed, 167 insertions(+), 301 deletions(-) diff --git a/Mx/Component/AudioSource/MxAudioSource.cpp b/Mx/Component/AudioSource/MxAudioSource.cpp index 74b2cb5..26db178 100644 --- a/Mx/Component/AudioSource/MxAudioSource.cpp +++ b/Mx/Component/AudioSource/MxAudioSource.cpp @@ -7,154 +7,143 @@ namespace Mix { MX_IMPLEMENT_RTTI(AudioSource, Component); - void AudioSource::dopplerLevel(const float _dopplerLevel) { - if (mChannel) { - mChannel->set3DDopplerLevel(_dopplerLevel); - mChannel->get3DDopplerLevel(&mDopplerLevel); + + void AudioSource::setMute(const bool _mute) { + if(mChannel) + mChannel->setMute(_mute); + else + mChannelParam.mute = _mute; } - else { - mDopplerLevel = _dopplerLevel; - } - } - bool AudioSource::isPlaying() const { - bool is = false; + bool AudioSource::getMute() const { if (mChannel) - mChannel->isPlaying(&is); - return is; + mChannel->getMute(&mChannelParam.mute); + return mChannelParam.mute; } - bool AudioSource::isVirtual() const { - bool iv = true; + bool AudioSource::getPaused() const { if (mChannel) - mChannel->isVirtual(&iv); - return iv; + mChannel->getPaused(&mChannelParam.paused); + return mChannelParam.paused; } - void AudioSource::loop(const bool _loop) { - if (mChannel) { - mChannel->setMode(_loop ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF); - FMOD_MODE mode; - mChannel->getMode(&mode); - mLoop = mode & FMOD_LOOP_NORMAL; - } - else { - mLoop = _loop; - } + void AudioSource::setPaused(const bool _paused) { + if (mChannel) + mChannel->setPaused(_paused); + else + mChannelParam.paused = _paused; } - void AudioSource::mute(const bool _mute) { - if (mChannel) { - mChannel->setMute(_mute); - mChannel->getMute(&mMute); - } - else { - mMute = _mute; - } + float AudioSource::getVolume() const { + if (mChannel) + mChannel->getVolume(&mChannelParam.volume); + return mChannelParam.volume; } - void AudioSource::pan(const float _pan) { - if (mChannel) { - mChannel->setPan(_pan); - } - else { - mPan = _pan; - } + void AudioSource::setVolume(const float _volume) { + if (mChannel) + mChannel->setVolume(_volume); + else + mChannelParam.volume = _volume; } - void AudioSource::pitch(const float _pitch) { - if (mChannel) { - mChannel->setPitch(_pitch); - mChannel->getPitch(&mPitch); - } - else { - mPitch = _pitch; - } + bool AudioSource::getVolumeRamp() const { + if (mChannel) + mChannel->getVolumeRamp(&mChannelParam.volumRamp); + return mChannelParam.volumRamp; } - void AudioSource::priority(const int _priority) { - if (mChannel) { - mChannel->setPriority(_priority); - mChannel->getPriority(&mPriority); - } - else { - mPriority = _priority; - } + void AudioSource::setVolumeRamp(const bool _volumeRamp) { + if (mChannel) + mChannel->setVolumeRamp(_volumeRamp); + else + mChannelParam.volumRamp = _volumeRamp; } - void AudioSource::volume(const float _volume) { - if (mChannel) { - mChannel->setVolume(_volume); - mChannel->getVolume(&mVolume); - } - else { - mVolume = _volume; - } + float AudioSource::getPitch() const { + if (mChannel) + mChannel->getPitch(&mChannelParam.pitch); + return mChannelParam.pitch; } - void AudioSource::play() { - if (!mClip || mClip->loadState() != Audio::LoadState::LOADED) - return; - stop(); - FMOD::System* core = nullptr; - mClip->mSound->getSystemObject(&core); - core->playSound(mClip->mSound, nullptr, false, &mChannel); - initChannelParameters(); + void AudioSource::setPitch(const float _pitch) { + if (mChannel) + mChannel->setPitch(_pitch); + else + mChannelParam.pitch = _pitch; } - void AudioSource::start() { - if (!mGameObject) - throw IndependentComponentError(getTypeName()); - - play(); - if (!mPlayOnAwake) - pause(); + Vector2f AudioSource::get3DMinMaxDistance() const { + if (mChannel) + mChannel->get3DMinMaxDistance(&mChannelParam.distance.x, &mChannelParam.distance.y); + return mChannelParam.distance; } - void AudioSource::fixedUpdate() { - if (!mChannel || !mUseFixedUpdate) return; - - if (const auto& rb = mGameObject->getComponent()) { - const auto& pos = rb->get().getCenterOfMassPosition(); - const auto& vel = rb->get().getLinearVelocity(); - updatePosAndVel({ pos.x(), pos.y(), pos.z() }, { vel.x(), vel.y(), vel.z() }); - } - else { - auto pos = mGameObject->transform().getPosition(); - auto vel = (pos - mLastPos) / Time::FixedDeltaTime(); - updatePosAndVel(pos, vel); - } + void AudioSource::set3DMinMaxDistance(const Vector2f& _distance) { + if (mChannel) + mChannel->set3DMinMaxDistance(_distance.x, _distance.y); + else + mChannelParam.distance = _distance; } - void AudioSource::lateUpdate() { - if (!mChannel || mUseFixedUpdate) return; + float AudioSource::get3DDopplerLevel() const { + if (mChannel) + mChannel->get3DDopplerLevel(&mChannelParam.level); + return mChannelParam.level; + } - auto pos = mGameObject->transform().getPosition(); - auto vel = (pos - mLastPos) / Time::DeltaTime(); - updatePosAndVel(pos, vel); + void AudioSource::set3DDopplerLevel(const float _level) { + if (mChannel) + mChannel->set3DDopplerLevel(_level); + else + mChannelParam.level = _level; } - void AudioSource::initChannelParameters() { - if (!mChannel) return; + float AudioSource::getFrequency() const { + if (mChannel) + mChannel->getFrequency(&mChannelParam.Frequency); + return mChannelParam.Frequency; + } - mLastPos = mGameObject->transform().getPosition(); - mUseFixedUpdate = mVelocityUpdateMode == Audio::VelocityUpdateMode::FIXED || - mVelocityUpdateMode == Audio::VelocityUpdateMode::AUTO && mGameObject->getComponent(); + void AudioSource::setFrequency(const float _frequency) { + if (mChannel) + mChannel->setFrequency(_frequency); + else + mChannelParam.Frequency = _frequency; + } - dopplerLevel(mDopplerLevel); - loop(mLoop); - mute(mMute); - pan(mPan); - pitch(mPitch); - priority(mPriority); - volume(mVolume); + int AudioSource::getPriority() const { + if (mChannel) + mChannel->getPriority(&mChannelParam.Priority); + return mChannelParam.Priority; } - void AudioSource::updatePosAndVel(const Vector3f& _pos, const Vector3f& _vel) { - auto glmVecToFmodVec = [](const Vector3f& _vec) { return FMOD_VECTOR{ _vec.x, _vec.y, _vec.z }; }; - auto fvPos = glmVecToFmodVec(_pos), - fvVel = glmVecToFmodVec(_vel); - mChannel->set3DAttributes(&fvPos, &fvVel); - mLastPos = _pos; + void AudioSource::setPriority(const int _priority) { + if (mChannel) + mChannel->setPriority(_priority); + else + mChannelParam.Priority = _priority; } + void import(FMOD::Channel* _Channel, FMODChannelParam _ChannelParam) { + _Channel->getMute(&_ChannelParam.mute); + _Channel->getPaused(&_ChannelParam.paused); + _Channel->getVolume(&_ChannelParam.volume); + _Channel->getVolumeRamp(&_ChannelParam.volumRamp); + _Channel->getPitch(&_ChannelParam.pitch); + _Channel->get3DMinMaxDistance(&_ChannelParam.distance.x, &_ChannelParam.distance.y); + _Channel->get3DLevel (&_ChannelParam.level); + _Channel->getFrequency (&_ChannelParam.Frequency); + _Channel->getPriority (&_ChannelParam.Priority); + } + void export(FMOD::Channel* _Channel, FMODChannelParam _ChannelParam) { + _Channel->setMute(_ChannelParam.mute); + _Channel->setPaused(_ChannelParam.paused); + _Channel->setVolume(_ChannelParam.volume); + _Channel->setVolumeRamp(_ChannelParam.volumRamp); + _Channel->setPitch(_ChannelParam.pitch); + _Channel->set3DMinMaxDistance(_ChannelParam.distance.x, _ChannelParam.distance.y); + _Channel->set3DLevel(_ChannelParam.level); + _Channel->setFrequency(_ChannelParam.Frequency); + _Channel->setPriority(_ChannelParam.Priority); + } } diff --git a/Mx/Component/AudioSource/MxAudioSource.h b/Mx/Component/AudioSource/MxAudioSource.h index 5737f3b..bfdeeea 100644 --- a/Mx/Component/AudioSource/MxAudioSource.h +++ b/Mx/Component/AudioSource/MxAudioSource.h @@ -4,201 +4,78 @@ #define MX_AUDIO_SOURCE_H_ #include "../Behaviour/MxBehaviour.h" -#include "../../Audio/MxAudioClip.h" + #include "../../Math/MxVector3.h" + namespace Mix { - // todo: add 3d roll off - class AudioSource final : public Behaviour { - MX_DECLARE_RTTI + struct FMODChannelParam { + bool mute; + bool paused; + float volume; + bool volumRamp; + float pitch; + Vector2f distance; + float level; + float Frequency; + int Priority; + + }; + + void import(FMOD::Channel* _Channel, FMODChannelParam _ChannelParam); + + void export(FMOD::Channel* _Channel, FMODChannelParam _ChannelParam); + + class AudioSource:public Component { + MX_DECLARE_RTTI; + public: - /** @note Default ctor is for RTTI. DO NOT use this ctor. */ - AudioSource() : mPlayOnAwake(true), - mVelocityUpdateMode(Audio::VelocityUpdateMode::AUTO), - mClip(nullptr), - mChannel(nullptr), - mLastPos(0), - mUseFixedUpdate(false), - mDopplerLevel(1.0f), - mLoop(false), - mMute(false), - mPan(0.0f), - mPitch(1.0f), - mPriority(128), - mVolume(1.0f) { - } - - AudioSource(AudioClip* _clip, - const bool _playOnAwake = true, - const Audio::VelocityUpdateMode _mode = Audio::VelocityUpdateMode::AUTO) - : mPlayOnAwake(_playOnAwake), - mVelocityUpdateMode(_mode), - mClip(_clip), - mChannel(nullptr), - mLastPos(0), - mUseFixedUpdate(false), - mDopplerLevel(1.0f), - mLoop(false), - mMute(false), - mPan(0.0f), - mPitch(1.0f), - mPriority(128), - mVolume(1.0f) { - } - -/** @note Copy constructed AudioSources are initially stopped. */ - AudioSource(const AudioSource& _other) : Behaviour(), - mPlayOnAwake(_other.mPlayOnAwake), - mVelocityUpdateMode(_other.mVelocityUpdateMode), - mClip(_other.mClip), - mChannel(nullptr), - mLastPos(_other.mLastPos), - mUseFixedUpdate(_other.mUseFixedUpdate), - mDopplerLevel(_other.mDopplerLevel), - mLoop(_other.mLoop), - mMute(_other.mMute), - mPan(_other.mPan), - mPitch(_other.mPitch), - mPriority(_other.mPriority), - mVolume(_other.mVolume) { - } - - ~AudioSource() { stop(); } - - // ----- Properties ----- - - const AudioClip* clip() const { return mClip; } - - void clip(AudioClip* _clip) { mClip = _clip; } - - float dopplerLevel() const { return mDopplerLevel; } - - /** - * @brief Determines how much doppler effect will be applied to this audio source. - * @param _dopplerLevel Doppler scale from 0.0 (none), to 1.0 (normal) to 5.0 (exaggerated), default = 1.0. - */ - void dopplerLevel(const float _dopplerLevel); - - bool isPlaying() const; - - bool isVirtual() const; - - bool loop() const { return mLoop; } - - void loop(const bool _loop); - - /** - * @note This is a getter. To mute the clip, consider @code AudioSource::mute(true) @endcode. - */ - bool mute() const { return mMute; } - - void mute(const bool _mute); - - /** - * @return The pan level set by user. This value may differ from the real one. - */ - float pan() const { return mPan; } - - /** - * @brief Pan level affects the left right balance of the sound. - * @param _pan Pan level, from -1.0 (left) to 1.0 (right), default = 0 (center). - * @note AKA Stereo Pan. - */ - void pan(const float _pan); - - float pitch() const { return mPitch; } - - /** - * @brief Scales existing frequency values by the pitch. - * @param _pitch Pitch value, 0.5 = half pitch, 2.0 = double pitch, etc. Default = 1.0. - */ - void pitch(const float _pitch); - - int priority() const { return mPriority; } - - /** - * @param _priority An integer between 0 and 255. 0 = highest priority, 255 = lowest priority. - * Default = 128. - */ - void priority(const int _priority); - - float volume() const { return mVolume; } - - /** - * @param _volume Linear volume level. Recommended be in range [0, 1]. - * @note Volume level can be below 0 to invert a signal and above 1 to amplify the signal. - * Increasing the signal level too far may cause audible distortion. - */ - void volume(const float _volume); - - // ----- Stream controlling ----- - - /** - * @note This function creates a new channel to play the clip. - * Nothing would happen if the clip is not ready. - * @see AudioSource::unpause() - */ - void play(); - - void pause() { - if (mChannel) - mChannel->setPaused(true); - } - - /** - * @brief Unpause the clip; no channel created. - */ - void unpause() { - if (mChannel) - mChannel->setPaused(false); - } - - void stop() { - if (mChannel) - mChannel->stop(); - } - - float time() const { - unsigned t = 0; - if (mChannel) - mChannel->getPosition(&t, FMOD_TIMEUNIT_MS); - return t / 1000.0f; - } + void setMute(const bool _mute); - /** - * @brief Set the playback position in seconds. - */ - void time(const float _time) { - if (mChannel) - mChannel->setPosition(static_cast(_time * 1000), FMOD_TIMEUNIT_MS); - } - - private: - bool mPlayOnAwake; - Audio::VelocityUpdateMode mVelocityUpdateMode; - - AudioClip* mClip; - FMOD::Channel* mChannel; + bool getMute() const; + + bool getPaused() const; + + void setPaused(const bool _paused); + + float getVolume() const; + + void setVolume(const float _volume); - Vector3f mLastPos; - bool mUseFixedUpdate; + bool getVolumeRamp() const; - // use FMOD::ChannelGroup instead? - float mDopplerLevel; - bool mLoop; - bool mMute; - float mPan; - float mPitch; - int mPriority; - float mVolume; + void setVolumeRamp(const bool _volumeRamp); - void start() override; - void fixedUpdate() override; - void lateUpdate() override; + //todo getAudibility - void initChannelParameters(); - void updatePosAndVel(const Vector3f& _pos, const Vector3f& _vel); + float getPitch() const; + void setPitch(const float _pitch); +; + + + Vector2f get3DMinMaxDistance() const; + + void set3DMinMaxDistance(const Vector2f& _distance); + //todo get3DCustomRolloff + + float get3DDopplerLevel() const; + + void set3DDopplerLevel(const float _level); + + + + float getFrequency() const; + + void setFrequency(const float _frequency); + + int getPriority() const; + + void setPriority(const int _priority); + + + FMOD::Channel* mChannel; + mutable FMODChannelParam mChannelParam; }; }