Upgrade NazaraAudio
This commit is contained in:
parent
a52103a641
commit
b936946154
|
|
@ -10,6 +10,8 @@
|
|||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Audio/Config.hpp>
|
||||
#include <Nazara/Audio/Enums.hpp>
|
||||
#include <Nazara/Audio/SoundBuffer.hpp>
|
||||
#include <Nazara/Audio/SoundStream.hpp>
|
||||
#include <Nazara/Core/Core.hpp>
|
||||
#include <Nazara/Math/Quaternion.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
|
|
@ -26,18 +28,23 @@ namespace Nz
|
|||
struct Config {};
|
||||
|
||||
Audio(Config /*config*/);
|
||||
Audio(const Audio&) = delete;
|
||||
Audio(Audio&&) = delete;
|
||||
~Audio();
|
||||
|
||||
AudioFormat GetAudioFormat(unsigned int channelCount);
|
||||
float GetDopplerFactor();
|
||||
float GetGlobalVolume();
|
||||
Vector3f GetListenerDirection();
|
||||
Vector3f GetListenerPosition();
|
||||
Quaternionf GetListenerRotation();
|
||||
Vector3f GetListenerVelocity();
|
||||
float GetSpeedOfSound();
|
||||
AudioFormat GetAudioFormat(unsigned int channelCount) const;
|
||||
float GetDopplerFactor() const;
|
||||
float GetGlobalVolume() const;
|
||||
Vector3f GetListenerDirection() const;
|
||||
Vector3f GetListenerPosition() const;
|
||||
Quaternionf GetListenerRotation() const;
|
||||
Vector3f GetListenerVelocity() const;
|
||||
const SoundBufferLoader& GetSoundBufferLoader() const;
|
||||
const SoundStreamLoader& GetSoundStreamLoader() const;
|
||||
float GetSpeedOfSound() const;
|
||||
|
||||
bool IsFormatSupported(AudioFormat format) const;
|
||||
|
||||
bool IsFormatSupported(AudioFormat format);
|
||||
void SetDopplerFactor(float dopplerFactor);
|
||||
void SetGlobalVolume(float volume);
|
||||
void SetListenerDirection(const Vector3f& direction);
|
||||
|
|
@ -49,7 +56,13 @@ namespace Nz
|
|||
void SetListenerVelocity(float velX, float velY, float velZ);
|
||||
void SetSpeedOfSound(float speed);
|
||||
|
||||
Audio& operator=(const Audio&) = delete;
|
||||
Audio& operator=(Audio&&) = delete;
|
||||
|
||||
private:
|
||||
SoundBufferLoader m_soundBufferLoader;
|
||||
SoundStreamLoader m_soundStreamLoader;
|
||||
|
||||
static Audio* s_instance;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
#include <Nazara/Audio/Enums.hpp>
|
||||
#include <Nazara/Audio/SoundEmitter.hpp>
|
||||
#include <Nazara/Audio/SoundStream.hpp>
|
||||
#include <Nazara/Core/MovablePtr.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
|
|
@ -20,12 +19,12 @@ namespace Nz
|
|||
class NAZARA_AUDIO_API Music : public Resource, public SoundEmitter
|
||||
{
|
||||
public:
|
||||
Music() = default;
|
||||
Music();
|
||||
Music(const Music&) = delete;
|
||||
Music(Music&&) noexcept = default;
|
||||
Music(Music&&) noexcept;
|
||||
~Music();
|
||||
|
||||
bool Create(SoundStream* soundStream);
|
||||
bool Create(std::shared_ptr<SoundStream> soundStream);
|
||||
void Destroy();
|
||||
|
||||
void EnableLooping(bool loop) override;
|
||||
|
|
@ -51,10 +50,10 @@ namespace Nz
|
|||
void Stop() override;
|
||||
|
||||
Music& operator=(const Music&) = delete;
|
||||
Music& operator=(Music&&) noexcept = default;
|
||||
Music& operator=(Music&&) noexcept;
|
||||
|
||||
private:
|
||||
MovablePtr<MusicImpl> m_impl;
|
||||
std::unique_ptr<MusicImpl> m_impl;
|
||||
|
||||
bool FillAndQueueBuffer(unsigned int buffer);
|
||||
void MusicThread();
|
||||
|
|
|
|||
|
|
@ -18,14 +18,14 @@ namespace Nz
|
|||
{
|
||||
public:
|
||||
Sound() = default;
|
||||
Sound(const SoundBuffer* soundBuffer);
|
||||
Sound(const Sound& sound);
|
||||
Sound(std::shared_ptr<const SoundBuffer> soundBuffer);
|
||||
Sound(const Sound&) = default;
|
||||
Sound(Sound&&) noexcept = default;
|
||||
~Sound();
|
||||
|
||||
void EnableLooping(bool loop) override;
|
||||
|
||||
const SoundBuffer* GetBuffer() const;
|
||||
const std::shared_ptr<const SoundBuffer>& GetBuffer() const;
|
||||
UInt32 GetDuration() const override;
|
||||
UInt32 GetPlayingOffset() const override;
|
||||
SoundStatus GetStatus() const override;
|
||||
|
|
@ -41,7 +41,7 @@ namespace Nz
|
|||
void Pause() override;
|
||||
void Play() override;
|
||||
|
||||
void SetBuffer(const SoundBuffer* buffer);
|
||||
void SetBuffer(std::shared_ptr<const SoundBuffer> soundBuffer);
|
||||
void SetPlayingOffset(UInt32 offset);
|
||||
|
||||
void Stop() override;
|
||||
|
|
@ -50,7 +50,7 @@ namespace Nz
|
|||
Sound& operator=(Sound&&) noexcept = default;
|
||||
|
||||
private:
|
||||
SoundBufferConstRef m_buffer;
|
||||
std::shared_ptr<const SoundBuffer> m_buffer;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Audio/Config.hpp>
|
||||
#include <Nazara/Audio/Enums.hpp>
|
||||
#include <Nazara/Core/MovablePtr.hpp>
|
||||
#include <Nazara/Core/ObjectRef.hpp>
|
||||
#include <Nazara/Core/ObjectLibrary.hpp>
|
||||
#include <Nazara/Core/RefCounted.hpp>
|
||||
|
|
@ -32,24 +31,18 @@ namespace Nz
|
|||
class Sound;
|
||||
class SoundBuffer;
|
||||
|
||||
using SoundBufferConstRef = ObjectRef<const SoundBuffer>;
|
||||
using SoundBufferLibrary = ObjectLibrary<SoundBuffer>;
|
||||
using SoundBufferLoader = ResourceLoader<SoundBuffer, SoundBufferParams>;
|
||||
using SoundBufferManager = ResourceManager<SoundBuffer, SoundBufferParams>;
|
||||
using SoundBufferRef = ObjectRef<SoundBuffer>;
|
||||
|
||||
struct SoundBufferImpl;
|
||||
|
||||
class NAZARA_AUDIO_API SoundBuffer : public RefCounted, public Resource
|
||||
{
|
||||
friend Sound;
|
||||
friend SoundBufferLibrary;
|
||||
friend SoundBufferLoader;
|
||||
friend SoundBufferManager;
|
||||
friend class Audio;
|
||||
|
||||
public:
|
||||
SoundBuffer() = default;
|
||||
SoundBuffer();
|
||||
SoundBuffer(AudioFormat format, UInt64 sampleCount, UInt32 sampleRate, const Int16* samples);
|
||||
SoundBuffer(const SoundBuffer&) = delete;
|
||||
SoundBuffer(SoundBuffer&&) = delete;
|
||||
|
|
@ -71,28 +64,14 @@ namespace Nz
|
|||
|
||||
static bool IsFormatSupported(AudioFormat format);
|
||||
|
||||
static SoundBufferRef LoadFromFile(const std::filesystem::path& filePath, const SoundBufferParams& params = SoundBufferParams());
|
||||
static SoundBufferRef LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params = SoundBufferParams());
|
||||
static SoundBufferRef LoadFromStream(Stream& stream, const SoundBufferParams& params = SoundBufferParams());
|
||||
|
||||
template<typename... Args> static SoundBufferRef New(Args&&... args);
|
||||
|
||||
// Signals:
|
||||
NazaraSignal(OnSoundBufferDestroy, const SoundBuffer* /*soundBuffer*/);
|
||||
NazaraSignal(OnSoundBufferRelease, const SoundBuffer* /*soundBuffer*/);
|
||||
static std::shared_ptr<SoundBuffer> LoadFromFile(const std::filesystem::path& filePath, const SoundBufferParams& params = SoundBufferParams());
|
||||
static std::shared_ptr<SoundBuffer> LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params = SoundBufferParams());
|
||||
static std::shared_ptr<SoundBuffer> LoadFromStream(Stream& stream, const SoundBufferParams& params = SoundBufferParams());
|
||||
|
||||
private:
|
||||
unsigned int GetOpenALBuffer() const;
|
||||
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
MovablePtr<SoundBufferImpl> m_impl = nullptr;
|
||||
|
||||
static SoundBufferLibrary::LibraryMap s_library;
|
||||
static SoundBufferLoader::LoaderList s_loaders;
|
||||
static SoundBufferManager::ManagerMap s_managerMap;
|
||||
static SoundBufferManager::ManagerParams s_managerParameters;
|
||||
std::unique_ptr<SoundBufferImpl> m_impl;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,26 +2,12 @@
|
|||
// This file is part of the "Nazara Engine - Audio module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Audio/SoundBuffer.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Audio/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \brief Creates a new sound buffer from the arguments
|
||||
* \return A reference to the newly created sound buffer
|
||||
*
|
||||
* \param args Arguments for the sound buffer
|
||||
*/
|
||||
|
||||
template<typename... Args>
|
||||
SoundBufferRef SoundBuffer::New(Args&&... args)
|
||||
{
|
||||
std::unique_ptr<SoundBuffer> object(new SoundBuffer(std::forward<Args>(args)...));
|
||||
object->SetPersistent(false);
|
||||
|
||||
return object.release();
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Audio/DebugOff.hpp>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Audio/Config.hpp>
|
||||
#include <Nazara/Audio/Enums.hpp>
|
||||
#include <Nazara/Core/ObjectRef.hpp>
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Core/ResourceParameters.hpp>
|
||||
|
|
@ -29,12 +28,9 @@ namespace Nz
|
|||
class SoundStream;
|
||||
|
||||
using SoundStreamLoader = ResourceLoader<SoundStream, SoundStreamParams>;
|
||||
using SoundStreamRef = Nz::ObjectRef<SoundStream>;
|
||||
|
||||
class NAZARA_AUDIO_API SoundStream : public RefCounted, public Resource
|
||||
class NAZARA_AUDIO_API SoundStream : public Resource
|
||||
{
|
||||
friend SoundStreamLoader;
|
||||
|
||||
public:
|
||||
SoundStream() = default;
|
||||
virtual ~SoundStream();
|
||||
|
|
@ -49,12 +45,9 @@ namespace Nz
|
|||
virtual void Seek(UInt64 offset) = 0;
|
||||
virtual UInt64 Tell() = 0;
|
||||
|
||||
static SoundStreamRef OpenFromFile(const std::filesystem::path& filePath, const SoundStreamParams& params = SoundStreamParams());
|
||||
static SoundStreamRef OpenFromMemory(const void* data, std::size_t size, const SoundStreamParams& params = SoundStreamParams());
|
||||
static SoundStreamRef OpenFromStream(Stream& stream, const SoundStreamParams& params = SoundStreamParams());
|
||||
|
||||
private:
|
||||
static SoundStreamLoader::LoaderList s_loaders;
|
||||
static std::shared_ptr<SoundStream> OpenFromFile(const std::filesystem::path& filePath, const SoundStreamParams& params = SoundStreamParams());
|
||||
static std::shared_ptr<SoundStream> OpenFromMemory(const void* data, std::size_t size, const SoundStreamParams& params = SoundStreamParams());
|
||||
static std::shared_ptr<SoundStream> OpenFromStream(Stream& stream, const SoundStreamParams& params = SoundStreamParams());
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,22 +30,16 @@ namespace Nz
|
|||
if (!OpenAL::Initialize())
|
||||
throw std::runtime_error("failed to initialize OpenAL");
|
||||
|
||||
if (!SoundBuffer::Initialize())
|
||||
throw std::runtime_error("failed to initialize sound buffers");
|
||||
|
||||
// Definition of the orientation by default
|
||||
SetListenerDirection(Vector3f::Forward());
|
||||
|
||||
// Loaders
|
||||
Loaders::Register_sndfile();
|
||||
m_soundBufferLoader.RegisterLoader(Loaders::GetSoundBufferLoader_sndfile());
|
||||
m_soundStreamLoader.RegisterLoader(Loaders::GetSoundStreamLoader_sndfile());
|
||||
}
|
||||
|
||||
Audio::~Audio()
|
||||
{
|
||||
// Loaders
|
||||
Loaders::Unregister_sndfile();
|
||||
|
||||
SoundBuffer::Uninitialize();
|
||||
OpenAL::Uninitialize();
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +52,7 @@ namespace Nz
|
|||
* \remark Produces a NazaraError if the number of channels is erroneous (3 or 5) and AudioFormat_Unknown is returned
|
||||
*/
|
||||
|
||||
AudioFormat Audio::GetAudioFormat(unsigned int channelCount)
|
||||
AudioFormat Audio::GetAudioFormat(unsigned int channelCount) const
|
||||
{
|
||||
switch (channelCount)
|
||||
{
|
||||
|
|
@ -80,8 +74,7 @@ namespace Nz
|
|||
* \brief Gets the factor of the doppler effect
|
||||
* \return Global factor of the doppler effect
|
||||
*/
|
||||
|
||||
float Audio::GetDopplerFactor()
|
||||
float Audio::GetDopplerFactor() const
|
||||
{
|
||||
return alGetFloat(AL_DOPPLER_FACTOR);
|
||||
}
|
||||
|
|
@ -90,8 +83,7 @@ namespace Nz
|
|||
* \brief Gets the global volume
|
||||
* \return Float between [0, inf) with 100.f being the default
|
||||
*/
|
||||
|
||||
float Audio::GetGlobalVolume()
|
||||
float Audio::GetGlobalVolume() const
|
||||
{
|
||||
ALfloat gain = 0.f;
|
||||
alGetListenerf(AL_GAIN, &gain);
|
||||
|
|
@ -105,8 +97,7 @@ namespace Nz
|
|||
*
|
||||
* \see GetListenerRotation
|
||||
*/
|
||||
|
||||
Vector3f Audio::GetListenerDirection()
|
||||
Vector3f Audio::GetListenerDirection() const
|
||||
{
|
||||
ALfloat orientation[6];
|
||||
alGetListenerfv(AL_ORIENTATION, orientation);
|
||||
|
|
@ -120,8 +111,7 @@ namespace Nz
|
|||
*
|
||||
* \see GetListenerVelocity
|
||||
*/
|
||||
|
||||
Vector3f Audio::GetListenerPosition()
|
||||
Vector3f Audio::GetListenerPosition() const
|
||||
{
|
||||
Vector3f position;
|
||||
alGetListenerfv(AL_POSITION, &position.x);
|
||||
|
|
@ -133,8 +123,7 @@ namespace Nz
|
|||
* \brief Gets the rotation of the listener
|
||||
* \return Rotation of the listener
|
||||
*/
|
||||
|
||||
Quaternionf Audio::GetListenerRotation()
|
||||
Quaternionf Audio::GetListenerRotation() const
|
||||
{
|
||||
ALfloat orientation[6];
|
||||
alGetListenerfv(AL_ORIENTATION, orientation);
|
||||
|
|
@ -150,8 +139,7 @@ namespace Nz
|
|||
*
|
||||
* \see GetListenerPosition
|
||||
*/
|
||||
|
||||
Vector3f Audio::GetListenerVelocity()
|
||||
Vector3f Audio::GetListenerVelocity() const
|
||||
{
|
||||
Vector3f velocity;
|
||||
alGetListenerfv(AL_VELOCITY, &velocity.x);
|
||||
|
|
@ -159,12 +147,29 @@ namespace Nz
|
|||
return velocity;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the default SoundBuffer loader
|
||||
* \return A constant reference to the default SoundBuffer loader
|
||||
*/
|
||||
const SoundBufferLoader& Audio::GetSoundBufferLoader() const
|
||||
{
|
||||
return m_soundBufferLoader;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the default SoundStream loader
|
||||
* \return A constant reference to the default SoundStream loader
|
||||
*/
|
||||
const SoundStreamLoader& Audio::GetSoundStreamLoader() const
|
||||
{
|
||||
return m_soundStreamLoader;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the speed of sound
|
||||
* \return Speed of sound
|
||||
*/
|
||||
|
||||
float Audio::GetSpeedOfSound()
|
||||
float Audio::GetSpeedOfSound() const
|
||||
{
|
||||
return alGetFloat(AL_SPEED_OF_SOUND);
|
||||
}
|
||||
|
|
@ -175,8 +180,7 @@ namespace Nz
|
|||
*
|
||||
* \param format Format to check
|
||||
*/
|
||||
|
||||
bool Audio::IsFormatSupported(AudioFormat format)
|
||||
bool Audio::IsFormatSupported(AudioFormat format) const
|
||||
{
|
||||
if (format == AudioFormat_Unknown)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <Nazara/Core/Stream.hpp>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <sndfile.h>
|
||||
#include <Nazara/Audio/Debug.hpp>
|
||||
|
|
@ -223,9 +224,9 @@ namespace Nz
|
|||
UInt64 m_sampleCount;
|
||||
};
|
||||
|
||||
bool IsSupported(const std::string& extension)
|
||||
bool IsSupported(const std::string_view& extension)
|
||||
{
|
||||
static std::set<std::string> supportedExtensions = {
|
||||
static std::set<std::string_view> supportedExtensions = {
|
||||
"aiff", "au", "avr", "caf", "flac", "htk", "ircam", "mat4", "mat5", "mpc2k",
|
||||
"nist","ogg", "pvf", "raw", "rf64", "sd2", "sds", "svx", "voc", "w64", "wav", "wve"
|
||||
};
|
||||
|
|
@ -251,43 +252,40 @@ namespace Nz
|
|||
return Ternary::False;
|
||||
}
|
||||
|
||||
SoundStreamRef LoadSoundStreamFile(const std::filesystem::path& filePath, const SoundStreamParams& parameters)
|
||||
std::shared_ptr<SoundStream> LoadSoundStreamFile(const std::filesystem::path& filePath, const SoundStreamParams& parameters)
|
||||
{
|
||||
std::unique_ptr<sndfileStream> soundStream = std::make_unique<sndfileStream>();
|
||||
std::shared_ptr<sndfileStream> soundStream = std::make_shared<sndfileStream>();
|
||||
if (!soundStream->Open(filePath, parameters.forceMono))
|
||||
{
|
||||
NazaraError("Failed to open sound stream");
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
soundStream->SetPersistent(false);
|
||||
return soundStream.release();
|
||||
return soundStream;
|
||||
}
|
||||
|
||||
SoundStreamRef LoadSoundStreamMemory(const void* data, std::size_t size, const SoundStreamParams& parameters)
|
||||
std::shared_ptr<SoundStream> LoadSoundStreamMemory(const void* data, std::size_t size, const SoundStreamParams& parameters)
|
||||
{
|
||||
std::unique_ptr<sndfileStream> soundStream(new sndfileStream);
|
||||
std::shared_ptr<sndfileStream> soundStream = std::make_shared<sndfileStream>();
|
||||
if (!soundStream->Open(data, size, parameters.forceMono))
|
||||
{
|
||||
NazaraError("Failed to open music stream");
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
soundStream->SetPersistent(false);
|
||||
return soundStream.release();
|
||||
return soundStream;
|
||||
}
|
||||
|
||||
SoundStreamRef LoadSoundStreamStream(Stream& stream, const SoundStreamParams& parameters)
|
||||
std::shared_ptr<SoundStream> LoadSoundStreamStream(Stream& stream, const SoundStreamParams& parameters)
|
||||
{
|
||||
std::unique_ptr<sndfileStream> soundStream(new sndfileStream);
|
||||
if (!soundStream->Open(stream, parameters.forceMono))
|
||||
{
|
||||
NazaraError("Failed to open music stream");
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
soundStream->SetPersistent(false);
|
||||
return soundStream.release();
|
||||
return soundStream;
|
||||
}
|
||||
|
||||
Ternary CheckSoundBuffer(Stream& stream, const SoundBufferParams& parameters)
|
||||
|
|
@ -307,7 +305,7 @@ namespace Nz
|
|||
return Ternary::False;
|
||||
}
|
||||
|
||||
SoundBufferRef LoadSoundBuffer(Stream& stream, const SoundBufferParams& parameters)
|
||||
std::shared_ptr<SoundBuffer> LoadSoundBuffer(Stream& stream, const SoundBufferParams& parameters)
|
||||
{
|
||||
SF_INFO info;
|
||||
info.format = 0;
|
||||
|
|
@ -319,9 +317,6 @@ namespace Nz
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// Lynix utilise RAII...
|
||||
// C'est très efficace !
|
||||
// MemoryLeak est confus...
|
||||
CallOnExit onExit([file]
|
||||
{
|
||||
sf_close(file);
|
||||
|
|
@ -336,12 +331,12 @@ namespace Nz
|
|||
|
||||
// https://github.com/LaurentGomila/SFML/issues/271
|
||||
// http://www.mega-nerd.com/libsndfile/command.html#SFC_SET_SCALE_FLOAT_INT_READ
|
||||
///FIXME: Seulement le Vorbis ?
|
||||
///FIXME: Only Vorbis?
|
||||
if (info.format & SF_FORMAT_VORBIS)
|
||||
sf_command(file, SFC_SET_SCALE_FLOAT_INT_READ, nullptr, SF_TRUE);
|
||||
|
||||
unsigned int sampleCount = static_cast<unsigned int>(info.frames * info.channels);
|
||||
std::unique_ptr<Int16[]> samples(new Int16[sampleCount]);
|
||||
sf_count_t sampleCount = static_cast<sf_count_t>(info.frames * info.channels);
|
||||
std::unique_ptr<Int16[]> samples = std::make_unique<Int16[]>(sampleCount); //< std::vector would default-init to zero
|
||||
|
||||
if (sf_read_short(file, samples.get(), sampleCount) != sampleCount)
|
||||
{
|
||||
|
|
@ -349,32 +344,41 @@ namespace Nz
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// Une conversion en mono est-elle nécessaire ?
|
||||
// Convert to mono if required
|
||||
if (parameters.forceMono && format != AudioFormat_Mono)
|
||||
{
|
||||
// Nous effectuons la conversion en mono dans le même buffer (il va de toute façon être copié)
|
||||
MixToMono(samples.get(), samples.get(), static_cast<unsigned int>(info.channels), static_cast<unsigned int>(info.frames));
|
||||
MixToMono(samples.get(), samples.get(), static_cast<UInt32>(info.channels), static_cast<UInt64>(info.frames));
|
||||
|
||||
format = AudioFormat_Mono;
|
||||
sampleCount = static_cast<unsigned int>(info.frames);
|
||||
}
|
||||
|
||||
return SoundBuffer::New(format, sampleCount, info.samplerate, samples.get());
|
||||
return std::make_shared<SoundBuffer>(format, sampleCount, info.samplerate, samples.get());
|
||||
}
|
||||
}
|
||||
|
||||
namespace Loaders
|
||||
{
|
||||
void Register_sndfile()
|
||||
SoundBufferLoader::Entry GetSoundBufferLoader_sndfile()
|
||||
{
|
||||
SoundBufferLoader::RegisterLoader(Detail::IsSupported, Detail::CheckSoundBuffer, Detail::LoadSoundBuffer);
|
||||
SoundStreamLoader::RegisterLoader(Detail::IsSupported, Detail::CheckSoundStream, Detail::LoadSoundStreamStream, Detail::LoadSoundStreamFile, Detail::LoadSoundStreamMemory);
|
||||
SoundBufferLoader::Entry loaderEntry;
|
||||
loaderEntry.extensionSupport = Detail::IsSupported;
|
||||
loaderEntry.streamChecker = Detail::CheckSoundBuffer;
|
||||
loaderEntry.streamLoader = Detail::LoadSoundBuffer;
|
||||
|
||||
return loaderEntry;
|
||||
}
|
||||
|
||||
void Unregister_sndfile()
|
||||
SoundStreamLoader::Entry GetSoundStreamLoader_sndfile()
|
||||
{
|
||||
SoundBufferLoader::UnregisterLoader(Detail::IsSupported, Detail::CheckSoundBuffer, Detail::LoadSoundBuffer);
|
||||
SoundStreamLoader::UnregisterLoader(Detail::IsSupported, Detail::CheckSoundStream, Detail::LoadSoundStreamStream, Detail::LoadSoundStreamFile, Detail::LoadSoundStreamMemory);
|
||||
SoundStreamLoader::Entry loaderEntry;
|
||||
loaderEntry.extensionSupport = Detail::IsSupported;
|
||||
loaderEntry.streamChecker = Detail::CheckSoundStream;
|
||||
loaderEntry.fileLoader = Detail::LoadSoundStreamFile;
|
||||
loaderEntry.memoryLoader = Detail::LoadSoundStreamMemory;
|
||||
loaderEntry.streamLoader = Detail::LoadSoundStreamStream;
|
||||
|
||||
return loaderEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,14 +8,13 @@
|
|||
#define NAZARA_LOADERS_SNDFILE_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Audio/SoundBuffer.hpp>
|
||||
#include <Nazara/Audio/SoundStream.hpp>
|
||||
|
||||
namespace Nz
|
||||
namespace Nz::Loaders
|
||||
{
|
||||
namespace Loaders
|
||||
{
|
||||
void Register_sndfile();
|
||||
void Unregister_sndfile();
|
||||
}
|
||||
SoundBufferLoader::Entry GetSoundBufferLoader_sndfile();
|
||||
SoundStreamLoader::Entry GetSoundStreamLoader_sndfile();
|
||||
}
|
||||
|
||||
#endif // NAZARA_LOADERS_SNDFILE_HPP
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ namespace Nz
|
|||
std::atomic<UInt64> processedSamples;
|
||||
std::vector<Int16> chunkSamples;
|
||||
std::mutex bufferLock;
|
||||
SoundStreamRef stream;
|
||||
std::shared_ptr<SoundStream> stream;
|
||||
std::thread thread;
|
||||
UInt64 playingOffset;
|
||||
bool loop = false;
|
||||
|
|
@ -37,12 +37,14 @@ namespace Nz
|
|||
unsigned int sampleRate;
|
||||
};
|
||||
|
||||
Music::Music() = default;
|
||||
Music::Music(Music&&) noexcept = default;
|
||||
|
||||
/*!
|
||||
* \brief Destructs the object and calls Destroy
|
||||
*
|
||||
* \see Destroy
|
||||
*/
|
||||
|
||||
Music::~Music()
|
||||
{
|
||||
Destroy();
|
||||
|
|
@ -55,7 +57,7 @@ namespace Nz
|
|||
* \param soundStream Sound stream which is the source for the music
|
||||
*/
|
||||
|
||||
bool Music::Create(SoundStream* soundStream)
|
||||
bool Music::Create(std::shared_ptr<SoundStream> soundStream)
|
||||
{
|
||||
NazaraAssert(soundStream, "Invalid stream");
|
||||
|
||||
|
|
@ -63,11 +65,11 @@ namespace Nz
|
|||
|
||||
AudioFormat format = soundStream->GetFormat();
|
||||
|
||||
m_impl = new MusicImpl;
|
||||
m_impl = std::make_unique<MusicImpl>();
|
||||
m_impl->sampleRate = soundStream->GetSampleRate();
|
||||
m_impl->audioFormat = OpenAL::AudioFormat[format];
|
||||
m_impl->chunkSamples.resize(format * m_impl->sampleRate); // One second of samples
|
||||
m_impl->stream = soundStream;
|
||||
m_impl->stream = std::move(soundStream);
|
||||
|
||||
SetPlayingOffset(0);
|
||||
|
||||
|
|
@ -85,8 +87,7 @@ namespace Nz
|
|||
{
|
||||
StopThread();
|
||||
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
m_impl.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -216,8 +217,8 @@ namespace Nz
|
|||
*/
|
||||
bool Music::OpenFromFile(const std::filesystem::path& filePath, const SoundStreamParams& params)
|
||||
{
|
||||
if (SoundStreamRef soundStream = SoundStream::OpenFromFile(filePath, params))
|
||||
return Create(soundStream);
|
||||
if (std::shared_ptr<SoundStream> soundStream = SoundStream::OpenFromFile(filePath, params))
|
||||
return Create(std::move(soundStream));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
@ -234,8 +235,8 @@ namespace Nz
|
|||
*/
|
||||
bool Music::OpenFromMemory(const void* data, std::size_t size, const SoundStreamParams& params)
|
||||
{
|
||||
if (SoundStreamRef soundStream = SoundStream::OpenFromMemory(data, size, params))
|
||||
return Create(soundStream);
|
||||
if (std::shared_ptr<SoundStream> soundStream = SoundStream::OpenFromMemory(data, size, params))
|
||||
return Create(std::move(soundStream));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
@ -251,8 +252,8 @@ namespace Nz
|
|||
*/
|
||||
bool Music::OpenFromStream(Stream& stream, const SoundStreamParams& params)
|
||||
{
|
||||
if (SoundStreamRef soundStream = SoundStream::OpenFromStream(stream, params))
|
||||
return Create(soundStream);
|
||||
if (std::shared_ptr<SoundStream> soundStream = SoundStream::OpenFromStream(stream, params))
|
||||
return Create(std::move(soundStream));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
@ -346,6 +347,8 @@ namespace Nz
|
|||
SetPlayingOffset(0);
|
||||
}
|
||||
|
||||
Music& Music::operator=(Music&&) noexcept = default;
|
||||
|
||||
bool Music::FillAndQueueBuffer(unsigned int buffer)
|
||||
{
|
||||
std::size_t sampleCount = m_impl->chunkSamples.size();
|
||||
|
|
|
|||
|
|
@ -23,21 +23,9 @@ namespace Nz
|
|||
*
|
||||
* \param soundBuffer Buffer to read sound from
|
||||
*/
|
||||
Sound::Sound(const SoundBuffer* soundBuffer)
|
||||
Sound::Sound(std::shared_ptr<const SoundBuffer> soundBuffer)
|
||||
{
|
||||
SetBuffer(soundBuffer);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Sound object which is a copy of another
|
||||
*
|
||||
* \param sound Sound to copy
|
||||
*/
|
||||
Sound::Sound(const Sound& sound) :
|
||||
SoundEmitter(sound)
|
||||
{
|
||||
SetBuffer(sound.m_buffer);
|
||||
EnableLooping(sound.IsLooping());
|
||||
SetBuffer(std::move(soundBuffer));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -66,7 +54,7 @@ namespace Nz
|
|||
* \brief Gets the internal buffer
|
||||
* \return Internal buffer
|
||||
*/
|
||||
const SoundBuffer* Sound::GetBuffer() const
|
||||
const std::shared_ptr<const SoundBuffer>& Sound::GetBuffer() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
|
@ -151,7 +139,7 @@ namespace Nz
|
|||
*/
|
||||
bool Sound::LoadFromFile(const std::filesystem::path& filePath, const SoundBufferParams& params)
|
||||
{
|
||||
SoundBufferRef buffer = SoundBuffer::LoadFromFile(filePath, params);
|
||||
std::shared_ptr<SoundBuffer> buffer = SoundBuffer::LoadFromFile(filePath, params);
|
||||
if (!buffer)
|
||||
{
|
||||
NazaraError("Failed to load buffer from file (" + filePath.generic_u8string() + ')');
|
||||
|
|
@ -174,7 +162,7 @@ namespace Nz
|
|||
*/
|
||||
bool Sound::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params)
|
||||
{
|
||||
SoundBufferRef buffer = SoundBuffer::LoadFromMemory(data, size, params);
|
||||
std::shared_ptr<SoundBuffer> buffer = SoundBuffer::LoadFromMemory(data, size, params);
|
||||
if (!buffer)
|
||||
{
|
||||
NazaraError("Failed to load buffer from memory (" + PointerToString(data) + ')');
|
||||
|
|
@ -196,7 +184,7 @@ namespace Nz
|
|||
*/
|
||||
bool Sound::LoadFromStream(Stream& stream, const SoundBufferParams& params)
|
||||
{
|
||||
SoundBufferRef buffer = SoundBuffer::LoadFromStream(stream, params);
|
||||
std::shared_ptr<SoundBuffer> buffer = SoundBuffer::LoadFromStream(stream, params);
|
||||
if (!buffer)
|
||||
{
|
||||
NazaraError("Failed to load buffer from stream");
|
||||
|
|
@ -237,7 +225,7 @@ namespace Nz
|
|||
*
|
||||
* \remark Produces a NazaraError if buffer is invalid with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
void Sound::SetBuffer(const SoundBuffer* buffer)
|
||||
void Sound::SetBuffer(std::shared_ptr<const SoundBuffer> buffer)
|
||||
{
|
||||
NazaraAssert(m_source != InvalidSource, "Invalid sound emitter");
|
||||
NazaraAssert(!buffer || buffer->IsValid(), "Invalid sound buffer");
|
||||
|
|
@ -247,7 +235,7 @@ namespace Nz
|
|||
|
||||
Stop();
|
||||
|
||||
m_buffer = buffer;
|
||||
m_buffer = std::move(buffer);
|
||||
|
||||
if (m_buffer)
|
||||
alSourcei(m_source, AL_BUFFER, m_buffer->GetOpenALBuffer());
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ namespace Nz
|
|||
UInt32 sampleRate;
|
||||
};
|
||||
|
||||
SoundBuffer::SoundBuffer() = default;
|
||||
|
||||
/*!
|
||||
* \brief Constructs a SoundBuffer object
|
||||
*
|
||||
|
|
@ -71,17 +73,7 @@ namespace Nz
|
|||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Destructs the object and calls Destroy
|
||||
*
|
||||
* \see Destroy
|
||||
*/
|
||||
SoundBuffer::~SoundBuffer()
|
||||
{
|
||||
OnSoundBufferRelease(this);
|
||||
|
||||
Destroy();
|
||||
}
|
||||
SoundBuffer::~SoundBuffer() = default;
|
||||
|
||||
/*!
|
||||
* \brief Creates the SoundBuffer object
|
||||
|
|
@ -146,7 +138,7 @@ namespace Nz
|
|||
return false;
|
||||
}
|
||||
|
||||
m_impl = new SoundBufferImpl;
|
||||
m_impl = std::make_unique<SoundBufferImpl>();
|
||||
m_impl->buffer = buffer;
|
||||
m_impl->duration = static_cast<UInt32>((1000ULL*sampleCount / (format * sampleRate)));
|
||||
m_impl->format = format;
|
||||
|
|
@ -163,16 +155,9 @@ namespace Nz
|
|||
/*!
|
||||
* \brief Destroys the current sound buffer and frees resources
|
||||
*/
|
||||
|
||||
void SoundBuffer::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
OnSoundBufferDestroy(this);
|
||||
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
m_impl.reset();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -259,7 +244,10 @@ namespace Nz
|
|||
*/
|
||||
bool SoundBuffer::IsFormatSupported(AudioFormat format)
|
||||
{
|
||||
return Audio::Instance()->IsFormatSupported(format);
|
||||
Audio* audio = Audio::Instance();
|
||||
NazaraAssert(audio, "Audio module has not been initialized");
|
||||
|
||||
return audio->IsFormatSupported(format);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -269,9 +257,12 @@ namespace Nz
|
|||
* \param filePath Path to the file
|
||||
* \param params Parameters for the sound buffer
|
||||
*/
|
||||
SoundBufferRef SoundBuffer::LoadFromFile(const std::filesystem::path& filePath, const SoundBufferParams& params)
|
||||
std::shared_ptr<SoundBuffer> SoundBuffer::LoadFromFile(const std::filesystem::path& filePath, const SoundBufferParams& params)
|
||||
{
|
||||
return SoundBufferLoader::LoadFromFile(filePath, params);
|
||||
Audio* audio = Audio::Instance();
|
||||
NazaraAssert(audio, "Audio module has not been initialized");
|
||||
|
||||
return audio->GetSoundBufferLoader().LoadFromFile(filePath, params);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -282,9 +273,12 @@ namespace Nz
|
|||
* \param size Size of the memory
|
||||
* \param params Parameters for the sound buffer
|
||||
*/
|
||||
SoundBufferRef SoundBuffer::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params)
|
||||
std::shared_ptr<SoundBuffer> SoundBuffer::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params)
|
||||
{
|
||||
return SoundBufferLoader::LoadFromMemory(data, size, params);
|
||||
Audio* audio = Audio::Instance();
|
||||
NazaraAssert(audio, "Audio module has not been initialized");
|
||||
|
||||
return audio->GetSoundBufferLoader().LoadFromMemory(data, size, params);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -294,9 +288,12 @@ namespace Nz
|
|||
* \param stream Stream to the sound buffer
|
||||
* \param params Parameters for the sound buffer
|
||||
*/
|
||||
SoundBufferRef SoundBuffer::LoadFromStream(Stream& stream, const SoundBufferParams& params)
|
||||
std::shared_ptr<SoundBuffer> SoundBuffer::LoadFromStream(Stream& stream, const SoundBufferParams& params)
|
||||
{
|
||||
return SoundBufferLoader::LoadFromStream(stream, params);
|
||||
Audio* audio = Audio::Instance();
|
||||
NazaraAssert(audio, "Audio module has not been initialized");
|
||||
|
||||
return audio->GetSoundBufferLoader().LoadFromStream(stream, params);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -317,41 +314,4 @@ namespace Nz
|
|||
|
||||
return m_impl->buffer;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Initializes the libraries and managers
|
||||
* \return true if initialization is successful
|
||||
*
|
||||
* \remark Produces a NazaraError if sub-initialization failed
|
||||
*/
|
||||
bool SoundBuffer::Initialize()
|
||||
{
|
||||
if (!SoundBufferLibrary::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialise library");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SoundBufferManager::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialise manager");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Uninitializes the libraries and managers
|
||||
*/
|
||||
void SoundBuffer::Uninitialize()
|
||||
{
|
||||
SoundBufferManager::Uninitialize();
|
||||
SoundBufferLibrary::Uninitialize();
|
||||
}
|
||||
|
||||
SoundBufferLibrary::LibraryMap SoundBuffer::s_library;
|
||||
SoundBufferLoader::LoaderList SoundBuffer::s_loaders;
|
||||
SoundBufferManager::ManagerMap SoundBuffer::s_managerMap;
|
||||
SoundBufferManager::ManagerParams SoundBuffer::s_managerParameters;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Audio/SoundStream.hpp>
|
||||
#include <Nazara/Audio/Audio.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
|
|
@ -18,23 +19,57 @@ namespace Nz
|
|||
*
|
||||
* \remark This class is abstract
|
||||
*/
|
||||
|
||||
SoundStream::~SoundStream() = default;
|
||||
|
||||
SoundStreamRef SoundStream::OpenFromFile(const std::filesystem::path& filePath, const SoundStreamParams& params)
|
||||
/*!
|
||||
* \brief Opens the sound stream from file
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param filePath Path to the file
|
||||
* \param params Parameters for the sound stream
|
||||
*
|
||||
* \remark The file must stay valid until the sound stream is destroyed
|
||||
*/
|
||||
std::shared_ptr<SoundStream> SoundStream::OpenFromFile(const std::filesystem::path& filePath, const SoundStreamParams& params)
|
||||
{
|
||||
return SoundStreamLoader::LoadFromFile(filePath, params);
|
||||
Audio* audio = Audio::Instance();
|
||||
NazaraAssert(audio, "Audio module has not been initialized");
|
||||
|
||||
return audio->GetSoundStreamLoader().LoadFromFile(filePath, params);
|
||||
}
|
||||
|
||||
SoundStreamRef SoundStream::OpenFromMemory(const void* data, std::size_t size, const SoundStreamParams& params)
|
||||
/*!
|
||||
* \brief Opens the sound stream from memory
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param data Raw memory
|
||||
* \param size Size of the memory
|
||||
* \param params Parameters for the sound stream
|
||||
*
|
||||
* \remark The memory block must stay valid until the sound stream is destroyed
|
||||
*/
|
||||
std::shared_ptr<SoundStream> SoundStream::OpenFromMemory(const void* data, std::size_t size, const SoundStreamParams& params)
|
||||
{
|
||||
return SoundStreamLoader::LoadFromMemory(data, size, params);
|
||||
Audio* audio = Audio::Instance();
|
||||
NazaraAssert(audio, "Audio module has not been initialized");
|
||||
|
||||
return audio->GetSoundStreamLoader().LoadFromMemory(data, size, params);
|
||||
}
|
||||
|
||||
SoundStreamRef SoundStream::OpenFromStream(Stream& stream, const SoundStreamParams& params)
|
||||
/*!
|
||||
* \brief Opens the sound stream from stream
|
||||
* \return true if loading is successful
|
||||
*
|
||||
* \param stream Stream to the sound stream
|
||||
* \param params Parameters for the sound stream
|
||||
*
|
||||
* \remark The stream must stay valid until the sound stream is destroyed
|
||||
*/
|
||||
std::shared_ptr<SoundStream> SoundStream::OpenFromStream(Stream& stream, const SoundStreamParams& params)
|
||||
{
|
||||
return SoundStreamLoader::LoadFromStream(stream, params);
|
||||
}
|
||||
Audio* audio = Audio::Instance();
|
||||
NazaraAssert(audio, "Audio module has not been initialized");
|
||||
|
||||
SoundStreamLoader::LoaderList SoundStream::s_loaders;
|
||||
return audio->GetSoundStreamLoader().LoadFromStream(stream, params);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue