From 3c4c0fab6687f96228aefc8ec8fbda9015a69d7f Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 8 Apr 2018 17:51:25 +0200 Subject: [PATCH] Audio: Make Music, Sound, SoundEmitter movable --- ChangeLog.md | 1 + include/Nazara/Audio/Music.hpp | 6 +- include/Nazara/Audio/Sound.hpp | 4 +- include/Nazara/Audio/SoundEmitter.hpp | 9 ++- src/Nazara/Audio/Music.cpp | 2 + src/Nazara/Audio/Sound.cpp | 17 +++++- src/Nazara/Audio/SoundEmitter.cpp | 83 ++++++++++++++++++++++++--- 7 files changed, 104 insertions(+), 18 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index ef4ee8c35..4e02e78df 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -81,6 +81,7 @@ Nazara Engine: - Fixed IPv6 addresses not being correctly encoded/decoded from the socket API. - Fix copy and move semantic on HandledObject and ObjectHandle - Add support for emissive and normal maps in .mtl loader using custom keywords ([map_]emissive and [map_]normal) +- Music, Sound and SoundEmitter are now movable Nazara Development Kit: - Added ImageWidget (#139) diff --git a/include/Nazara/Audio/Music.hpp b/include/Nazara/Audio/Music.hpp index fc43d514c..27e742063 100644 --- a/include/Nazara/Audio/Music.hpp +++ b/include/Nazara/Audio/Music.hpp @@ -38,7 +38,7 @@ namespace Nz public: Music() = default; Music(const Music&) = delete; - Music(Music&&) = delete; + Music(Music&&) noexcept = default; ~Music(); bool Create(SoundStream* soundStream); @@ -67,10 +67,10 @@ namespace Nz void Stop() override; Music& operator=(const Music&) = delete; - Music& operator=(Music&&) = delete; + Music& operator=(Music&&) noexcept = default; private: - MovablePtr m_impl = nullptr; + MovablePtr m_impl; bool FillAndQueueBuffer(unsigned int buffer); void MusicThread(); diff --git a/include/Nazara/Audio/Sound.hpp b/include/Nazara/Audio/Sound.hpp index f416f208a..55cc2f97a 100644 --- a/include/Nazara/Audio/Sound.hpp +++ b/include/Nazara/Audio/Sound.hpp @@ -20,7 +20,7 @@ namespace Nz Sound() = default; Sound(const SoundBuffer* soundBuffer); Sound(const Sound& sound); - Sound(Sound&&) = default; + Sound(Sound&&) noexcept = default; ~Sound(); void EnableLooping(bool loop) override; @@ -47,7 +47,7 @@ namespace Nz void Stop() override; Sound& operator=(const Sound&) = delete; ///TODO? - Sound& operator=(Sound&&) = default; + Sound& operator=(Sound&&) noexcept = default; private: SoundBufferConstRef m_buffer; diff --git a/include/Nazara/Audio/SoundEmitter.hpp b/include/Nazara/Audio/SoundEmitter.hpp index 614a1058e..725c6cf76 100644 --- a/include/Nazara/Audio/SoundEmitter.hpp +++ b/include/Nazara/Audio/SoundEmitter.hpp @@ -11,6 +11,7 @@ #include #include #include +#include ///TODO: Inherit SoundEmitter from Node @@ -19,6 +20,7 @@ namespace Nz class NAZARA_AUDIO_API SoundEmitter { public: + SoundEmitter(SoundEmitter&& emitter) noexcept; virtual ~SoundEmitter(); virtual void EnableLooping(bool loop) = 0; @@ -51,16 +53,17 @@ namespace Nz virtual void Stop() = 0; - SoundEmitter& operator=(const SoundEmitter&) = delete; ///TODO - SoundEmitter& operator=(SoundEmitter&&) = delete; + SoundEmitter& operator=(const SoundEmitter&) = delete; + SoundEmitter& operator=(SoundEmitter&&) noexcept; protected: SoundEmitter(); SoundEmitter(const SoundEmitter& emitter); - SoundEmitter(SoundEmitter&&) = delete; SoundStatus GetInternalStatus() const; + static constexpr unsigned int InvalidSource = std::numeric_limits::max(); + unsigned int m_source; }; } diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index 185b911b6..221cb9d50 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -262,6 +262,8 @@ namespace Nz */ void Music::Pause() { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + alSourcePause(m_source); } diff --git a/src/Nazara/Audio/Sound.cpp b/src/Nazara/Audio/Sound.cpp index a3beac029..c06ca5526 100644 --- a/src/Nazara/Audio/Sound.cpp +++ b/src/Nazara/Audio/Sound.cpp @@ -56,6 +56,8 @@ namespace Nz */ void Sound::EnableLooping(bool loop) { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + alSourcei(m_source, AL_LOOPING, loop); } @@ -87,6 +89,8 @@ namespace Nz */ UInt32 Sound::GetPlayingOffset() const { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + ALint samples = 0; alGetSourcei(m_source, AL_SAMPLE_OFFSET, &samples); @@ -108,6 +112,8 @@ namespace Nz */ bool Sound::IsLooping() const { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + ALint loop; alGetSourcei(m_source, AL_LOOPING, &loop); @@ -205,6 +211,8 @@ namespace Nz */ void Sound::Pause() { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + alSourcePause(m_source); } @@ -215,6 +223,7 @@ namespace Nz */ void Sound::Play() { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); NazaraAssert(IsPlayable(), "Music is not playable"); alSourcePlay(m_source); @@ -229,6 +238,7 @@ namespace Nz */ void Sound::SetBuffer(const SoundBuffer* buffer) { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); NazaraAssert(!buffer || buffer->IsValid(), "Invalid sound buffer"); if (m_buffer == buffer) @@ -251,14 +261,19 @@ namespace Nz */ void Sound::SetPlayingOffset(UInt32 offset) { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + alSourcei(m_source, AL_SAMPLE_OFFSET, static_cast(offset/1000.f * m_buffer->GetSampleRate())); } /*! * \brief Stops the sound + * + * \remark This is one of the only function that can be called on a moved sound (and does nothing) */ void Sound::Stop() { - alSourceStop(m_source); + if (m_source != InvalidSource) + alSourceStop(m_source); } } diff --git a/src/Nazara/Audio/SoundEmitter.cpp b/src/Nazara/Audio/SoundEmitter.cpp index 4492771f4..40b7ccd59 100644 --- a/src/Nazara/Audio/SoundEmitter.cpp +++ b/src/Nazara/Audio/SoundEmitter.cpp @@ -23,7 +23,6 @@ namespace Nz /*! * \brief Constructs a SoundEmitter object */ - SoundEmitter::SoundEmitter() { alGenSources(1, &m_source); @@ -39,22 +38,40 @@ namespace Nz SoundEmitter::SoundEmitter(const SoundEmitter& emitter) { - alGenSources(1, &m_source); + if (emitter.m_source != InvalidSource) + { + alGenSources(1, &m_source); - SetAttenuation(emitter.GetAttenuation()); - SetMinDistance(emitter.GetMinDistance()); - SetPitch(emitter.GetPitch()); - // No copy for position or velocity - SetVolume(emitter.GetVolume()); + SetAttenuation(emitter.GetAttenuation()); + SetMinDistance(emitter.GetMinDistance()); + SetPitch(emitter.GetPitch()); + // No copy for position or velocity + SetVolume(emitter.GetVolume()); + } + else + m_source = InvalidSource; + } + + /*! + * \brief Constructs a SoundEmitter object by moving another + * + * \param emitter SoundEmitter to move + * + * \remark The moved sound emitter cannot be used after being moved + */ + SoundEmitter::SoundEmitter(SoundEmitter&& emitter) noexcept : + m_source(emitter.m_source) + { + emitter.m_source = InvalidSource; } /*! * \brief Destructs the object */ - SoundEmitter::~SoundEmitter() { - alDeleteSources(1, &m_source); + if (m_source != InvalidSource) + alDeleteSources(1, &m_source); } /*! @@ -65,6 +82,8 @@ namespace Nz void SoundEmitter::EnableSpatialization(bool spatialization) { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + alSourcei(m_source, AL_SOURCE_RELATIVE, !spatialization); } @@ -75,6 +94,8 @@ namespace Nz float SoundEmitter::GetAttenuation() const { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + ALfloat attenuation; alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &attenuation); @@ -88,6 +109,8 @@ namespace Nz float SoundEmitter::GetMinDistance() const { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + ALfloat distance; alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &distance); @@ -101,6 +124,8 @@ namespace Nz float SoundEmitter::GetPitch() const { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + ALfloat pitch; alGetSourcef(m_source, AL_PITCH, &pitch); @@ -114,6 +139,8 @@ namespace Nz Vector3f SoundEmitter::GetPosition() const { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + Vector3f position; alGetSourcefv(m_source, AL_POSITION, position); @@ -127,6 +154,8 @@ namespace Nz Vector3f SoundEmitter::GetVelocity() const { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + Vector3f velocity; alGetSourcefv(m_source, AL_VELOCITY, velocity); @@ -140,6 +169,8 @@ namespace Nz float SoundEmitter::GetVolume() const { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + ALfloat gain; alGetSourcef(m_source, AL_GAIN, &gain); @@ -153,6 +184,8 @@ namespace Nz bool SoundEmitter::IsSpatialized() const { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + ALint relative; alGetSourcei(m_source, AL_SOURCE_RELATIVE, &relative); @@ -167,6 +200,8 @@ namespace Nz void SoundEmitter::SetAttenuation(float attenuation) { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + alSourcef(m_source, AL_ROLLOFF_FACTOR, attenuation); } @@ -178,6 +213,8 @@ namespace Nz void SoundEmitter::SetMinDistance(float minDistance) { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + alSourcef(m_source, AL_REFERENCE_DISTANCE, minDistance); } @@ -189,6 +226,8 @@ namespace Nz void SoundEmitter::SetPitch(float pitch) { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + alSourcef(m_source, AL_PITCH, pitch); } @@ -200,6 +239,8 @@ namespace Nz void SoundEmitter::SetPosition(const Vector3f& position) { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + alSourcefv(m_source, AL_POSITION, position); } @@ -211,6 +252,8 @@ namespace Nz void SoundEmitter::SetPosition(float x, float y, float z) { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + alSource3f(m_source, AL_POSITION, x, y, z); } @@ -222,6 +265,8 @@ namespace Nz void SoundEmitter::SetVelocity(const Vector3f& velocity) { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + alSourcefv(m_source, AL_VELOCITY, velocity); } @@ -233,6 +278,8 @@ namespace Nz void SoundEmitter::SetVelocity(float velX, float velY, float velZ) { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + alSource3f(m_source, AL_VELOCITY, velX, velY, velZ); } @@ -244,9 +291,25 @@ namespace Nz void SoundEmitter::SetVolume(float volume) { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + alSourcef(m_source, AL_GAIN, volume * 0.01f); } + /*! + * \brief Assign a sound emitter by moving it + * + * \param emitter SoundEmitter to move + * + * \return *this + */ + SoundEmitter& SoundEmitter::operator=(SoundEmitter&& emitter) noexcept + { + std::swap(m_source, emitter.m_source); + + return *this; + } + /*! * \brief Gets the status of the sound emitter * \return Enumeration of type SoundStatus (Playing, Stopped, ...) @@ -254,6 +317,8 @@ namespace Nz SoundStatus SoundEmitter::GetInternalStatus() const { + NazaraAssert(m_source != InvalidSource, "Invalid sound emitter"); + ALint state; alGetSourcei(m_source, AL_SOURCE_STATE, &state);